I't trying to get my program to read the most recent file in a directory with a few similar files and retrieve a name but its still reading all the files. If anyone knows why I'd appreciate the help :)
EDIT: Undo
here's my code:
public GetMyNames()
{
DirectoryInfo fileDirectory = new DirectoryInfo(#"C:\user\mark\folder");
List<string> files = new List<string>();
int creationDate = 0;
string CreationDate = "";
foreach (FileInfo fileInfo in fileDirectory.GetFiles("*.txt"))
{
string creationTime = fileInfo.CreationTime.ToString();
string[] bits = creationTime.Split('/', ':', ' ');
string i = bits[0] + bits[1] + bits[2];
int e = Int32.Parse(i);
if (e > creationDate)
{
creationDate = e;
files.Add(fileInfo.Name);
}
}
foreach(string file in files)
{
string filePath = fileDirectory + file;
string lines = ReadAllLines(filePath);
foreach (string line in Lines)
{
Name = Array.Find(dexLines,
element => element.StartsWith("Name", StringComparison.Ordinal));
}
MyName = Name[0];
}
Note that OrderBy runs at an order of O(nlog(n)) as it sorts the enumerable.
I suggest using Linq Max extension method, that is:
newestFile = files.Max(x => x.CreationDate);
this is more efficient (runs at an order of O(n)) and is more readable in my opinion
Why not use Linq and order by the date?
files.OrderBy(x => x.CreationDate)
Related
I am trying to sort files according to their creation time from a specific directory and store them in a string array. But I am getting the
error "Cannot implicitly convert type 'System.IO.FileInfo[]' to 'string[]'. Is it not possible the store the data
in string array?
Here is my code:
string[] getFiles(string path, string text, string fileExtension)
{
try
{
string searchingText = text;
searchingText = "*" + text + "*";
string[] filesArray = Directory.GetFiles(path, searchingText, SearchOption.TopDirectoryOnly).Select(f => new FileInfo(f)).OrderBy(f => f.CreationTime).ToArray();
//filesArray = filesArray.OrderBy(s => s.).ToArray();
//string[] filesArray2 = Array.Sort(filesArray);
List<string> filesList = new List<string>(filesArray);
List<string> newFilesList = new List<string>();
foreach(string file in filesList)
{
if ( file.Contains(fileExtension) == true)
{
newFilesList.Add(file);
}
}
string[] files = newFilesList.ToArray();
return files;
}
catch
{
string[] files = new string[0];
return files;
}
}
Where are you getting that error? The error is pretty self-explanotory: your function returns an array of strings, and you cannot simply cast a string to a FileInfo object. In order to get a FileInfo object, use:
var fi = new FileInfo(fileName);
However, if all you want is to get a sorted list, I'd go about this differently, for example:
var folder = #"C:\temp";
var files = Directory
.EnumerateFiles(folder)
.OrderBy(x => File.GetCreationTime(x))
.ToArray();
This will give you a list of strings holding file names, sorted by their creation date.
Edit:
If you'd only want files with a given extension, you could expand the LINQ query:
var files = Directory
.EnumerateFiles(folder)
.Where(x => x.EndsWith(".ext"))
.OrderBy(x => File.GetCreationTime(x))
.ToArray();
i need to find and delete all lines wich contain the word "recto",
i did search in stackoverflow forum, but all what i found is do that (delete the line) using path (Directory & FileName).
in my case i want to delete the line contain "recto" in all fils with specific extention (*.txt) in the directory.
thanks for help
here is my code so far
string sourceDir = #"C:\SRCE\";
string destinDir = #"C:\DIST\";
string[] files = Directory.GetFiles(sourceDir);
foreach (string file in files)
{
using (StreamReader sr_ = new StreamReader
(sourceDir + Path.GetFileName(file)))
{
string line = sr_.ReadLine();
if (line.Contains("recto"))
{
File.Copy(file, destinDir + Path.GetFileName(file));
string holdName = sourceDir + Path.GetFileName(file);
}
sr_.DiscardBufferedData();
sr_.Close();
}
}
}
You can try something like this. You were only identifying the files with the word but not making any try to remove it. At the end, you were copying the files that included the word "recto"
string sourceDir = #"C:\SRCE\";
string destinDir = #"C:\DIST\";
string[] files = Directory.GetFiles(sourceDir);
foreach (string file in files)
{
using (StreamReader sr_ = new StreamReader
(sourceDir + Path.GetFileName(file)))
{
string res = string.Empty;
while(!sr_.EndOfStream)
{
var l = sr_.ReadLine();
if (l.Contains("recto"))
{
continue;
}
res += l + Environment.NewLine;
}
var streamWriter = File.CreateText(destinDir + Path.GetFileName(file));
streamWriter.Write(res);
streamWriter.Flush();
streamWriter.Close();
}
}
If the files are not really big you can simplify a lot your code reading all lines in memory, processing the lines with Linq and then rewriting the files
string sourceDir = #"C:\SRCE\";
string destinDir = #"C:\DIST\";
string[] files = Directory.GetFiles(sourceDir);
foreach (string file in files)
{
var lines = File.ReadLines(file);
var result = lines.Where(x => x != "recto").ToArray();
File.WriteAllLines(Path.Combine(destinDir, Path.GetFileName(file)), result);
}
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;
I've asked a very similar question before here. But that was about getting directories, and this is about files. And these codes are a bit different from each other. Ever since I've been trying to convert this to make it look like the answer on my old question, I haven't been able to make it work.
string[] files = Directory.GetFiles(ScanPath, "*.*", System.IO.SearchOption.AllDirectories);
DateTime From = DateTime.Now.AddHours(-24);
DateTime To = DateTime.Now;
foreach (string name in files)
{
FileInfo file = new FileInfo(name);
string fullname = file.FullName;
if (file.LastWriteTime >= From & file.LastWriteTime <= To && file.Length >= ScanSize)
Console.WriteLine(file.FullName + " ; " + "last changed at " + " ; " + file.LastWriteTime.ToString());
}
I've been getting the same errors as I explained in the other question. Because I don't know where to put the code of the foreach in a recursion. Since it's not an enumeration but a Directory.GetFiles().
The error occurs with:
Directory.GetFiles(ScanPath, "*", SearchOption.AllDirectories);
because this gets all the files of the directories at once. But if I remove it, it only gets the files in the given path, without any of the files in the subdirectories. So I was told to apply recursion.
I am the administrator of the system and I plan to run this on the entire data drive. D:\
I'm hoping anyone here knows a good example.
Your app could not have access rights to some folders, for others you can use the following code:
void DiscoverDirs(string where, List<string> files, Func<FileInfo, bool> filter)
{
try
{
var di = new DirectoryInfo(where);
files.AddRange(di.EnumerateFiles().Where(filter).Select(x => x.FullName));
foreach (var dir in Directory.GetDirectories(where))
{
DiscoverDirs(dir, files, filter);
}
}
catch
{
// no access fo this dir, ignore
}
}
Usage:
DateTime From = DateTime.Now.AddHours(-24);
DateTime To = DateTime.Now;
var ScanSize = 5*1024*1024;
var list = new List<string>();
DiscoverDirs(#"C:\", list,
file => file.LastWriteTime >= From & file.LastWriteTime <= To && file.Length >= ScanSize);
foreach (string name in list)
{
FileInfo file = new FileInfo(name);
string fullname = file.FullName;
Console.WriteLine(file.FullName + " ; " + "last changed at " + " ; " + file.LastWriteTime.ToString());
}
You might be getting "UnauthorizedAccessException" while accessing the some of the system directories.List of the directory causing the problems are directories which are actually just redirection to other directory.
May be you can tried out the following code if it helps-
try
{
foreach (String file in Directory.GetFiles(directoryName, pattern, SearchOption.TopDirectoryOnly))
{
// do stuff
}
catch (UnauthorizedAccessException uae)
{
//handle
}
catch (Exception e)
{
//handle
}
Alternative:
string[] directories = Directory.GetDirectories(ScanPath);
foreach (string directory in directories)
{
string[] filesinCurrentDirectory = Directory.GetFiles(directory, "*.*", System.IO.SearchOption.AllDirectories);
foreach (string file in filesinCurrentDirectory)
{
MessageBox.Show(file);
}
}
I create a FileInfo array like this
try
{
DirectoryInfo Dir = new DirectoryInfo(DirPath);
FileInfo[] FileList = Dir.GetFiles("*.*", SearchOption.AllDirectories);
foreach (FileInfo FI in FileList)
{
Console.WriteLine(FI.FullName);
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
And this array holds all the file names in folder = DirPath
I thought of looping through the FileInfo array and copy it to a String array. Is this ok or is there a much cleaner method ?
Using LINQ:
FileList.Select(f => f.FullName).ToArray();
Alternatively, using Directory you can get filenames directly.
string[] fileList = Directory.GetFiles(DirPath, "*.*",
SearchOption.AllDirectories);
If you want to go the other way (convert string array into FileInfo's) you can use the following:
string[] files;
var fileInfos = files.Select(f => new FileInfo(f));
List<FileInfo> infos = fileInfos.ToList<FileInfo>();
the linq is a great soluction, but for the persons who don't want to use linq, i made this function:
static string BlastWriteFile(FileInfo file)
{
string blasfile = " ";
using (StreamReader sr = file.OpenText())
{
string s = " ";
while ((s = sr.ReadLine()) != null)
{
blasfile = blasfile + s + "\n";
Console.WriteLine();
}
}
return blasfile;
}
Try this one
DirectoryInfo directory = new DirectoryInfo("your path");
List<string> Files = (directory.GetFiles().Where(file => file.LastWriteTime >= date_value)).Select(f => f.Name).ToList();
If you don't want a filter with date, you can simply convert with the below code
List<string> logFiles = directory.GetFiles().Select(f => f.Name).ToList();
If you need the full path of the file, you can use FullName instead of Name.