I'm trying to search for a specific value within an array of files. I'm not sure what I'm missing here, but some insight would be great.
I've tried containing all lines from each file into an array that can be read from within an if statement.
void getAssetTag()
{
string path = #"\\SERVER\SHARE\FOLDER";
DirectoryInfo d = new DirectoryInfo(path);//Grabbing Directory
FileInfo[] Files = d.GetFiles("*.txt"); //Getting Text files
foreach (FileInfo file in Files)
{
string[] asset = File.ReadAllLines(file.FullName);
if (asset.Contains(AssetT.Text) == true) {
string allinfo = File.ReadAllText(file.FullName);
Results.Text = allinfo;
}
}
}
The results should output the entire data from the text file contained within AssetT.Textinto Results.Text.
asset is a string[], where each string is a line of text. When you do if (asset.Contains(AssetT.Text)), you're comparing an entire line to AssetT.Text.
If you want to find out if any single line contains AssetT.Text, then we need to call Contains on the line, not the array:
if (asset.Any(line => line.Contains(AssetT.Text))
Also, you're ending up reading the file twice here, once when you do ReadAllLines, and again when you do ReadAllText. Since it seems you will always read the whole file (either to determine that the file doesn't contain the text, or to get all the contents because it does contain the text), you should just do it once.
If you use File.ReadAllText in the beginning, now we have a string representation of the entire file which we can call .Contains on:
foreach (FileInfo file in new DirectoryInfo(path).GetFiles("*.txt"))
{
string asset = File.ReadAllText(file.FullName);
if (asset.Contains(AssetT.Text))
{
Results.Text = asset;
// No use reading more files unless we're going
// to save the contents to another variable
break;
}
}
Note that we break out of the loop since it appears you're setting the contents of the file to a single field of some class, so searching for more files will just overwrite any previous results found.
This can be simplified further using System.Linq extension methods and method chaining. We can also use Directory.GetFiles (which returns a list of file paths) instead, since we don't need a full-blown FileInfo object:
Results.Text = Directory
.GetFiles(path, "*.txt")
.Select(File.ReadAllText)
.FirstOrDefault(fileText => fileText.Contains(AssetT.Text)) ?? Results.Text;
Related
I am making project on getting all text files from a selected drive. The thing is I am getting names of all text files along with path but all I need is name. I don't want to even get the extension, all I want is name of that text file. I have searched all over the internet but couldn't find the right answer. I am storing all those names in a listbox. here is my code:
String[] dir1 = System.IO.Directory.GetDirectories(#"F:\");
for (int i = 0; i < dir1.Length; i++)
{
FileAttributes attributes = File.GetAttributes(dir1[i]);
if ((attributes & FileAttributes.Hidden) != fileAttributes.Hidden)
{
string folder = #""+ dir1[i];
txtfiles = Directory.GetFiles(folder, "*.txt");
listBox1.Items.AddRange(txtfiles);
}
}
How can I get only names, instead of whole path and extension?
The Path.GetFileNameWithoutExtension method will do this for you.
https://msdn.microsoft.com/en-us/library/system.io.path.getfilenamewithoutextension(v=vs.110).aspx
Returns the file name of the specified path string without the extension.
Pass the results of GetFiles into the method and it should return what you need.
Take a look at System.IO.Path.GetFileNameWithoutExtension()
You could do something like
txtfiles = Directory.GetFiles(folder, "*.txt");
var fileNames = txtfiles.Select(System.IO.Path.GetFileNameWithoutExtension).ToList();
You need to use Path.GetFileName method which will just extract the file name only from the path back, so what you can do is project the txtfiles to get the collection of just filename like:
listBox1.Items.AddRange(txtfiles.Select(file=>Path.GetFileName(file));
and if you only need path, not actually reading them, you can use EnumerateFiles method which would be better in memory performance which would be :
listBox1.Items.AddRange(txtDirectory.EnumerateFiles(folder, "*.txt")
.Select(file=>Path.GetFileName(file))
);
Also if you only need name of file without extension then you can do as Valuator answer suggested.
I'm trying to write a nifty content loader in XNA to avoid having to individually load each asset. However, I'm having trouble describing directory locations because the default directory for File operations is the location of the exe, but XNA's Content.Load uses a default directory of the Content folder.
foreach (string subD in Directory.GetDirectories("..\\..\\..\\..\\Happy WorkerContent\\gfx\\", "*.*", SearchOption.AllDirectories))
{
foreach (string s in Directory.GetFiles(subD))
{
string file = Path.GetFileNameWithoutExtension(s);
if (Enum.IsDefined(typeof(Tex), file))
{
Console.WriteLine(subD);
Console.WriteLine(file);
GXDict.Add(Path.GetFileNameWithoutExtension(s), GV.C_Game1.Content.Load<Texture2D>(subD + "\\" + file));
}
}
}
My error is because subD is, for example, "........\Happy WorkerContent\gfx\level entities\terrains", but Content.Load expects "gfx\level entities\terrains".
I could do something like subD.Substring(32), but this seems messy, especially if I rename any folders or anything later (and may not work in the published version?). Is there a good way to say "I only want the part of the file which is after the "Happy WorkerContent" directory?
You could write a method to return the text following a particular target string.
Then if you needed to search for a different string, you'd just need to pass a different target string to the method.
For example:
// Returns the contents of text following the target string,
// or "" if the target string wasn't found.
public static string ContentAfter(string text, string target)
{
int index = text.IndexOf(target);
if (index >= 0)
return text.Substring(index + target.Length);
else
return "";
}
Then you'd call it like:
string test = "..\\..\\..\\..\\Happy WorkerContent\\gfx\\whatever";
string target = "\\Happy WorkerContent\\";
string following = ContentAfter(test, target);
That wouldn't work so great if you had two strings matching the target string in the text. The method would return all the text after the first match, which would include the second target string of course.
I have a list of .cs files, each of which contain a string commandID. I need to retrieve the value of this string.
How do I implement this search and retrieve value mechanism in C#?
//Sample code to list all .cs files within a directory
string[] filePaths = Directory.GetFiles(#"c:\MyDir\", "*.cs");
// Sample code to read 1 file.
// Read each line of the file into a string array. Each element
// of the array is one line of the file.
string[] lines = System.IO.File.ReadAllLines(#"C:\Users\Public\TestFolder\file1.cs");
// Display the file contents by using a foreach loop.
foreach (string line in lines)
{
// INSERT YOUR SEARCH LOGIC HERE
}
I am assuming that, there is some string named CommandId in your .Cs files in your project and you are trying to get the value of it because you donot want to manually go to each file and get its value.
Follow the following
1- Paste all the .CS files in a separate folder.
2- Use FileSytem to get all the files in that folder
3- Use stream reader to get the text in the .cs files
4- compare each line in the file with the text you want to find.
5- If the string matches, the save it somewhere like XML or another text file.
6- Read the next file and Go back to step 3.
Finally got the ID out of it :)
let's say you have found the line you want, so I get the ID out of the line like :
string line = "while(i<10){CommandID = 15852; i+=1;}";
//I've put a complicated code in the string to make you sure
var rightSideOfAssignment = line.Split(new string[] {"CommandID"}, StringSplitOptions.RemoveEmptyEntries)[1];
int val = 0,temp;
bool hasAlreadyStartedFetchingNumbers= false;
foreach (char ch in rightSideOfAssignment) //iterate each charachter
{
if (int.TryParse(ch.ToString(), out temp)) //if ch is a number
{
foundFirstInteger = true;
val *= 10;
val += temp;
}
else
{
if (hasAlreadyStartedFetchingNumbers)
break;
//If you don't check this condition, it'll result to 158521
//because after hitting `;` it won't stop searching
}
}
MessageBox.Show(val.ToString()); //shows 15852
I wish to delete image files. The files are named somefile.jpg and somefile_t.jpg, the file with the _t on the end is the thumbnail. With this delete operation I wish to delete both the thumbnail and original image.
The code works up until the foreach loop, where the GetFiles method returns nothing.
The string.Substring operation successfully returns just the file name with no extension and no _t e.g: somefile.
There are no invalid characters in the file names I wish to delete.
Code looks good to me, only thing I can think of is that I am somehow not using the searchpattern
function properly.
filesource = "~/somedir/somefile_t.jpg"
var dir = Server.MapPath(filesource);
FileInfo FileToDelete = new FileInfo(dir);
if (FileToDelete.Exists)
{
var FileName = Path.GetFileNameWithoutExtension(FileToDelete.Name);
foreach(FileInfo file in FileToDelete.Directory.GetFiles(FileName.Substring(0, FileName.Length - 2), SearchOption.TopDirectoryOnly).ToList())
{
file.Delete();
}
}
DirectoryInfo.GetFiles Method (String, SearchOption)
You need to ensure that the first parameter, searchPattern, is proper. In you're case you are supplying FileName.Substring(0, FileName.Length - 2), which would be "somefile". The reason the method returns nothing is because you are looking for files literally named somefile. What you meant to do was to use a wildcard in addition to the base filename: String.Concat(FileName.Substring(0, FileName.Length - 2), "*"), which would be "somefile*" ... at least I think you're looking for that searchPattern as opposed to any other one.
This code works for me:
var file_path = #"K:\Work\IoCToy\IoCToy\image.jpg";
var dir = Path.GetDirectoryName(file_path);
var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file_path);
var files = Directory.EnumerateFiles(dir, string.Format("{0}*", fileNameWithoutExtension), SearchOption.TopDirectoryOnly);
Of course, you have to delete the files by the returned file names. I am assuming here that your folder contains only the image and the thumbnail file which start with the "image" substring.
I have a directory that contains jpg,tif,pdf,doc and xls. The client DB conly contains the file names without extension. My app has to pick up the file and upload the file. One of the properties of the upload object is the file extension.
Is there a way of getting file extension if all i have is the path and name
eg:
C:\temp\somepicture.jpg is the file and the information i have through db is
c:\temp\somepicture
Use Directory.GetFiles(fileName + ".*"). If it returns just one file, then you find the file you need. If it returns more than one, you have to choose which to upload.
Something like this maybe:
DirectoryInfo D = new DirectoryInfo(path);
foreach (FileInfo fi in D.GetFiles())
{
if (Path.GetFileNameWithoutExtension(fi.FullName) == whatever)
// do something
}
You could obtain a list of all of the files with that name, regardless of extension:
public string[] GetFileExtensions(string path)
{
System.IO.DirectoryInfo directory =
new System.IO.DirectoryInfo(System.IO.Path.GetDirectoryName(path));
return directory.GetFiles(
System.IO.Path.GetFileNameWithoutExtension(path) + ".*")
.Select(f => f.Extension).ToArray();
}
Obviously, if you have no other information and there are 2 files with the same name and different extensions, you can't do anything (e.g. there is somepicture.jpg and somepicture.png at the same time).
On the other hand, usually that won't be the case so you can simply use a search pattern (e.g. somepicture.*) to find the one and only (if you're lucky) file.
Search for files named somepicture.* in that folder, and upload any that matches ?
Get the lowest level folder for each path. For your example, you would have:
'c:\temp\'
Then find any files that start with your filename in that folder, in this case:
'somepicture'
Finally, grab the extension off the matching filename. If you have duplicates, you would have to handle that in a unique way.
You would have to use System.IO.Directory.GetFiles() and iterate through all the filenames. You will run into issues when you have a collision like somefile.jpg and somefile.tif.
Sounds like you have bigger issues than just this and you may want to make an argument to store the file extension in your database as well to remove the ambiguity.
you could do something like this perhaps....
DirectoryInfo di = new DirectoryInfo("c:/temp/");
FileInfo[] rgFiles = di.GetFiles("somepicture.*");
foreach (FileInfo fi in rgFiles)
{
if(fi.Name.Contains("."))
{
string name = fi.Name.Split('.')[0].ToString();
string ext = fi.Name.Split('.')[1].ToString();
System.Console.WriteLine("Extension is: " + ext);
}
}
One more, with the assumption of no files with same name but different extension.
string[] files = Directory.GetFiles(#"c:\temp", #"testasdadsadsas.*");
if (files.Length >= 1)
{
string fullFilenameAndPath = files[0];
Console.WriteLine(fullFilenameAndPath);
}
From the crippled file path you can get the directory path and the file name:
string path = Path.GetDirectoryName(filename);
string name = Path.GetFileName(filename);
Then you can get all files that matches the file name with any extension:
FileInfo[] found = new DirectoryInfo(path).GetFiles(name + ".*");
If the array contains one item, you have your match. If there is more than one item, you have to decide which one to use, or what to do with them.
All the pieces are here in the existing answers, but just trying to unify them into one answer for you - given the "guaranteed unique" declaration you're working with, you can toss in a FirstOrDefault since you don't need to worry about choosing among multiple potential matches.
static void Main(string[] args)
{
var match = FindMatch(args[0]);
Console.WriteLine("Best match for {0} is {1}", args[0], match ?? "[None found]");
}
private static string FindMatch(string pathAndFilename)
{
return FindMatch(Path.GetDirectoryName(pathAndFilename), Path.GetFileNameWithoutExtension(pathAndFilename));
}
private static string FindMatch(string path, string filename)
{
return Directory.GetFiles(path, filename + ".*").FirstOrDefault();
}
Output:
> ConsoleApplication10 c:\temp\bogus
Best match for c:\temp\bogus is [None found]
> ConsoleApplication10 c:\temp\7z465
Best match for c:\temp\7z465 is c:\temp\7z465.msi
> ConsoleApplication10 c:\temp\boot
Best match for c:\temp\boot is c:\temp\boot.wim