Obtain all files that are over 1gb in C# - c#

I'm trying to get all the non system files on my computer to find out what files are over 1gb via a WinForms application.
Here is the code I'm working with:
const long b500mb = 65536000;
const long b1gb = 134217728;
public Main()
{
InitializeComponent();
}
//https://unitconverter.io/gigabits/bytes/1
private void Main_Load(object sender, EventArgs e)
{
var cDriveDirectories = new DirectoryInfo(#"C:\").GetDirectories()
.Where(f => !f.Attributes.HasFlag(FileAttributes.System))
.Where(w => w.FullName != #"C:\Windows")
.Select(f => f.FullName)
.ToList();
var filesOver1Gb = new List<FileInfo>();
foreach (var item in cDriveDirectories)
{
DirectoryInfo d = new DirectoryInfo(item);
var files = d.GetFiles("*", SearchOption.AllDirectories).Where(w => w.Attributes.HasFlag(FileAttributes.Normal)
&& w.Length > b1gb).ToList();
foreach (FileInfo file in files)
{
filesOver1Gb.Add(file);
}
}
}
How can I get around this error?
System.UnauthorizedAccessException: 'Access to the path 'C:\inetpub\history' is denied.'

After #zee's help:
I VS as an admin and then put a try/catch around the line of code that was failing and continued.
This code will obtain the information I need!
const long b500mb = 65536000;
const long b1gb = 134217728;
public Main()
{
InitializeComponent();
}
//https://unitconverter.io/gigabits/bytes/1
private void Main_Load(object sender, EventArgs e)
{
var cDriveDirectories = new DirectoryInfo(#"C:\").GetDirectories()
.Where(f => !f.Attributes.HasFlag(FileAttributes.System))
.Where(w => w.FullName != #"C:\Windows")
.Select(f => f.FullName)
.ToList();
var filesOver1Gb = new List<FileInfo>();
IList<string> unauthorizedFiles = new List<string>();
foreach (var item in cDriveDirectories)
{
DirectoryInfo d = new DirectoryInfo(item);
var files = new List<FileInfo>();
try
{
files = d.GetFiles("*", SearchOption.AllDirectories).Where(w => !w.Attributes.HasFlag(FileAttributes.System)
&& w.Length > b1gb).ToList();
}
catch (UnauthorizedAccessException)
{
// ignore error and continue to process files over 1gb.
}
foreach (FileInfo file in files)
{
filesOver1Gb.Add(file);
}
}
// get the total count in bytes to find out how many gbs we have etc.
long totalOver1Gb = 0;
foreach (var file in filesOver1Gb)
{
totalOver1Gb = totalOver1Gb + file.Length;
}
}

Related

elastic search field update from csv file in c#

I am new to programming in C#
I want to read the csv file and update the fields in elastic search. I already have this function made by someone else and I want to call this function and update fields.
public static bool UpdateDocumentFields(dynamic updatedFields, IHit<ClientDocuments> metaData)
{
var settings = (SystemWideSettings)SystemSettings.Instance;
if (settings == null)
throw new SettingsNotFoundException("System settings have not been initialized.");
if (ElasticSearch.Connect(settings.ElasticAddressString(), null, out ElasticClient elasticClient, out string status))
{
return ElasticSearch.UpdateDocumentFields(updatedFields, metaData, elasticClient);
}
return false;
}
what I have done myself so far is :
private void btnToEs_Click(object sender, EventArgs e)
{
var manager = new StateOne.FileProcessing.DocumentManager.DocumentManager();
var path = "C:/Temp/MissingElasticSearchRecords.csv";
var lines = File.ReadLines(path);
foreach (string line in lines)
{
var item = ClientDocuments.GetClientDocumentFromFilename(line);
if (item != null)
{
var output = new List<ClientDocuments>();
manager.TryGetClientDocuments(item.AccountNumber.ToString(), 100, out output);
if (output!= null && output.Count <= 0)
{
var docs = new List<ClientDocuments>();
//var doc = docs.Add();
// var doc = docs.Add();
//docs.Add(doc);
foreach (var doc in output)
{
if (!item.FileExists)
{
//insert in elastic search
manager.UpdateDocumentFields(output, );
}
else
{
//ignore
}
}
My problem here is manager.updateDocumentFields() is a function. I am calling it but what I need to pass as a parameter? Thanks in advance.

How can I get the Google drive folder hierarchy? [duplicate]

i am new with Nodes here.. :) i came up with this algorithm but it only shows the list of parent nodes.. like this..
a
a.txt
b
c
c
m
n
b
o
p
etc...
i want the next node will be put in one of the node inside the previous node.. so it will come up like this..
a
a.txt
b
o
p
c
m
n
etc...
i have some ideas in mind but i can implement it to codes.. :) any help please..
private void ListDirectory(TreeView treeView, String path)
{
Stack<string> stack = new Stack<string>();
TreeNode DirFilesCollection = new TreeNode();
stack.Push(path);
while (stack.Count > 0)
{
string dir = stack.Pop();
try
{
List<String> parentDir = new List<string>();
parentDir.AddRange(Directory.GetFiles(dir, "*.*"));
parentDir.AddRange(Directory.GetDirectories(dir));
DirectoryInfo d = new DirectoryInfo(dir);
TreeNode TParent = new TreeNode(d.Name);
foreach (String s in parentDir)
{
FileInfo f = new FileInfo(s);
TreeNode subItems = new TreeNode(f.Name);
TParent.Nodes.Add(subItems);
}
DirFilesCollection.Nodes.Add(TParent);
foreach (string dn in Directory.GetDirectories(dir))
{
stack.Push(dn);
}
}
catch
{}
}
Action clearTreeView = () => treeView.Nodes.Clear();
this.Invoke(clearTreeView);
Action showTreeView = () => treeView.Nodes.Add(DirFilesCollection);
this.Invoke(showTreeView);
}
Option #1: Recursive approach:
private void ListDirectory(TreeView treeView, string path)
{
treeView.Nodes.Clear();
var rootDirectoryInfo = new DirectoryInfo(path);
treeView.Nodes.Add(CreateDirectoryNode(rootDirectoryInfo));
}
private static TreeNode CreateDirectoryNode(DirectoryInfo directoryInfo)
{
var directoryNode = new TreeNode(directoryInfo.Name);
foreach (var directory in directoryInfo.GetDirectories())
directoryNode.Nodes.Add(CreateDirectoryNode(directory));
foreach (var file in directoryInfo.GetFiles())
directoryNode.Nodes.Add(new TreeNode(file.Name));
return directoryNode;
}
Option #2: Non-recursive approach:
private static void ListDirectory(TreeView treeView, string path)
{
treeView.Nodes.Clear();
var stack = new Stack<TreeNode>();
var rootDirectory = new DirectoryInfo(path);
var node = new TreeNode(rootDirectory.Name) { Tag = rootDirectory };
stack.Push(node);
while (stack.Count > 0)
{
var currentNode = stack.Pop();
var directoryInfo = (DirectoryInfo)currentNode.Tag;
foreach (var directory in directoryInfo.GetDirectories())
{
var childDirectoryNode = new TreeNode(directory.Name) { Tag = directory };
currentNode.Nodes.Add(childDirectoryNode);
stack.Push(childDirectoryNode);
}
foreach (var file in directoryInfo.GetFiles())
currentNode.Nodes.Add(new TreeNode(file.Name));
}
treeView.Nodes.Add(node);
}

Create WiX Msi with WiX Sharp

my WiX Sharp program for Creating msi:
static public void BuildMsi(string FolderPath)
{
string InstallationDirectoryPath = #"D:\Program";
var project = new Project("MyProduct",
new Dir(InstallationDirectoryPath,
new Files(System.IO.Path.Combine(FolderPath,"**"))));
Compiler.BuildMsi(project);
}
In this code if i pass the folder path which i want to release then it will create a msi that is working fine.
My Question is i want to pass multiple folder path so my main function looks like this but i am not able to figure out what i have to change in middle of the code
static public void BuildMsi(list<string> folderPath)
You could try something like this, but the code is not perfect..
It will get the main directory with files and all sub directories with files.
static string sRootDir = #"<Path of main directory>";
static public void BuildMsi(string FolderPath)
{
WixEntity[] weDir = new WixEntity[0];
weDir = BuildDirInfo(sRootDir, weDir);
var project = new Project("MyProduct", weDir);
Compiler.BuildMsi(project);
}
static WixEntity[] BuildDirInfo(string sRootDir, WixEntity[] weDir)
{
DirectoryInfo RootDirInfo = new DirectoryInfo(sRootDir);
if (RootDirInfo.Exists)
{
DirectoryInfo[] DirInfo = RootDirInfo.GetDirectories();
List<string> lMainDirs = new List<string>();
foreach (DirectoryInfo DirInfoSub in DirInfo)
lMainDirs.Add(DirInfoSub.FullName);
int cnt = lMainDirs.Count;
weDir = new WixEntity[cnt + 1];
if (cnt == 0)
weDir[0] = new DirFiles(RootDirInfo.FullName + #"\*.*");
else
{
weDir[cnt] = new DirFiles(RootDirInfo.FullName + #"\*.*");
for (int i = 0; i < cnt; i++)
{
DirectoryInfo RootSubDirInfo = new DirectoryInfo(lMainDirs[i]);
if (!RootSubDirInfo.Exists)
continue;
WixEntity[] weSubDir = new WixEntity[0];
weSubDir = BuildDirInfo(RootSubDirInfo.FullName, weSubDir);
weDir[i] = new Dir(RootSubDirInfo.Name, weSubDir);
}
}
}
return weDir;
}

How to look for different types of files in a directory?

public List<string> MapMyFiles()
{
List<FileInfo> batchaddresses = new List<FileInfo>();
foreach (object o in lstViewAddresses.Items)
{
try
{
string[] files = Directory.GetFiles(o.ToString(), "*-E.esy");
files.ToList().ForEach(f => batchaddresses.Add(new FileInfo(f)));
}
catch
{
if(MessageBox.Show(o.ToString() + " does not exist. Process anyway?",
"Continue?", MessageBoxButtons.YesNo)
== DialogResult.Yes) { }
else
{
Application.Exit();
}
}
}
return batchaddresses.OrderBy(f => f.CreationTime)
.Select(f => f.FullName).ToList();
}
i would like to add to the array not only
.ESY
but also
"p-.csv"
how do i do this?
Or just include more filters and select them together:
var filters = new[] { "*-E.esy", "*p-.csv" };
var files = filters.SelectMany(f => Directory.GetFiles(o.ToString(), f));
// .. etc.
Assuming that your code works for one set of wildcards...
Then after these lines:
string[] files = Directory.GetFiles(o.ToString(), "*-E.esy");
files.ToList().ForEach(f => batchaddresses.Add(new FileInfo(f)));
Add these:
files = Directory.GetFiles(o.ToString(), "*p-.csv");
files.ToList().ForEach(f => batchaddresses.Add(new FileInfo(f)));
I think you have to iterate multiple times with different wildcards.
public List<string> MapMyFiles()
{
List<FileInfo> batchaddresses = new List<FileInfo>();
foreach (object o in lstViewAddresses.Items)
{
DirectoryInfo di = new DirectoryInfo(o);
if (!di.Exists && MessageBox.Show(o.ToString() + " does not exist. Process anyway?", "Continue?", MessageBoxButtons.YesNo) != DialogResult.Yes)
Application.Exit();
(new List<string>(new[]{ "*-E.esy", "*p-.csv" })).ForEach(filter => {
(new List<string>(di.GetFiles(filter))).ForEach(file => {
batchaddresses.Add(new FileInfo(file));
});
});
}
return batchaddresses.OrderBy(f => f.CreationTime).Select(f => f.FullName).ToList();
}
There's my bid; added directory check as well.
try
{
foreach (string searchPattern in searchPatterns)
{
string[] files = Directory.GetFiles(o.ToString(), searchPattern);
files.ToList().ForEach(f => batchaddresses.Add(new FileInfo(f)));
}
}

How to compare two folders for similar files based on name in C#?

I have two folders A and B..Inside A multiple files are there and inside B multiple files are there..I have to check files in A with files in B for identical files...
I tried like this for a particular file name
void DirSearch(string sDir)
{
List<string> lstFilesFound = new List<string>();
foreach (string d in Directory.GetDirectories(sDir))
{
foreach (string f in Directory.GetFiles(d,"MsBuild_Tracker.proj")
{
lstFilesFound.Add(f);
}
DirSearch(d);
}
}
It is working..I tried like this for two folders
foreach (string d in Directory.GetDirectories(sDir))
{
foreach (string f in Directory.GetDirectories(dDir))
{
foreach (string g in Directory.GetFiles(d, f))
{
lstFilesFound.Add(g);
}
DirSearch(d, f);
}
}
It is not working...Any suggestion??
If you're using .NET 4, you can use DirectoryInfo and EnumerateFiles(). Then you can use LINQ to join the two directories to get the common files between the two directories.
var dir1 = new DirectoryInfo(#"c:\temp1");
var dir2 = new DirectoryInfo(#"c:\temp2");
var filesinboth = from f1 in dir1.EnumerateFiles()
join f2 in dir2.EnumerateFiles() on f1.Name equals f2.Name
select f1.Name;
or you can use where if you want additional conditions to apply.
var filesinboth = from f1 in dir1.EnumerateFiles()
from f2 in dir2.EnumerateFiles()
where f1.Name == f2.Name // and some other condition
select f1.Name;
These will both give you stream of strings. If you need the actual FileInfo instances, change the select part of the query to return f1 instead of f1.Name.
If you're using .NET 3.5, you need to use GetFiles() instead, which returns FileInfo[]. So the queries will look like this:
var filesinboth = from f1 in dir1.GetFiles()
join f2 in dir2.GetFiles() on f1.Name equals f2.Name
select f1.Name;
and
var filesinboth = from f1 in dir1.GetFiles()
from f2 in dir2.GetFiles()
where f1.Name == f2.Name // and some other condition
select f1.Name;
Why don't use just something like this (without recursion) ?
public static IEnumerable<string> GetMachingFiles(string pathA, string pathB)
{
var matchingFiles = new HashSet<string>();
var allAfiles = Directory.GetFiles(pathA, "*", SearchOption.AllDirectories);
foreach (var file in allAfiles)
{
foreach (var mathcFile in Directory.GetFiles(pathB, Path.GetFileName(file), SearchOption.AllDirectories))
matchingFiles.Add(mathcFile);
}
return matchingFiles;
}
Of course this solution suffers a performance decay in case of many files, because Directory.GetFiles navigates all files even when you pass a restrictive pattern.
To be more faster you could use LINQ as pointed out in Brian Rasmussen's answer
EDIT:
a faster example using LINQ (.NET 3.5):
public static IEnumerable<string> GetMachingFilesFast(string pathA, string pathB)
{
DirectoryInfo dirA = new DirectoryInfo(pathA);
DirectoryInfo dirB = new DirectoryInfo(pathB);
var filesA = dirA.GetFiles("*",SearchOption.AllDirectories);
var filesB = dirB.GetFiles("*", SearchOption.AllDirectories);
var matchingFiles =
filesA.Where(fA => filesB.Any(
fB => fA.Name == fB.Name
// && fA.LastWriteTime == fB.LastWriteTime
)
)
.Select(x => x.Name);
return matchingFiles;
}
try below code , you need to change path of files
DirectoryInfo dinfoTemp1 = new DirectoryInfo(#"C:\\Temp1");
DirectoryInfo dinfoTemp2 = new DirectoryInfo(#"C:\\Temp2");
FileInfo[] lstTemp1 = dinfoTemp1.GetFiles();
List<string> ui = lstTemp1.Where(
x => dinfoTemp2.GetFiles().
Where(y => y.Name.Contains(x.Name)).Count() > 0).
Select(x=>x.Name).ToList();
What you are basically doing is:
setting directory to var d like C://
Setting directory to var f like My Documents
Getting files that have the name My Documents in C://
and if you find any which I highly doubt, you add it to your list.
The first one works because;
sets the directory to var d like C://
gets the file that is named MsBuild_Tracker.proj in C://
adds it to the list.
Tell us what you need and maybe we can help..
Maybe compare (for a non-linq version) --
namespace RecursiveDirCompare
{
class Program
{
static List initialFiles = new List();
static string initRoot = #"root";
static string initCompare = #"compare";
static void Main(string[] args)
{
Directory.SetCurrentDirectory( #"C:\Temp\test\");
initRoot = #"root";// args[0];
initCompare = #"compare";// args[1];
AddFilesToInitialList(initRoot);
CompareWithInitialList(initCompare);
Console.ReadKey();
}
static void AddFilesToInitialList(string root)
{
foreach (string file in Directory.GetFiles(root))
{
initialFiles.Add(file.Replace(initRoot, ""));
}
foreach (string directory in Directory.GetDirectories(root))
{
AddFilesToInitialList(directory);
}
}
static void CompareWithInitialList(string root)
{
foreach (string file in Directory.GetFiles(root))
{
if(initialFiles.Contains(file.Replace(initCompare, "")))
{
Console.WriteLine(file + " is found in both");
}
}
foreach (string directory in Directory.GetDirectories(root))
{
CompareWithInitialList(directory);
}
}
}
}

Categories