I d like to create a blind test generator with a script using Sony vegas 14. For this I must make my script in C#.
I don’t have many experiences in C# so maybe my problem is a very basic one.
To do my script I must use a library class (.dll) and execute my script by Sony vegas. To test my code easily I create a console app where I try my code and can easily print in the console what my code does.
For my program y need to get the path of all subdirectory in a Directory in a string.
My problem is the next one.
the command "Directory.GetDirectories" don't work
When I use the next code to check what in my array/list I get a coherent result if I use it in the console app version on my script (the number of subdirectories in my directory)
string[] dirs = Directory.GetDirectories(myDirectorypath, "", SearchOption.TopDirectoryOnly);// get all directory path in dirs
Console.WriteLine("the number of element in your array is "+ dirs.Length);
List<string> listdedossier = new List<string>(dirs); // convert the array in a list
Console.WriteLine("the number of element in your list is " + listdedossier.Count);
But when in paste my code in my dll project nothing is written in my array or my list. I notice this because when I want to print the number of elements in the list /array that return me 0
.
do you have any idea of what happen i my code?
thanks
You should check the online Microsoft documentation for GetDirectories. The 2nd argument is supposed to be a pattern to search for that conforms to Windows file name patterns. Essentially, all or part of a file name is allowed with * being a wildcard (The .* from regex meaning "match any character any number of times") and ? being a single character wildcard (regex .). You are providing an empty string, so you get nothing back. The pattern *.exe will match all executables in a folder (if you are using GetFiles, while the pattern pattern* matches any files/folders that start with pattern. If you want all directories, do this:
string[] dirs = Directory.GetDirectories(myDirectoryPath, "*", SearchOption.TopDirectoryOnly);
Next point, the path you provide can be either a relative path (e.g., "relative\path\to\folder"), an absolute path (e.g., "D:\path\to\folder"), or a fully qualified domain name (FQDN, e.g. "\servername.gov.edu.com\drive$\path\to\folder"). If you supply a relative path, you'll need to look up Windows' rules for path resolution. It is very easy using a relative path to search the wrong folder, or even a non-existent location (though you should get an exception in that case). Also remember: Windows path names are NOT case-sensitive.
Finally, when writing text with arguments, I HIGHLY recommend you use this format:
Console.WriteLine("The number of elements in your array is {0}", dirs.Length);
This uses a place holder in the string itself which has a numeric value in it. The number indicates what argument after the format string to use (0 is the first argument after the format string). You can use as many placeholders as you want, and use the same place holder in multiple locations. This is a more type-safe way to doing string printing in C# than using the + operator, which requires that an operator be defined that takes a string and whatever type you provided. When you use placeholders, WriteLine will use the built-in ToString method which is defined for all types in the Object class. Placeholders will always work, while using + will only sometimes work.
Related
I am trying to find a regular expression to parse two sections out of the file name for the .resx files in my project. There is one main file called "UiText.resx" and then many translation .resx files with convention "UiText.ja-JP.resx". I need both the "UiText" and the "ja-JP" out of the latter string, as we do have other resx files that don't have to be for UiText (e.g. I have some files named "ExceptionText.resx").
The pattern I'm using right now (which works, it just requires a little extra coding after) is "(?<=\.)((.*?)(?=\.resx))". For the example above, "UiText.ja-JP.resx" gets me a match set in C# of "UiText.", "ja-JP.", "ja-JP.", ".resx"
Of course I am able to just take the first occurrence of "ja-JP." and "UiText." from this set and massage it to what I want, but I'd rather just have a cleaner "UiText" "ja-JP" and be done with it.
I figure I'll probably have to have at least two different patterns for this, so that is OK. Thank you in advance!
Since UiText seems to be constant you can use this regex to extract just js-JP into $1:
^UiText\.(.+?)\.resx$
https://regex101.com/r/XKvwHA/1/
If I'm understanding your needs correctly, then the main reason you need "UiText" is not because you have any value for the term itself, but rather because you need to filter your files. The real term you need to play around with is "ja-JP", which changes for the files you need.
If I'm correct, try this regex:
(?<=UiText\.).+(?=\.resx)
Used in C# as follows:
var fileName = "UiText.ja-JP.resx";
var result = new Regex(#"(?<=^UiText\.).+(?=\.resx$)").Match(fileName).Value;
A little explanation:
(?<=^UiText\.) Start of string must begin exactly with "UiText."
.+ Any number of characters (but at least one)
(?=\.resx$) End of string must end with ".resx"
Any file that doesn't meet your criteria will return an empty string for 'result'.
I am developing a program that functions similar to the MS-DOS command "cd". The user types "cd.." into the program's prompt and then, using Stringbuilder, remove the characters representing the user's current directory. It would function like this:
Prompt> cd..
with a Stringbuilder instance declared in the code file:
Stringbuilder builder = new Stringbuilder(#"E:\Folder");
After the user types "cd.." and hits Enter, the program would remove the directory at the end of the Stringbuilder value, with the end result like this:
Stringbuilder builder = new Stringbuilder(#"E:\");
I am not sure how I can do this, or if it is even possible to do. I thought I could try builder.Length - Directory.Length to get the length of the directory name, and then use builder.Remove(int StartIndex, int length), but I don't know how that could be implemented.
Another thing I could possibly use is using builder.ToString() and split it, using the backslash as the seperator.
Any suggestions?
You could use Path.GetDirectoryName, but it's kind of dumb. It just does string manipulation with no idea what the file system actually looks like. For example, if you do Path.GetDirectoryName(#"E:\Folder\") it will return "E:\Folder", because there was a slash at the end of the string you gave it. Or you could feed it a folder that doesn't even exist, and it'll still give you an answer.
I can suggest another way to do this: keep a DirectoryInfo object for the current working directory. For example:
var curDirectory = new DirectoryInfo(#"E:\Folder");
When you need to display it, use curDirecotry.FullName, which will return the full path, like "E:\Folder". Then when you need to go up a directory, it's one line with no string manipulation:
curDirectory = curDirectory.Parent;
Although you do have to check it for null since, if you are already at the root of the drive, Parent will be null.
DirectoryInfo actually looks at the file system so you can be sure that it's always valid. Plus, you can use it for seeing the contents of the folder too, which I'm sure you will want to do.
I notice that when I use Path.GetFullPath(Path.Combine(#"c:\folder\","\subfolder\file.txt")) it returns a path c:\subfolder\file.txt, instead of the expected combined path c:\folder\subfolder\file.txt. It seems like having a '\' on the second combined input isn't handled by these methods. Has anyone come across this and found a better solution for merging paths?
var test1 = Path.GetFullPath(Path.Combine(#"C:\users\dev\desktop\testfiles\", #".\test1.txt"));
var test2 = Path.GetFullPath(Path.Combine(#"C:\users\dev\desktop\testfiles\", #"\test2.txt"));//
var test3 = Path.GetFullPath(Path.Combine(#"C: \users\dev\desktop\testfiles\", #"test3.txt"));
var test4 = Path.GetFullPath(Path.Combine(#"C:\users\dev\desktop\testfiles\",#".\XXX\test4.txt"));
var test5 = Path.GetFullPath(Path.Combine(#"C:\users\dev\desktop\testfiles\", #"\XXX\test5.txt"));//
var test6 = Path.GetFullPath(Path.Combine(#"C:\users\dev\desktop\testfiles\", #"XXX\test6.txt"));
var test7 = Path.GetFullPath(Path.Combine(#"C:\users\dev\desktop\testfiles\", #"\somefile\that\doesnt\exist.txt"));//
Results in
test1 is "C:\users\dev\desktop\testfiles\test1.txt"
test2 is wrong "\test2.txt"
test3 is "C: \users\dev\desktop\testfiles\test3.txt"
test4 is "C:\users\dev\desktop\testfiles\XXX\test4.txt"
test5 is wrong "c:\XXX\test5.txt"
test6 is "C:\users\dev\desktop\testfiles\XXX\test6.txt"
test7 is wrong "c:\somefile\that\doesnt\exist.txt"
Basically what I'm doing is combining a source path with individual file paths from a text file so that I can copy these files to a destination, and I want to maintain subfolder hierarchy.
e.g. common scenario of the files list being the same, but wanting to reference a specific source folder version.
source path + individual file path
\\myserver\project\1.x + \dll\important.dll
which should be copied to a destination in the same manner
c:\myproject\ + \dll\important.dll
So there would be variables; source, destination, files[array or list]
My current way forward is to use String.TRIM() method to remove special chars . \ / before combining paths with Path.Combine, Path.GetFullPath. But I thought maybe someone has realized a better way for a similar scenario.
It's also a pain creating the subfolders in the destination, basically im using String.LastIndexOf(#'\') to separate the filename from the foldername. Which is also seems a little sketchy, but a better way is beyond my experience.
Similar question:
Path.Combine absolute with relative path strings
Thanks to the feedback I now know that \file.txt is considered a fully qualified (absolute) path, which is why the combine method works that way.
A file name is relative to the current directory if it does not begin with one of the following:
A UNC name of any format, which always start with two backslash characters ("\\"). For more information, see the next section.
A disk designator with a backslash, for example "C:\" or "d:\".
A single backslash, for example, "\directory" or "\file.txt". This is also referred to as an absolute path.
https://msdn.microsoft.com/en-nz/library/windows/desktop/aa365247(v=vs.85).aspx#fully_qualified_vs._relative_paths
Based on the MSDN Documentation, this is expected behavior.
If path2 does not include a root (for example, if path2 does not start
with a separator character or a drive specification), the result is a
concatenation of the two paths, with an intervening separator
character. If path2 includes a root, path2 is returned.
Seperator characters are discussed in this MSDN article.
So let's take a look at your test cases:
var test1 = Path.GetFullPath(Path.Combine(#"C:\users\dev\desktop\testfiles\", #".\test1.txt"));
var test2 = Path.GetFullPath(Path.Combine(#"C:\users\dev\desktop\testfiles\", #"\test2.txt"));
Test1 is behaving correctly because it is taking the . as part of a valid file path and using it in combination with the first parameter to generate the combined path.
Test2 is behaving as expected because the \ is a separator character, so as described it is returned without the first parameter.
There is no functions that you like to use in .Net framework - trimming path or ensuring that relative path starts with ".\" your real options (probably library that does it exists somewhere).
Why code does not behave the way you like (not "wrong", just not meeting your unexpected expectations).
Combine need to decide which part of left path will stay and which will be replaced. It uses regular file system conventions to decide that (".", "..", "\" have special meaning for file paths)
Meaning of path starting with:
#"\" or"/" - starting from the root of current device - this covers most cases that you don't like
#".\" - means from current directory (hence after combining and normalizing it will behave exactly as you want)
`#"..\" (possible multiple "go up") - go up one folder - this is another case you'll likely disagree with.
any character that is not '/' or #'\' - file name or path from current folder
Also note that path ending on anything but "/" or #"\" is treated by Path.Combine as file path and when combined with other path it will lose last segment.
I have a folder, full of 38,000+ .pdf files. I was not the genius to put them all into one folder, but I now have the task of separating them. The files that are of value to us, all have the same basic naming convention, for example:
123456_20130604_NEST_IV
456789_20120209_VERT_IT
What I'm trying to do, if possible, is search the folder for only those files with that particular naming convention. As in, search only for files that have 6 digits, an underscore, and then 8 digits followed by another underscore. Kind of like *****_********. I've searched online but I haven't had much luck. Any help would be great!
var regex = new Regex(#"^\d{6}_\d{8}_", RegexOptions.Compiled);
string[] files = Directory.GetFiles(folderPath)
.Where(path => regex.Match(Path.GetFileName(path)).Success)
.ToArray();
files would contain paths to a files, that match criteria.
For my example C:\Temp\123456_20130604_NEST_IV 456789_20120209_VERT_IT.pdf, which I've added beforehand.
As a bonus, here is PowerShell script to do this (assuming you are in the correct folder, otherwise use gc "C:\temp" instead of dir):
dir | Where-Object {$_ -match "^\d{6}_\d{8}_"}
? - single character
* - multiple characters
So, I would say use ?????? _ ???????? _ ???? _ ??.* to get all your files
You can use move or copy command from a command prompt to do that.
If you want to do advanced searches such as pattern matching, use windows grep: http://www.wingrep.com/
Are you familiar with regular expressions? If not, they are a generalized way to search for strings of a special format. I see you tagged your question with C# so assuming you are writing a C# script you might try the .NET regular expression module.
http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regex.aspx
If you are a beginner, you may want to start here.
http://www.codeproject.com/Articles/9099/The-30-Minute-Regex-Tutorial
There are numerous ways to handle this. What I like to do is to divide work into different steps with clear output/data in each step. Hence I would tackle this in the following way (since this seems easier for me instead of writing a master program in c# that does everything):
Open windows command prompt (start/run/cmd), navigate to correct
folder and then "dir *.pdf > pdf_files.txt". This would give you a
file containing all pdf-files inside the specific folder.
open up the txt-file (pdf_files.txt) in Notepad++ and then press "ctrl + f
(find)" activate radio button "regular expressions"
type: [0-9]{6}_[0-9]{8}_.*\.pdf and press "Find all in current document"
Copy results and save to new .txt-file
Now you have a text file containing all pdf-files that you can do what you want with (create a c# program that parses the files and move them depending on their name or whatever)
The directory 'C:\temp' has two files named 'GZ96A7005.tif' and 'GZ96A7005001.tif'. They have different length with the same extension. Now I run below code:
string[] resultFileNames = Directory.GetFiles(#"C:\temp", "????????????.tif");
The 'resultFileNames' return two items 'c:\temp\GZ96A7005.tif' and 'c:\temp\GZ96A7005001.tif'.
But the Window Search will work fine. This is why and how do I get I want?
For Directory.GetFiles, ? signifies "Exactly zero or one character." On the other hand, you could use DirectoryInfo.GetFiles, for which ? signifies "Exactly one character" (apparently what you want).
EDIT:
Full code:
string[] resultFileNames = (from fileInfo in new DirectoryInfo(#"C:\temp").GetFiles("????????????.tif") select fileInfo.Name).ToArray();
You can probably skip the ToArray and just let resultFileNames be an IEnumerable<string>.
People are reporting this doesn't work for them on MS .NET. The below exact code works for me with on Mono on Ubuntu Hardy. I agree it doesn't really make sense to have two related classes use different conventions. However, that is what the documentation (linked above) says, and Mono complies with the docs. If Microsoft's implementation doesn't, they have a bug:
using System;
using System.IO;
using System.Linq;
public class GetFiles
{
public static void Main()
{
string[] resultFileNames = (from fileInfo in new DirectoryInfo(#".").GetFiles("????????????.tif") select fileInfo.Name).ToArray();
foreach(string fileName in resultFileNames)
{
Console.WriteLine(fileName);
}
}
}
I know I've read about this somewhere before, but the best I could find right now was this reference to it in Raymond Chen's blog post. The point is that Windows keeps a short (8.3) filename for every file with a long filename, for backward compatibility, and filename wildcards are matched against both the long and short filenames. You can see these short filenames by opening a command prompt and running "dir /x". Normally, getting a list of files which match ????????.tif (8) returns a list of file with 8 or less characters in their filename and a .tif extension. But every file with a long filename also has a short filename with 8.3 characters, so they all match this filter.
In your case both GZ96A7005.tif and GZ96A7005001.tif are long filenames, so they both have a 8.3 short filename which matches ????????.tif (anything with 8 or more ?'s).
UPDATE... from MSDN:
Because this method checks against
file names with both the 8.3 file name
format and the long file name format,
a search pattern similar to "*1*.txt"
may return unexpected file names. For
example, using a search pattern of
"*1*.txt" returns "longfilename.txt"
because the equivalent 8.3 file name
format is "LONGFI~1.TXT".
UPDATE: The MSDN docs specifiy different behavior for the "?" wildcard in Directory.GetFiles() and DirectoryInfo.GetFiles(). The documentation seems to be wrong, however. See Matthew Flaschen's answer.
The ? character matches "zero or one" characters... so from what you have I would imagine that your search pattern will match any file ending in ".tif" that is between zero and twelve characters long.
Try dropping another file in that is only three characters long with a ".tif" extension and see if the code picks that up as well. I have a sneaking suspicion that it will ;)
As far as the Windows search is concerned, it is most definately not using the same algorithm under the hood. The ? character might have a very different meaning there than it does in the .Net search pattern specification for the Directory.GetFiles(string, string) method.
string path = "C:/";
var files = Directory.GetFiles(path)
.Where(f => f.Replace(path, "").Length == 8);
A little costly with the string replacement. You can add whatever extension you need.