C# Won't display size in subdirectorys - c#

I call the following function to check a specific path and get a list from all the folders located in the given path, for each folder it will check what the folder size is.
This works if i have a file in the folder like this.
Givenfolderpath\Underlying_folder\file.txt
But when there is a subdirectory with a file in it, it will not give me the size of the folder.
Givenfolderpath\Underlying_folder\subdirectory\file.txt
This is my code.
public void ListFolders()
{
dataGridView1.Rows.Clear();
DirectoryInfo di = new DirectoryInfo(Properties.Settings.Default.RevitPath);
DirectoryInfo[] diArr = di.GetDirectories();
foreach (DirectoryInfo dri in diArr)
{
string strCreateTime = dri.LastWriteTime.ToString();
string strCreateDate = dri.LastWriteTime.ToString();
string strCreateSize2 = null;
string strCreateSizeMb = null;
int strCreateSize3;
long strCreateSize1 = GetDirectorySize(Properties.Settings.Default.RevitPath + #"\" + dri);
string strCreateSize = GetSizeReadable(strCreateSize1);
strCreateTime = strCreateTime.Remove(strCreateTime.LastIndexOf(" "));
strCreateDate = strCreateDate.Remove(0,strCreateDate.LastIndexOf(" "));
strCreateSize2 = strCreateSize.Remove(strCreateSize.LastIndexOf(" "));
strCreateSizeMb = strCreateSize.Remove(0, strCreateSize.LastIndexOf(" "));
strCreateSize3 = Convert.ToInt32(strCreateSize2);
if (strCreateSizeMb == " Mb")
{
if (strCreateSize3 >= Properties.Settings.Default.FolderSize)
{
notifyIcon1.ShowBalloonTip(20000, "Attention Required!", dri + " exceed the permissible size " + Properties.Settings.Default.FolderSize + " Mb", System.Windows.Forms.ToolTipIcon.Warning);
}
}
int idx = dataGridView1.Rows.Add();
DataGridViewRow row = dataGridView1.Rows[idx];
row.Cells["User"].Value = dri;
row.Cells["Date"].Value = strCreateTime;
row.Cells["Time"].Value = strCreateDate;
row.Cells["Size"].Value = strCreateSize2;
row.Cells["SizeMB"].Value = strCreateSizeMb;
}
Where does it go wrong?
It will put the data like this.
static long GetDirectorySize(string p)
{
// 1
// Get array of all file names.
string[] a = Directory.GetFiles(p, "*.*");
// 2
// Calculate total bytes of all files in a loop.
long b = 0;
foreach (string name in a)
{
// 3
// Use FileInfo to get length of each file.
FileInfo info = new FileInfo(name);
b += info.Length;
}
// 4
// Return total size
return b;
}

Try replacing the line
DirectoryInfo[] diArr = di.GetDirectories();
with
DirectoryInfo[] diArr = di.GetDirectories("*", SearchOption.AllDirectories);
That should iterate over all directories contained in the given one. See for reference MSDN: DirectoryInfo.GetDirectories Method (String, SearchOption) and MSDN: SearchOption.

Related

Get files from a folder that I have created in Xamarin.Android

I want get all files from an external storage folder(wall_e_imgs)..Here are codes-
public void getImages()
{
var path1 = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath.ToString();
string path = System.IO.Path.Combine(path1, "wall_e_imgs");
//var files= System.IO.Directory.GetFiles(Android.OS.Environment.ExternalStorageDirectory.ToString() + "wall_e_imgs");
//var files = System.IO.Directory.GetFiles(path);
//string path = Android.OS.Environment.ExternalStorageDirectory.ToString() + "/wall_e_imgs";
//File directory=new File(path);
Java.IO.File directory = new Java.IO.File(path);
Java.IO.File[] files = directory.ListFiles();//always count is 0 even though there are lot files there
foreach (var i in files)
{
FileInfo info = new FileInfo(i.Name);
if (info.Name.Contains("Wall_e"))
{
di.Add(new DownloadedImages { Path1 = info.DirectoryName, Name1 = info.FullName });
}
}
}
But it always give 0 files even though there are lot of files.
Try this
var folder = Android.OS.Environment.ExternalStorageDirectory + Java.IO.File.Separator + "yourfoldername";
if (!Directory.Exists(folder))
Directory.CreateDirectory(folder);
var filesList = Directory.GetFiles(folder);
foreach (var file in filesList)
{
var filename = Path.GetFileName(file);
}
Try something like this:
// Use whatever folder path you want here, the special folder is just an example
string folderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "wall_e_imgs");
if (Directory.Exists(folderPath))
{
var files = Directory.EnumerateFiles(folderPath);
foreach (var file in files)
{
// Do your stuff
}
}
Please note that this uses the Directory class from System.IO, not Java.IO
ffilelist will contain a list of mp3 files in "/storage/emulated/0/Music/"
string phyle;
string ffilelist = "";
public void listfiles()
{
try
{
var path1 = "/storage/emulated/0/Music/";
var mp3Files = Directory.EnumerateFiles(path1, "*.mp3", SearchOption.AllDirectories);
foreach (string currentFile in mp3Files)
{
phyle = currentFile;
ffilelist = ffilelist + "\n" + phyle;
}
//playpath(phyle); // play the last file found
}
catch (Exception e9)
{
Toast.MakeText(ApplicationContext, "ut oh\n"+e9.Message , ToastLength.Long).Show();
}
}

How can I filter out lines in a richtextbox?

I have code that shows the name of all .dll files within a directory on a rich textbox. How would I be able to filter/hide all filenames which I specify as unimportant and keep the rest?
Example:
Actual directory contains: 1.dll, 2.dll, 3.dll
Rich Textbox shows: 1.dll, 3.dll because 2.dll is specified as unimportant in the code.
Code I currently have that displays all files.
DirectoryInfo r = new DirectoryInfo(#"E:\SteamLibrary\steamapps\common\Grand Theft Auto V");
FileInfo[] rFiles = r.GetFiles("*.dll");
string rstr = "";
foreach (FileInfo rfile in rFiles)
{
rstr = rstr + rfile.Name + " ";
}
string strfinalR;
strfinalR = richTextBox3.Text + rstr;
richTextBox3.Text = (strfinalR);
Just make a blacklist :
string[] blacklist = new string[] { "2", "1337" };
and filter the filenames within your foreach
foreach(FileInfo rFile in rFiles)
{
if(blacklist.Any(bl => rFile.Name.Contains(bl)))
continue;
// your code
}
or when you retrieve files from r
r.GetFiles("*.dll").Where(file => !blacklist.Any( type => file.Name.Contains(type))).ToArray();
one approach is to make a list of files to ignore and then fetch all files excluding those in ignore list. Something like this:
//ignore list
List<string> filesToIgnore = new List<string>() { "2.dll", "some_other.dll" };
//get files and filter them
DirectoryInfo r = new DirectoryInfo(#"E:\SteamLibrary\steamapps\common\Grand Theft Auto V");
List<FileInfo> rFiles = r.GetFiles("*.dll").Where(x => !filesToIgnore.Contains(x.Name)).ToList();
//your existing code follows
string rstr = "";
foreach (FileInfo rfile in rFiles)
{
rstr = rstr + rfile.Name + " ";
}
string strfinalR;
strfinalR = richTextBox3.Text + rstr;
richTextBox3.Text = (strfinalR);

How to efficiently cross reference 2 text files? | Improve my code

Below an outline of what my code does:
Read TextFileA which has 150k lines.
Read TextFileB which has 150k lines and is a cross reference list for TextFileA.
.Split both text files and match specified elements.
Finally, output a 3rd text file which will contain values from both TextFileA and TextFileB.
The below code runs well until about 13,000 lines in and then the program becomes exceedingly slow.
Could someone explain why the program becomes exponentially slower and how I could improve on this code? Thanks.
private void BT_Xref_Click(object sender, EventArgs e)
{
//grabs file path from text box
string ManifestPath = TB_Manifest.Text;
//grabs parent directory from file path
string directoryName = Path.GetDirectoryName(ManifestPath);
//creates a new folder for the final output text file
string pathString = Path.Combine(directoryName, "Final Index");
Directory.CreateDirectory(pathString);
//list for matching text lines which will eventually be output to the final text file
List<string> NewData = new List<string>();
//initializes StreamReader for the first text file
StreamReader ManifestReader = new StreamReader(ManifestPath);
String[] ManifestArray = File.ReadAllLines(ManifestPath);
List<string> RemoveManifest = new List<string>(ManifestArray);
//initializes StreamReader for the second text file
StreamReader OutputReader = new StreamReader(TB_Complete.Text);
String[] OutputArray = File.ReadAllLines(TB_Complete.Text);
List<string> RemoveOutput = new List<string>(OutputArray);
//initializes a count which decides at what point a text file should be created
int shortcount = 0;
//.ReadLine is initialized to ignore the first line in both text files
string ManifestLine = ManifestReader.ReadLine();
string OutputLine = OutputReader.ReadLine();
foreach (string mfile in ManifestArray)
{
ManifestLine = ManifestReader.ReadLine();
string ManifestElement = ManifestLine.Split(',')[6];
string ManifestElement2 = ManifestLine.Split(',')[5];
//value to be retreived and output to final text file
string ManifestElementDate = ManifestElement2.Replace("/", "-");
//value to be compared with the other text file
string ManifestNoExt = Regex.Replace(ManifestElement, ("(\\.\\w+$)"),"");
//resets OutpuReader reader to ensure no lines are being skipped
OutputReader.BaseStream.Position = 0;
//counting the mfile position in the ManifestArray
//int removeIndex = Array.IndexOf(ManifestArray, mfile);
//remove by resising the array
//Array.Resize(ref ManifestArray, ManifestArray.Length - 1);
foreach (string ofile in OutputArray)
{
OutputLine = OutputReader.ReadLine();
//value to be comapred with other text file
string OutputElement = OutputLine.Split('|')[2];
//if values equal then add the specified line of text to the list.
if (ManifestNoExt.Equals(OutputElement))
{
NewData.Add(OutputLine + "|" + ManifestElementDate);
RemoveManifest.RemoveAll(item => item == ManifestLine);
if (NewData.Count == 1000)
{
//if youve reached the count then output files into a new text file
shortcount = shortcount + 1;
File.WriteAllLines(pathString + "\\test" + shortcount + ".txt", NewData);
NewData.Clear();
}
break;
}
}
}
//once all line of text have been searched combine all text files in directory
shortcount = shortcount + 1;
File.WriteAllLines(pathString + "\\test" + shortcount + ".txt", NewData);
String[] SplitTextFiles = Directory.GetFiles(pathString, "*.*", SearchOption.AllDirectories);
using (var FinalIndexFile = File.Create(pathString + "\\FinalIndex.txt"))
{
foreach (var file in SplitTextFiles)
{
using (var input = File.OpenRead(file))
{
input.CopyTo(FinalIndexFile);
}
File.Delete(file);
}
}
//File.WriteAllLines("\\test.txt", Directory.EnumerateFiles(pathString, #"*.txt").SelectMany(file => File.ReadLines(file)));
}
You have an O(nm) algorithm here, and assuming that n and m are the same, its actually an O(n^2). That's not so good and is why its slowing to a crawl (for 150k rows in each file, you are looking at 22500000000 iterations of the inner loop. Not entirely certain what your code is trying to do, but based on the condition if (ManifestNoExt.Equals(OutputElement)), I think you can reduce the complexity drastically as follows:
Read in TextFileA, store values into a Dictionary based on ManifestNoExt as Key and mFile as value.
Next read in TextFileB and iterate over all rows in B and do a lookup in the dictionary that was constructed.
This will give you an algorithm that is O(n) + O(m), which will be fast.
Also, I am not sure why you are reading in the entire files and then reading them in again inside the loops (the contents of ManifestArray and OutputArray is the same as the files). That is certainly a cause for slow down as well since you are going to end up hammering the file system.
A completely untested version of this idea:
private void BT_Xref_Click(object sender, EventArgs e)
{
//grabs file path from text box
string ManifestPath = TB_Manifest.Text;
//grabs parent directory from file path
string directoryName = Path.GetDirectoryName(ManifestPath);
//creates a new folder for the final output text file
string pathString = Path.Combine(directoryName, "Final Index");
Directory.CreateDirectory(pathString);
//list for matching text lines which will eventually be output to the final text file
List<string> NewData = new List<string>();
String[] ManifestArray = File.ReadAllLines(ManifestPath);
List<string> RemoveManifest = new List<string>(ManifestArray);
String[] OutputArray = File.ReadAllLines(TB_Complete.Text);
List<string> RemoveOutput = new List<string>(OutputArray);
//initializes a count which decides at what point a text file should be created
int shortcount = 0;
//.ReadLine is initialized to ignore the first line in both text files
string ManifestLine = ManifestReader.ReadLine();
string OutputLine = OutputReader.ReadLine();
Dictionary<string, Tuple<string, string>> ManifestMap = new Dictionary<string, Tuple<string, string>>();
foreach (string mfile in ManifestArray.Skip(1))
{
string ManifestLine = mfile;
string ManifestElement = ManifestLine.Split(',')[6];
string ManifestElement2 = ManifestLine.Split(',')[5];
//value to be retreived and output to final text file
string ManifestElementDate = ManifestElement2.Replace("/", "-");
//value to be compared with the other text file
string ManifestNoExt = Regex.Replace(ManifestElement, ("(\\.\\w+$)"),"");
ManifestMap.Add(ManifestNoExt, Tuple.Create(ManifestElementDate, ManifestLine));
//counting the mfile position in the ManifestArray
//int removeIndex = Array.IndexOf(ManifestArray, mfile);
//remove by resising the array
//Array.Resize(ref ManifestArray, ManifestArray.Length - 1);
}
foreach (string ofile in OutputArray.Skip(1))
{
//value to be compared with other text file
string OutputElement = OutputLine.Split('|')[2];
//if values equal then add the specified line of text to the list.
if (ManifestMap.ContainsKey(OutputElement))
{
NewData.Add(OutputLine + "|" + ManifestMap[OutputElement].Item1);
RemoveManifest.RemoveAll(item => item == ManifestMap[OutputElement].Item2);
if (NewData.Count == 1000)
{
//if youve reached the count then output files into a new text file
shortcount = shortcount + 1;
File.WriteAllLines(pathString + "\\test" + shortcount + ".txt", NewData);
NewData.Clear();
}
break;
}
}
//once all line of text have been searched combine all text files in directory
shortcount = shortcount + 1;
File.WriteAllLines(pathString + "\\test" + shortcount + ".txt", NewData);
String[] SplitTextFiles = Directory.GetFiles(pathString, "*.*", SearchOption.AllDirectories);
using (var FinalIndexFile = File.Create(pathString + "\\FinalIndex.txt"))
{
foreach (var file in SplitTextFiles)
{
using (var input = File.OpenRead(file))
{
input.CopyTo(FinalIndexFile);
}
File.Delete(file);
}
}
//File.WriteAllLines("\\test.txt", Directory.EnumerateFiles(pathString, #"*.txt").SelectMany(file => File.ReadLines(file)));
}

c# I cannot get my code to sum file counts for directories beyond the root level

I'm using 2008 and am unable to use the EnumerateFiles class.
Any folder beyond the root level are essentially ignored when attempting to sum the files within listed network path. Here's my code:
public void getLeverageServer(string Server)
{
int Inp = 0;
int Out = 0;
int Ex = 0;
string output = "\\\\" + Server + "\\F\\Output";
string input = "\\\\" + Server + "\\F\\Input";
string exceptions = "\\\\" + Server + "\\F\\Exceptions";
string[] pathIn = Directory.GetFiles(input);
string[] pathOut = Directory.GetFiles(output);
string[] pathExceptions = Directory.GetFiles(exceptions);
foreach (string element in pathIn)
{
Inp++;
}
foreach (string element in pathOut)
{
Out++;
}
foreach (string element in pathExceptions)
{
Ex++;
}
txtLevInp.Text = Convert.ToString(Inp);
txtLevOut.Text = Convert.ToString(Out);
txtLevExc.Text = Convert.ToString(Ex);
txtLevTotal.Text = Convert.ToString(Out + Ex);
}
You need a different overload of Directory.GetFiles
string[] pathIn = Directory.GetFiles(input, "*.*", SearchOption.AllDirectories);
And you don't need to count the files found. Just read the value of the property Length of the returned array....
txtLevInp.Text = pathIn.Length;

how to sort file in alphanumeric in Fileinfo[] obtained via directory.getfiles and store them in same fileinfo[] array using C#

I need to take all file in particular directory and store them in fileinfo array and sort them alphanumerically.
code snippet
string dir = #"C:\tem";
DirectoryInfo directory = new DirectoryInfo(dir);
if (directory != null)
{
FileInfo[] files = directory.GetFiles("*.bmp");
if (files.Length > 0)
{
Console.WriteLine("Files:");
foreach (FileInfo subFile in files)
{
Console.WriteLine(" " + subFile.Name + " (" + subFile.Length + " bytes)");
}
}
}`
currently i am getting output
test_1.bmp test_11.bmp test_2.bmp
but i want the output like
test_1.bmp,test_2.bmp,test_11.bmp
Thanks
You can use LINQ for that:
if (directory != null)
{
FileInfo[] files = directory.GetFiles("*.bmp");
files.Select(f => f.Name).ToList().
OrderBy(x=> Int32.Parse(x.Substring(x.IndexOf('_') + 1, x.IndexOf('.') - x.IndexOf('_') - 1))).
ToList().ForEach(s => Console.WriteLine(s));
}
The output is:
test_1.bmp
test_2.bmp
test_11.bmp
UPDATE:
// Store as FileInfo array
FileInfo[] sortedFiles = files.OrderBy(x => Int32.Parse(x.Name.Substring(x.Name.IndexOf('_') + 1, x.Name.IndexOf('.') - x.Name.IndexOf('_') - 1))).
ToArray();
// Do whatever you want
foreach (FileInfo item in sortedFiles)
{
Console.WriteLine(string.Format("FullPath -> {0}", item.FullName));
}
public static void Main()
{
string dir = #"C:\tem";
var directory = new DirectoryInfo(dir);
FileInfo[] files = directory.GetFiles("*.bmp");
var sortedFiles=files.ToDictionary(k=>GetIntValueFromString(k.Name),v=>v).OrderBy(entry=>entry.Key);
foreach (var file in sortedFiles)
{
Console.WriteLine(file.Value.Name);
}
Console.Read();
}
static int GetIntValueFromString(string input)
{
var result = 0;
var intString = Regex.Replace(input, "[^0-9]+", string.Empty);
Int32.TryParse(intString, out result);
return result;
}

Categories