Taking Hilgreths answer made the code better however the actual problem was a variable data type , changing the type from string to bool to allow for files with no data fixed the issue .
Can't seem to find an answer to this on here or other forums just wondering if there is a way to ignore files of length 0 .
My program is searching through a DIR and returning all the files , I then want to search through the dir and find the most recent file , if a file length is 0 i want to skip to the next file but the system keeps crashing , my code so far looks like
if(fileinfo.Length > 0)
{
GetLatestWritenFileFileInDirectory(directoryInfo, keywordEH, keywordINTER, keywordM&M);
}
else if(result.Length == 0)
{
}
very rough at the moment as I'm not looking for it to be written for me (obviously) jus want to know if i can skip the empty files in some way without using linq as I'm using framework 1.0
thanks
Use fileinfo.Length instead of result.Length in the else if statement.
you should do
if(File.ReadAllText(yourfileName).Length == 0)
continue;
And this should be all.
I think you can drop the else if statement, because the FileInfo.Length cant be less than 0.
if(fileInfo.Length > 0)
{
////Do your stuff with non empty files
}
This will be enough unless you want to handle the files with length == 0, which seems you don't.
you can get all the files by calling GetFiles method with SearchOption.AllDirectories
FileInfo[] allfiles = directoryInfo.GetFiles("*.*", SearchOption.AllDirectories);
then do as below
for (int i = 0; i < allfiles.Length; i++)
{
if (allfiles[0].Length > 0)
{
GetLatestWritenFileFileInDirectory(allfiles[0], keywordEH, keywordINTER, keywordM & M);
}
}
Related
I have a method which searches the top directory for any files and returns the count which is as follows:
public int AttachmentCountItemDirectory(string directoryPath)
{
int fileCount = 0;
if (Directory.Exists(directoryPath))
fileCount = Directory.GetFiles(directoryPath, "*", SearchOption.TopDirectoryOnly).Length;
return fileCount;
}
The above method works great when there's 1 or more files in the directory. The issue I am facing is when there are no files the count is still 1 for some weird reason. I have enabled Show Hidden files, folders, and drives and from the image below it's clear there is no file.
Am I missing something obvious here? Can someone tell me where I'm going wrong please
You commented
It was thumbs.db
So the original question is answered.
My suggestion was to apply a filter to return only relevant files
Can i supply multiple filters at once? The filters I want to apply
are: pdf,doc,docx,xls,xlsx,jpeg,png
Yes, you can use LINQ:
public int AttachmentCountItemDirectory(string directoryPath)
{
string[] attExt = {".pdf",".doc",".docx",".xls",".xlsx",".jpeg",".png"};
return Directory.EnumerateFiles(directoryPath)
.Count(f => attExt.Contains(Path.GetExtension(f), StringComparer.InvariantCultureIgnoreCase));
}
I would not return 0 if an invalid path is passed to the method. I throw an exception then.
I am looking for a method that will take a file extension type and directory and return all the files within this directory and sub directories ordered by the latest creation date, i.e. latest files first.
So far i have identified the following method which is meant to be fast however is there a better way of doing this and i need it to return FileInfo rather than a string and ordered as described above.
public static IEnumerable<string> GetFileList(string fileSearchPattern, string rootFolderPath)
{
Queue<string> pending = new Queue<string>();
pending.Enqueue(rootFolderPath);
string[] tmp;
while (pending.Count > 0)
{
rootFolderPath = pending.Dequeue();
tmp = Directory.GetFiles(rootFolderPath, fileSearchPattern);
for (int i = 0; i < tmp.Length; i++)
{
yield return tmp[i];
}
tmp = Directory.GetDirectories(rootFolderPath);
for (int i = 0; i < tmp.Length; i++)
{
pending.Enqueue(tmp[i]);
}
}
}
When I have researched this problem space I've found there isn't a fast way to do this. The reason is no matter what approach you take, you end up having to go to the Operating System for the list of files in a directory. And the file system doesn't cache / index the way a search engine would. So you end up need to recrawl the file system yourself.
Once you have the raw information, however, you can index it yourself.
The below will work for your purposes. You want to use Directory.EnumerateFiles(...) to allow the file list to use less memory up front. It will only go looking for the next element when you ask for it instead of loading the entire collection in to memory at the start.
Directory.EnumerateFiles(rootFolderPath, fileSearchPattern, System.IO.SearchOption.AllDirectories).OrderBy(file => new FileInfo(file).CreationTime)
One additional consideration. Since you are doing a fairly blind search through the file system, if you try to enumerate a file and an exception is thrown, it will invalidate the enumerator causing it to exit without finishing. I have posted a solution to that problem here
Directory.GetFiles does have an option to search recursively.
The following should work, although I haven't tried it.
IEnumerable<FileInfo> GetFileList(string directory, string extension)
{
return Directory.GetFiles(directory, "*" + extension, SearchOption.AllDirectories)
.Select(f => new FileInfo(f))
.OrderByDescending(f => f.CreationTime);
}
I'm trying to write a program in C# to take a table of strings (variable names) from a database and search a directory of ~30,000 Fortran 77 source files to determine where that variable is calculated. The variables are typically calculated only 1 time in 1 of the fortran files but used many times in other files. The variables in the database table are all explicitly defined somewhere in the fortran files. So far I've accomplished most of this by first building a list of files that each variable appears in, and then searching the files in that list line by line. I've been looking for which side of the "=" sign the variable appears on by doing something like this:
CompareInfo ci = CultureInfo.CurrentCulture.CompareInfo;
for (int k = 0; k < fullpaths.Count; k++)
{
string line;
// Read the file and display it line by line.
System.IO.StreamReader FortranFile = new System.IO.StreamReader(fullpaths[k]);
while ((line = FortranFile.ReadLine()) != null)
{
// Search the file line-by-line for the variable
if (ci.IndexOf(line, Variable, CompareOptions.IgnoreCase) > 0)
{
// Search for the equals sign
int equalLocation = ci.IndexOf(line, "=");
if (equalLocation > 0)
{
// substring LHS
string subLineLHS = line.Substring(0, equalLocation+1);
// is the line commented out?
if (Convert.ToString(subLineLHS[0]) == "C" ||
Convert.ToString(subLineLHS[0]) == "!" ||
Convert.ToString(subLineLHS[0]) == "c" ||
Convert.ToString(subLineLHS[0]) == "*")
{
continue;
}
// ignore if the line contains a DO, IF, or WHILE loop,
// to prevent reading IF [Variable] = xxxx as being calculated.
else if ( (ci.IndexOf(subLineLHS, "IF", CompareOptions.IgnoreCase) > 0) ||
(ci.IndexOf(subLineLHS, "DO", CompareOptions.IgnoreCase) > 0) ||
(ci.IndexOf(subLineLHS, "WHILE", CompareOptions.IgnoreCase) > 0))
{
continue;
}
// find where the variable is used in the line
else if (ci.IndexOf(subLineLHS, Variable, CompareOptions.IgnoreCase) > 0 )
{
isCalculated[k] = true;
calculatedLine[k] = counter;
}
}
} //if loop
counter++;
} //while loop
FortranFile.Close();
}
The problems I'm having is with IF statements, e.g.:
IF(something == xx .AND.
1 variable == xx) THEN
...
this method would tell me that the variable is calculated on that line "variable = xx". 1-line if-statements such as IF(something) variable=xx are also ignored. Lines with multiple = signs may give me problems too.
Any suggestions on how I could get around this? Is there a better method of doing this? Please go easy on me - I'm not a programmer.
Thanks!
The most error-proof approach would be to parse the Fortran code and work from the syntax tree.
My suggestion: use ctags. See for instance Exuberant ctags; it has support for Fortran.
ctags generates an index of all named entities in a set of source code files. The index is stored in a data structure (tags) that can be read from most file editors/IDEs.
If you import that tags file in your favourite text editor, you will be able to jump to the definition of a variable when you position your cursor on it and take proper action.
The tags file is also very easy to read and parse: it structured like this.
named_entity<Tab>file_where_it_is_defined<Tab>location_in_the_file
For instance, from a set of Fortran files (this is on Linux, but Exuberant ctags offers Windows binaries):
gpar remlf90.f90 /^ xrank,npar,gpar,/;" v program:REMLF90
hashia1 ../libs/sparse2.f /^ subroutine hashia1(/;" s
hashv1 ../libs/sparse3.f /^ integer function hashv1(/;" f
hashvr_old ../libs/sparse2.f /^ integer function hashvr_old(/;" f
We can observe that the gparvariable is defined in remlf90.f90 and hashia1 is defined in ../libs/sparse2.f, etc.
What my program does is basically it lists file names (including it's extension) from a directory into a listbox. It then has a sorting function which sorts the list strings into alphabetical order.
Lastly it has a binary search function that allows the users to input any string which the program will then compare and display the matched results into a listbox.
Now, all these functions work perfectly however I can't seem to remove the extension off of a file name after a search.
For example in the scanning and sorting part it lists the file names as: filename.mp3
Now, what I want it do when the searching button is clicked is to remove the file extension and display just the filename.
private void buttonSearch_Click(object sender, RoutedEventArgs e)
{
listBox1.Items.Clear();
string searchString = textBoxSearchPath.Text;
int index = BinarySearch(list1, 0, list1.Count, searchString);
for (int n = index; n < list1.Count; n++)
{
//Removes file extension from last decimal point ''not working''
int i = list1[n].LastIndexOf(".");
if (i > 0)
list1[n].Substring(0, i);
// Adds items to list
if (list1[n].IndexOf(searchString, StringComparison.OrdinalIgnoreCase) != 0) break;
listBox1.Items.Add(list1[n]);
}
MessageBox.Show("Done");
}
C# is so easy that if something takes more than 2 minutes, there probably is a method for it in the Framework.
The Substring method returns a new fresh copy of the string, copied from the source one. If you want to "cut the extension off", then you must fetch what Substring returns and store it somewhere, i.e.:
int i = list1[n].LastIndexOf(".");
if (i > 0)
list1[n] = list1[n].Substring(0, i);
However, this is quite odd way to remove an extension.
Firstly, use of Substring(0,idx) is odd, as there's a Remove(idx)(link) which does exactly that:
int i = list1[n].LastIndexOf(".");
if (i > 0)
list1[n] = list1[n].Remove(i);
But, sencondly, there's even better way of doing it: the System.IO.Path class provides you with a set of well written static methods that, for example, remove the extension (edit: this is what L-Three suggested in comments), with full handling of dots and etc:
var str = System.IO.Path.GetFileNameWithoutExtension("myfile.txt"); // == "myfile"
See MSDN link
It still returns a copy and you still have to store the result somewhere!
list1[n] = Path.GetFileNameWithoutExtension( list1[n] );
Try like below ite will help you....
Description : Filename without Extension
listBox1.Items.Add(Path.GetFileNameWithoutExtension(list1[n]));
Use Path.GetFileNameWithoutExtension
Use Path.GetFileNameWithoutExtension method. Quite easy I guess.
http://msdn.microsoft.com/en-us/library/system.io.path.getfilenamewithoutextension.aspx
Not sure how you've implemented your directory searching, but you can leverage LINQ to your advantage in these situations for clean, easy to read code:
var files = Directory.EnumerateFiles(#"\\PathToFiles")
.Select(f => Path.GetFileNameWithoutExtension(f));
If you're using .NET 4.0, Enumerate files seems to be a superior choice over GetFiles. However it also sounds like you want to get both the full file path and the file name without extension. Here's how you could create a Dictionary so you'd eliminate looping through the collection twice:
var files = Directory.EnumerateFiles(#"\\PathToFiles")
.ToDictionary(f => f, n => Path.GetFileNameWithoutExtension(n));
A way to do this if you don't have a file path, just a file Name
string filePath = (#"D:/" + fileName);
string withoutExtension = Path.getFileNameWithoutExtension(filePath);
how to check if i have At least one file *.bak in my folder ?
You can list all files in a particular directory using Directory.GetFiles(). The second parameter is a pattern to search for (which includes wildcards). Something like this should do it:
var hasBak = Directory.GetFiles(yourdir, "*.bak").Length > 0;
Directory.GetFiles is correct, but not the best solution if you are using C# 4.0, because we have:
bool exist = Directory.EnumerateFiles(#"C:\mydir", "*.bak").Any();
Directory.GetFiles returns all those matched files, and you can check the Length property. But when we invoke Any to Directory.EnumerateFiles, essentially we get its enumerator and MoveNext, the method returns as soon as we found any item in it(in this way we always don't need to loop through all the files). I checked their implementation, and test with:
Directory.EnumerateFiles(#"C:\Windows", "*.log").Any();
GetFiles costs 4x time than EnumerateFiles(run them 10000 times, measuring by StopWatch).
Well, you can use Directory.GetFiles(directory. "*.bak") to get the list of bak files, and then just check whether the length is 0 or not.
if (Directory.GetFiles(directory, "*.bak").Length == 0)
{
// Complain to the user or whatever you want to do
}
public bool IsAtleastOneFilePresent()
{
string[] filePaths = Directory.GetFiles(#"c:\MyDir\", "*.bak");
if(filePaths.Length > 0) return true; else return false;
}
string[] files = Directory.GetFiles(#"c:\SomeDirectory\", "*.bak");
and ensure that files.Length > 0
Use Directory.GetFiles
Directory.GetFiles([dir], "*.bak")
http://msdn.microsoft.com/en-us/library/wz42302f.aspx