I need some Regular expression experts for an extra hand. :)
I have different paths,different folders,different amount of folders.
My question:How do I get the last thing - the filename?
For example in the path:
C:\a\b\c\d\e\fgh.ddj
How do I get "fgh.ddj" with regular expressions?
You don't need regex's, you can do it just like this, its a system.io helper function:
myfilename = Path.GetFileName(mypath);
You can also use FileInfo. When using FileInfo, it actually doesn't matter if the file is present or not.
var fileInfo = new FileInfo("C:\a\b\c\d\e\fgh.ddj");
var fileName = fileInfo.Name;
//this returns "fgh.ddj"
If the file is present, of course there's lots of info about file size, last accessed, etc.
If you have perl installed, then you can try something like this...
#!/usr/bin/perl
use strict;
my $fullname = 'C:\a\b\c\d\e\fgh.ddj';
my $file = (split /\\/, $fullname)[-1];
print $file;
Related
I want to create a data file, but before writing to the final file I want to drop it in a temporary location to avoid user confussion. As an example, I could begin with test.txt and want to have test.txt.tmp. The names could include a path, but the files may not necesarily exist (so this question is purely about string manipulation).
The closest I have been is to use Path.ChangeExtension:
string original = "test.txt";
string temp = Path.ChangeExtension(original, "tmp");
But that returns test.tmp instead. So my question is if there is a built-in method to achieve that "dual-extension" file name? I could always use brain-dead string concatenation, but I'm looking for a more safe and tested method.
Avoiding pitfalls is a great idea for things like Path.Combine, e.g. because you don't want to be bothered checking if there is no missing \ character.
But there are no pitfalls here.
If your original filename is as you expect it to be, then string concatenation will work.
If your original file name is not as you expect it to be, then the issue lies with whoever supplied you a faulty filename. "Shit goes in, shit comes out" is not really something your internal logic should worry about. An algorithm can only be as correct as the information that it receives.
String concatenation is perfectly acceptable here. There is no premade method here because there is no real pitfall to simply concatenating the strings.
Special shout out to AlessandroD'Andria's suggestion:
Path.ChangeExtension(original, Path.GetExtension(original) + ".tmp");
Technically, it employs Path logic and therefore fits with your criteria. I genuinely like the cleverness of following your expectations.
However, there is simply no merit to doing so. By its very nature an extension is defined as being "the last part of the filename".
Whether you do a direct string concatenation, or instead do this:
chop the string into two pieces (filename, extension)
append something to the last piece (extension + temp extension)
paste everything together again
The end result will always be the same. The chopping of the string is unnecessary work.
Why can't you append that string just like
if(!string.IsNullOrEmpty(Path.GetExtension(original)){
original+= ".tmp";
}
You should use temp file and rename the extension.
string path = Path.GetTempFileName();
// some logic on the file then rename the file and move it when you need it
string fileName = Path.GetFileName(path);
File.Move(path, path.Replace(fileName, "test.txt"));
If you would use temp file, you can use Path.GetTempFileName();
string tempFileName = Path.GetTempFileName();
Or in your case:
string original = "test.txt";
string temp = "test.txt" + ".tmp";
I know how to get all files that match the search pattern in a folder like this:
DirectoryInfo folderInfo = new DirectoryInfo(folderPath);
FileInfo[] fileInfos = folderInfo.GetFiles(searchPattern);
But my problem is, if I already know the file path, how can I match it with the search pattern? For compatibility, the search pattern has to be the same format like *.jpg or something.
I'm interpreting your question as meaning you already have a string for the file path and just want to check whether it matches a certain pattern. For this you first need to consider whether pattern patching is really what you need, it may be preferable to just use the extension directly for example.
Assuming that is not an option, you're probably going to want to use regular expressions. You will need to convert the string with wild-cards to a regular expression. Unfortunately I'm not aware of any built in ways of doing this, but it should be possible to do by simply escaping any characters which would have meaning in a regex and replacing the wild cards with appropriate regular expressions.
Well if you already have the full file path and you isolate the extension only, using Path.GetExtension or similar, then you just add a * before you are are set, right?
If u already know the path, Don't use search pattern.
Try
FileInfo fi = new FileInfo(FilePath);
you can use Directory.GetFiles like "Directory.GetFiles("d:/xxx/*.jpg")" to get string array of all match files, and then to open or handle the single file.
I have got a strange template whose extension is ".docx.amp" . Now i want to get fileName. i.e "template". Path.GetFileNameWithoutExtension() fails as it returns template.docx. Is there any other built in mechanism or i will have to go the ugle string comparison/split way. Please suggest and give some workaround
Nope, you will have to use some kind of string split, eg:
var nameWithoutExtension = filename.Split('.')[0];
I tried using Path.GetDirectoryName() but it doesn't work.
What I'm trying to get is from /home/nubela/test/some_folder , I wanna get "some_folder"
How can I do this? The method should work for both Windows/Linux (Mono)
Thanks!
Use Path.GetFileName instead? These functions work just on the string you provide and don't care if it's a directory or a file path.
If you have the path as a string already you can use this method to extract the lowest level directory:
String dir
= yourPath.Substring(
yourPath.LastIndexOf(Path.DirectorySeparatorChar) + 1);
Since this code uses Path.DirectorySeparatorChar it is platform independent.
My first idea would be to use System.IO.Path.GetDirectoryName, too. But you can try a regular expression to get the final substring of your string. Here is an answer in StackOverflow, using regular expressiones, that answers this.
I've used the setargv.obj linking for Expanding Wildcard Arguments in the past for a number of C and C++ apps, but I can't find any similar mention for .net applications.
Is there a standard way to have your app's command line parameters automatically wildcard expanded? (i.e. expand *.doc from one entry in args parameter to all that match that wildcard).
P.S. I've hacked something together with Directory.GetFiles() for my current little project, but it does not cover wildcards with paths (yet), and it would be nice to do it without custom code.
Update: here is my rough hack, for illustration. It needs to split the parameters for the path and name for the GetFiles(), but this is a general idea. Linking setargv.obj into a C or C++ app would basically do all the wildcard expansion, leaving the user to only iterate over the argv array.
public static void Main(string[] args)
{
foreach (string argString in args)
{
// Split into path and wildcard
int lastBackslashPos = argString.LastIndexOf('\\') + 1;
path = argString.Substring(0, lastBackslashPos);
filenameOnly = argString.Substring(lastBackslashPos, argString.Length - lastBackslashPos);
string[] fileList = System.IO.Directory.GetFiles(path, filenameOnly);
foreach (string fileName in fileList)
{
// do things for each file
}
}
}
Here us my rough hack. I'd love for it to be recursive. And having experienced the shortcoming of Windows wildcards I might decide to use regular expressions rather than letting GetFiles() do it for me.
using System.IO;
public static string[] ExpandFilePaths(string[] args)
{
var fileList = new List<string>();
foreach (var arg in args)
{
var substitutedArg = System.Environment.ExpandEnvironmentVariables(arg);
var dirPart = Path.GetDirectoryName(substitutedArg);
if (dirPart.Length == 0)
dirPart = ".";
var filePart = Path.GetFileName(substitutedArg);
foreach (var filepath in Directory.GetFiles(dirPart, filePart))
fileList.Add(filepath);
}
return fileList.ToArray();
}
I'm not sure exactly what you're after... but if I get where you're going with the Directory.GetFiles() "hack" you mentioned, then something like this might work:
var Dirs = Directory.GetDirectories(#"C:\Windows", "sys*",
SearchOption.TopDirectoryOnly).ToList();
var Files = new List<String>();
Dirs.ForEach(dirName => Files.AddRange(Directory.GetFiles(dirName, "*.sys", SearchOption.AllDirectories)));
The wildcard option on the GetDirectories call will allow you to grab all the directories contained in the Windows folder [directly] that match the pattern "sys*".
You can then iterate over those folders grabbing all the files that match the pattern "*.sys".
Is that the kind of thing you're looking for? To automatically expand the args, you'd have to extract the wildcards in some kind of meaningful manner and apply them to that model...
For instance:
RunMyApp "C:\Windows\Sys*\ *.sys"
You'd pull out the string C:\Windows - probably with a regular expression, find the lowest level directory that doesn't contain a wildcard and apply it to the GetDirectories method, attaching the wildcarded string as the search parameter.
Then if your end of string (in this case *.sys) as the search pattern for Directory.GetFiles.
If you wanted to get more complicated and do something like:
C:\Windows\*\Sys*\*.sys
You would use the SearchOptions to set this behaviour:
Directory.GetDirectories(#"C:\Windows", "sys*", SearchOptions.AllDirectories)
This would grab all directories that matched the sys* wildcard in the Windows directory and all directories below it.
If you wanted to get much more complicated than that, then I'm not sure how you would do that... for instance, say you wanted folders that are contained by folders directly inside the Windows directory - I have no idea how you would go about something like that I'm afraid...I don't imagine exporting the entire tree structure to XML and using XPath to do it would be so efficient - the XPath would be fabulously simple for parsing out using wildcards - but converting to XML wouldn't be so efficient...
see the source code of disassembled Microsoft.Build.Shared.FileMatcher class in Microsoft.Build.dll
you can get some idea from the implementation of method GetFiles.
as a client you may use the method as follows
var filelist = FileMatcher.GetFiles(#"c:\alaki",#"c:\alaki\**\bin\*.dll");
Your code looks like exactly how you're supposed to do it.