how to get specific file names using c# - c#

I have 10 zip files in a folder having path like this
TargetDirectory = "C:\docs\folder\"
some of the zip files names are like this
abc-19870908.Zip
abc-19870908.zip
abc-12345678.zip
and some are like this...
doc.zip
doc123.zip
..
I am getting all file names by using following code...
string [] fileEntries = Directory.GetFiles(targetDirectory);
foreach(string fileName in fileEntries)
{
// here I need to compare ,
// I mean I want to get only these files which are having
// these type of filenames `abc-19870908.Zip`
if (filename == "")
{
// I want to do something
}
}
What i have to put in the double quotes in this line if(filename == "") to get like abc-19870908.Zip these filenames.
Would any one please suggest any idea about this?
Many thanks...

If you're only interested in zip files containing a dash, you can provide a search pattern to Directory.GetFiles.
string [] fileEntries = Directory.GetFiles(targetDirectory, "*-*.zip");
Check out this link for more information on those search patterns: http://msdn.microsoft.com/en-us/library/wz42302f.aspx

I guess you can do
if (filename.Contains("-"))
{
...
}
if the - is always present in the filenames you are interested in
or
if (filename.StartsWith("abc-"))
{
...
}
if the filenames always start with abc- for the ones you are interested in.

you can do if(filename.StartsWith ("abc-") ) or you can do if (filename.Contains ( "-" ) ) or you can do string [] fileEntries = Directory.GetFiles(targetDirectory, "abc-*.Zip");

// Consider using this overload:
// public static string[] GetFiles( string path, string searchPattern)
string [] fileEntries = Directory.GetFiles(targetDirectory, "abc*.zip");
Alternatively, you can use a regular expression as follows:
string [] fileEntries = Directory.GetFiles(targetDirectory);
foreach(string fileName in fileEntries)
{
if(Regex.Match (filename, #"abc.*?\.zip", RegexOptions.IgnoreCase))
{
// i want to do something
}
}

List<String> files = Directory.GetFiles(#"C:\docs\folder\").ToList();
var g = from String s in files where s.StartsWith("abc") select s;
foreach(var z in g)
{
//Do stuff in here as a replacement for your if
}

You could use a regular expression that matches your filenames, something along thees lines:
string sPattern = "abc-\d+\.zip";
string [] fileEntries = Directory.GetFiles(targetDirectory);
foreach(string fileName in fileEntries)
{
// here i need to compare , i mean i want to get only these files which are having these type of filenames `abc-19870908.Zip`
if(System.Text.RegularExpressions.Regex.IsMatch(filename , sPattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase))
{
// i want to do something
}
}
The regular expression "abc-\d+.zip" means
the string "abc-" followed by any number of digits, followed by a . followed by the string "zip" (regular expression syntax)

Related

How to create a folder out of the first few letters of a filename?

So I checked out the basic things but I'd like to do the following:
I have 5 files let's say: X1_word_date.pdf, XX1_word_date.pdf, etc...
I'd like to create a folder structure like: C:\PATH\X1, C:\PATH\XX1, etc...
So how do I take the first letters before the '_' in the file names and put it into a string?
My idea is that I use the Directory.CreateDirectory and than combine the main path and the strings so I get the folders.
How do I do that? Help appreciated.
string fileName = "X1_word_date.pdf";
string[] tokens = fileName.Split('_');
string myPath = "C:\\PATH\\";
Directory.CreateDirectory( myPath + tokens[0]);
Something like this should work. Using Split() will also allow for numbers greater than 9 to be dealt with
Supposed that your files is a List<string> which contains the file name (X2_word_date.pdf,...)
files.ForEach(f => {
var pathName= f.Split('_').FirstOrDefault();
if(!string.IsNullOrEmpty(pathName))
{
var directoryInfo = DirectoryInfo(Path.Combine(#"C:\PATH", pathName));
if(!directoryInfo.Exists)
directoryInfo.Create();
//Then move this current file to the directory created, by FileInfo and Move method
}
})
With simple string methods like Split and the System.IO.Path class:
var filesAndFolders = files
.Select(fn => new
{
File = fn,
Dir = Path.Combine(#"C:\PATH", Path.GetFileNameWithoutExtension(fn).Split('_')[0].Trim())
});
If you want to create that folder and add the file:
foreach (var x in filesAndFolders)
{
Directory.CreateDirectory(x.Dir); // will only create it if it doesn't exist yet
string newFileName = Path.Combine(x.Dir, x.File);
// we don't know the old path of the file so i can't show how to move
}
Or using regex
string mainPath = #"C:\PATH";
string[] filenames = new string[] { "X1_word_date.pdf", "X2_word_date.pdf" };
foreach (string filename in filenames)
{
Match foldernameMatch = Regex.Match(filename, "^[^_]+");
if (foldernameMatch.Success)
Directory.CreateDirectory(Path.Combine(mainPath, foldernameMatch.Value));
}
Using the bigger picture starting with only your Source and Destination directory.
We can list all files we need to move with Directory.GetFiles.
In this list We first isolate the filename with GetFileName.
Using simple String.Split you have the new directory name.
Directory.CreateDirectory will create directories unless they already exist.
To move the file we need its destination path, a combinaison of the Destination directory path and the fileName.
string sourceDirectory = #"";
string destDirectory = #"";
string[] filesToMove = Directory.GetFiles(sourceDirectory);
foreach (var filePath in filesToMove) {
var fileName = Path.GetFileName(filePath);
var dirPath = Path.Combine(destDirectory, fileName.Split('_')[0]);
var fileNewPath= Path.Combine(dirPath,fileName);
Directory.CreateDirectory(dirPath);// If it exist it does nothing.
File.Move(filePath, fileNewPath);
}

Get files from specifically structured sub-folders?

How do I get *.xml files from a specifically structured folder/sub-folder system in array to perform some operation.
Eg: The sample structure of the parent folders in user provided path (say, myPath) is
2017-36459-20124-301236\2017\36459\20124\301236\301236.xml
I cannot use things like string[] tarDir = Directory.GetDirectories(myPath, "foldernameinitial"); as the folder name is changeable.
Does anyone have any idea how to solve this issue?
As I gathered clarification from your comments, this will get you all the sub-directories with only files in them ie., the last sub-directory
static IEnumerable<string> GetLastDirectory(string path) =>
Directory.GetDirectories(path, "*", SearchOption.AllDirectories)
.Where(dir => Directory.GetDirectories(dir).Length == 0);
Now use it as:
var MyDirectories = GetLastDirectory(#"D:\Softwares\Xtras"); //your path goes here
foreach (var subdir in MyDirectories)
{
var onlyXMLfiles = Directory.GetFiles(subdir, "*.xml");
foreach (var file in onlyXMLfiles)
{
//do your operation
}
}
To be frank I don't know regex, I tried this pattern match at regex101. But as you said in the comments below you want to match the pattern of directory structure also, you can do this:
string pattern = #"\d{4}-\d{4,10}-\d{4,10}-\d{4,10}\\\d{4}\\\d{4,10}\\\d{4,10}\\\d{4,10}";
//Now you won't have to use "GetLastDirectory", instead use "Directory.GetDirectories"
var MyDirectories = Directory.GetDirectories("your path goes here");
foreach (var subdir in MyDirectories)
{
if ((Regex.Match(subdir, pattern) != Match.Empty))
{
var onlyXMLfiles = Directory.GetFiles(subdir, "*.xml");
foreach (var file in onlyXMLfiles)
{
//do your operations
}
}
}
Probable pattern explanation:
\ : match keyword, maybe!?<br>
- : hyphen as mentioned in the folder structure<br>
\d : match digits only<br>
\d{4} : match digits of length 4 and above<br>
\d{4,10} : match digits of length 4 and limit upto upto 10<br>
\\ : match \ as in the folder path<br>
var job_folders = Directory.EnumerateDirectories(textBox1.Text, "*", SearchOption.TopDirectoryOnly);
if (job_folders.ToArray().Length == 0)
{
MessageBox.Show("NO job folders are found...");
}
else
{
foreach (string job_folder in job_folders)
{
var target_xml_file = Directory.GetFiles(job_folder, "*.xml", SearchOption.AllDirectories).Where(x => Path.GetFileName(Path.GetDirectoryName(x)).ToLower() == "xml");
var target_meta_file = Directory.GetFiles(job_folder, "*.xml", SearchOption.AllDirectories).Where(x => Path.GetFileName(Path.GetDirectoryName(x)).ToLower() == "meta");
}
}

How do I remove middle characters in a file name for each file in a directory

How do I remove characters in the middle of each file name in a directory?
My directory is filled with files like: "Example01.1234312232.txt", "Example02.2348234324.txt", etc.
I would like to remove the ".1234312232" so it will named "Example01.txt", and do this for every file in the directory.
Each file name will always have the same number of characters in it.
You could use
string fileNameOnly = Path.GetFileNameWithoutExtension(path);
string newFileName = string.Format("{0}{1}",
fileNameOnly.Split('.')[0],
Path.GetExtension(path));
Demo
For what it's worth, the complete code for your directory-renaming problem:
foreach (string file in Directory.GetFiles(folder))
{
string fileNameOnly = Path.GetFileNameWithoutExtension(file);
string newFileName = string.Format("{0}{1}",
fileNameOnly.Split('.')[0],
Path.GetExtension(file));
File.Move(file, Path.Combine(folder, newFileName));
}
The simplest way would be to use a regular expression replacement of
\.\d+
for an empty string "":
var str = "Example01.1234312232.txt";
var res = Regex.Replace(str, #"\.\d+", "");
Console.WriteLine("'{0}'", res);
Here is a link to a demo on ideone.
You'll have to use the IO.DirectoryInfo class and the GetFiles function to get the list of files.
Loop all files and do a substring to get the string you want.
Then you call My.Computer.Filesystem.RenameFile to rename the files.
Use this:
filename.Replace(filename.Substring(9, 15), ".txt")
You can hard code the index and length because you said the number of characters have same length.
Use Directory.EnumerateFiles to enumerate the files, Regex.Replace to get the new name and File.Move to rename files:
using System.IO;
using System.Text.RegularExpressions;
class SampleSolution
{
public static void Main()
{
var path = #"C:\YourDirectory";
foreach (string fileName in Directory.EnumerateFiles(path))
{
string changedName = Regex.Replace(fileName, #"\.\d+", string.Empty);
if (fileName != changedName)
{
File.Move(fileName, changedName);
}
}
}
}

In C# how can I prepare a string to be valid for windows directory name

I am writing a C# program which reads certain tags from files and based on tag values it creates a directory structure.
Now there could be anything in those tags,
If the tag name is not suitable for a directory name I have to prepare it to make it suitable by replacing those characters with anything suitable. So that directory creation does not fail.
I was using following code but I realised this is not enough..
path = path.replace("/","-");
path = path.replace("\\","-");
please advise what's the best way to do it..
thanks,
Import System.IO namespace and for path use
Path.GetInvalidPathChars
and for filename use
Path.GetInvalidFileNameChars
For Eg
string filename = "salmnas dlajhdla kjha;dmas'lkasn";
foreach (char c in Path.GetInvalidFileNameChars())
filename = filename.Replace(System.Char.ToString(c), "");
foreach (char c in Path.GetInvalidPathChars())
filename = filename.Replace(System.Char.ToString(c), "");
Then u can use Path.Combine to add tags to create a path
string mypath = Path.Combine(#"C:\", "First_Tag", "Second_Tag");
//return C:\First_Tag\Second_Tag
You can use the full list of invalid characters here to handle the replacement as desired. These are available directly via the Path.GetInvalidFileNameChars and Path.GetInvalidPathChars methods.
The characters you must now use are: ? < > | : \ / * "
string PathFix(string path)
{
List<string> _forbiddenChars = new List<string>();
_forbiddenChars.Add("?");
_forbiddenChars.Add("<");
_forbiddenChars.Add(">");
_forbiddenChars.Add(":");
_forbiddenChars.Add("|");
_forbiddenChars.Add("\\");
_forbiddenChars.Add("/");
_forbiddenChars.Add("*");
_forbiddenChars.Add("\"");
for (int i = 0; i < _forbiddenChars.Count; i++)
{
path = path.Replace(_forbiddenChars[i], "");
}
return path;
}
Tip: You can't include double-quote ("), but you can include 2 quotes ('').
In this case:
string PathFix(string path)
{
List<string> _forbiddenChars = new List<string>();
_forbiddenChars.Add("?");
_forbiddenChars.Add("<");
_forbiddenChars.Add(">");
_forbiddenChars.Add(":");
_forbiddenChars.Add("|");
_forbiddenChars.Add("\\");
_forbiddenChars.Add("/");
_forbiddenChars.Add("*");
//_forbiddenChars.Add("\""); Do not delete the double-quote character, so we could replace it with 2 quotes (before the return).
for (int i = 0; i < _forbiddenChars.Count; i++)
{
path = path.Replace(_forbiddenChars[i], "");
}
path = path.Replace("\"", "''"); //Replacement here
return path;
}
You'll of course use only one of those (or combine them to one function with a bool parameter for replacing the quote, if needed)
The correct answer of Nikhil Agrawal has some syntax errors.
Just for the reference, here is a compiling version:
public static string MakeValidFolderNameSimple(string folderName)
{
if (string.IsNullOrEmpty(folderName)) return folderName;
foreach (var c in System.IO.Path.GetInvalidFileNameChars())
folderName = folderName.Replace(c.ToString(), string.Empty);
foreach (var c in System.IO.Path.GetInvalidPathChars())
folderName = folderName.Replace(c.ToString(), string.Empty);
return folderName;
}

Recursively looping through a drive and replacing illegal characters

I have to create an app that drills into a specific drive, reads all file names and replaces illegal SharePoint characters with underscores.
The illegal characters I am referring to are: ~ # % & * {} / \ | : <> ? - ""
Can someone provide either a link to code or code itself on how to do this? I am VERY new to C# and need all the help i can possibly get. I have researched code on recursively drilling through a drive but i am not sure how to put the character replace and the recursive looping together. Please help!
The advice for removing illegal characters is here:
How to remove illegal characters from path and filenames?
You just have to change the character set to your set of characters that you want to remove.
If you have figured out how to recurse the folders, you can get all of the files in each folder with:
var files = System.IO.Directory.EnumerateFiles(currentPath);
and then
foreach (string file in files)
{
System.IO.File.Move(file, ConvertFileName(file));
}
The ConvertFileName method you will write to accept a filename as a string, and return a filename stripped of the bad characters.
Note that, if you are using .NET 3.5, GetFiles() works too. According to MSDN:
The EnumerateFiles and GetFiles
methods differ as follows: When you
use EnumerateFiles, you can start
enumerating the collection of names
before the whole collection is
returned; when you use GetFiles, you
must wait for the whole array of names
to be returned before you can access
the array. Therefore, when you are
working with many files and
directories, EnumerateFiles can be
more efficient.
How to recursively list directories
string path = #"c:\dev";
string searchPattern = "*.*";
string[] dirNameArray = Directory.GetDirectories(path, searchPattern, SearchOption.AllDirectories);
// Or, for better performance:
// (but breaks if you don't have access to a sub directory; see 2nd link below)
IEnumerable<string> dirNameEnumeration = Directory.EnumerateDirectories(path, searchPattern, SearchOption.AllDirectories);
How to: Enumerate Directories and Files
How to recursively list all the files in a directory in C#?
Not really an answer, but consider both of the following:
The following characters are not valid in filenames anyways so you don't have to worry about them: /\:*?"<>|.
Make sure your algorithm handles duplicate names appropriately. For example, My~Project.doc and My#Project.doc would both be renamed to My_Project.doc.
A recursive method to rename files in folders is what you want. Just pass it the root folder and it will call itself for all subfolders found.
private void SharePointSanitize(string _folder)
{
// Process files in the directory
string [] files = Directory.GetFiles(_folder);
foreach(string fileName in files)
{
File.Move(fileName, SharePointRename(fileName));
}
string[] folders = Directory.GetDirectories(_folder);
foreach(string folderName in folders)
{
SharePointSanitize(folderName);
}
}
private string SharePointRename(string _name)
{
string newName = _name;
newName = newName.Replace('~', '');
newName = newName.Replace('#', '');
newName = newName.Replace('%', '');
newName = newName.Replace('&', '');
newName = newName.Replace('*', '');
newName = newName.Replace('{', '');
newName = newName.Replace('}', '');
// .. and so on
return newName;
}
Notes:
You can replace the '' in the SharePointRename() method to whatever character you want to replace with, such as an underscore.
This does not check if two files have similar names like thing~ and thing%
class Program
{
private static Regex _pattern = new Regex("[~#%&*{}/\\|:<>?\"-]+");
static void Main(string[] args)
{
DirectoryInfo di = new DirectoryInfo("C:\\");
RecursivelyRenameFilesIn(di);
}
public static void RecursivelyRenameFilesIn(DirectoryInfo root)
{
foreach (FileInfo fi in root.GetFiles())
if (_pattern.IsMatch(fi.Name))
fi.MoveTo(string.Format("{0}\\{1}", fi.Directory.FullName, Regex.Replace(fi.Name, _pattern.ToString(), "_")));
foreach (DirectoryInfo di in root.GetDirectories())
RecursivelyRenameFilesIn(di);
}
}
Though this will not handle duplicates names as Steven pointed out.

Categories

Resources