i have a path dir called serverpath which is configurable.
eg.
serverpath=#"C:\AAA\New folder\";
in server path there are large number of directories. in following format:
serverpath\ID1\ID2\FileType\YYYY\MM\DD.MM.YYYY
i.e. C:\AAA\New folder\123\456\2017\01\01.01.2017
when i call
Directory.EnumerateDirectories(serverpath, "*", System.IO.SearchOption.AllDirectories)
i get all the directories but i want only those path which are in the given format.
so far i have tries adding "??.??.????" pattern in the EnumerateDirectories method
Directory.EnumerateDirectories(serverpath, "??.??.????", System.IO.SearchOption.AllDirectories)
but still i am getting path which are like this:
C:\AAA\New folder\123\456\pdf\2017\01
C:\AAA\New folder\123\456\txt\2017\01
i only want path like these:
C:\AAA\New folder\123\456\pdf\2017\01\01.01.2017
C:\AAA\New folder\123\456\txt\2017\01\01.01.2017
and exclude all the other paths in the directory
any other way to do this other than counting slashes..?
Edit: is there any way to get directory path of the last folder in the directory? "01.01.2017" folders are the last folders in their respective directories.
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
namespace ConsoleApp
{
class Program
{
static void Main()
{
string serverpath = #"C:\AAA\New folder\";
Regex re = new Regex(#"\d{2}\.\d{2}\.\d{4}");
var dirs = from dir in
Directory.EnumerateDirectories(serverpath, "*", SearchOption.AllDirectories)
where re.IsMatch(dir)
select dir;
}
}
}
This seems to work. Sorry if I have misunderstood - I am new to this.
\d = digit
{} = quantifier (of what is left of the quantifier)
. = any character (NOT OF ANY USE HERE)
\. = explicit dot
Related
I have an array of filepaths in a directory and I'm trying to move certain files based on alphabet.
string[] filePaths = Directory.GetFiles(#"C:\user\desktop\folder", "*.txt");
foreach (var file in filePaths)
{
if (file.StartsWith("A"))
{
//Move file
The obvious problem is that file.StartWith is pulling the entire filepath (C:\user\desktop\folder\Albert.txt) Which doesn't start with 'A'
So what would be the best way to just target the start of the actual file?
Thanks in advance.
I got it working with Path.GetFileName as per the suggestion by #Jimi
What about this code
var dir = new DirectoryInfo(#"C:\user\desktop\folder");
var files = dir.GetFiles();
foreach (var file in files)
{
if(file.Name.StartsWith("A"))
{
//Move file
You say you're looking to move files by alphabet- if you mean to put files into a folder whose name is the same as the first char of the filename then perhaps:
var desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); //don't hard code the path to the desktop
var root = Path.Combine(desktop, "foldernamehere"); //use path.combine to build paths
foreach(var f in directory.EnumerateFiles(root, "*.txt")){ //prefer EnumerateFiles over GetFiles
var filename = Path.GetFileName(f);
var dest = Path.Combine(root, filename.Remove(1));
Directory.CreateDirectory(dest); //safe to call even if exists, ensures exists
File.Move(f, Path.Combine(dest, filename));
}
See comments for more info
If you have a string that represents a full filename (or directory name), and you want the name without the directory, consider to use Path.GetFileName
string fullFileName = "C:\user\desktop\folder\Albert.txt";
string fileName = Path.GetDirectoryName(fullFileName);
fileName will be "Albert.txt"
With this in mind, your query will be easy:
IEnumerable<string> fullFileNames = ...
char startChar = 'A';
IEnumerable<string> fileNamesThatStartWithStartChar = fullFileNames
.Where(fileName => Path.GetDirectoryName(fileName).StartsWitch(startChar));
In words: from every fileName in the sequence of fullFileName, take the fileName without the directory information. Keep the fileName if this "fileName without directory information" starts with the startChar.
Note: StartsWitch(char) is case sensitive. If you want to check case insensitive, use String.StartsWitch(string, stringComparison)
There's room for improvement!
If you think that there might be a chance that you won't be using all information of all files, consider to use Directory.EnymerateFiles instead of GetFiles. This way, if at the end of your LINQ you decide to use only 3 of the fetched files (or worse: FirstOrDefault(), or Any()), you won't have fetched all files.
I've come across one thing.
There is code:
var searchPattern = #"??????";
var path = "C:\Users\MyUser\Folder";
IEnumerable<string> file = Directory.EnumerateFiles(path, searchPattern);
IEnumerable<string> dir = Directory.EnumerateDirectories(path, searchPattern);
and lets say following directories and files:
a.txt
b.txt
a
b
According to Documentation there "?" char should represent zero or one character in that position. Therefore I expect dir containing a and b and file should be a.txt and b.txt.
However my file variable contains only empty collection.
Why is that?
I have two lists containing paths to a directory of music files and I want to determine which of these files are stored on both lists and which are only stored on one. The problem lies in that the format of the paths differ between the two lists.
Format example:
List1: file://localhost//FILE/Musik/30%20Seconds%20To%20Mars.mp3
List2: \\FILE\Musik\30 Seconds To Mars.mp3
How do I go about comparing these two file paths and matching them to the same source?
The answer depends on your notion of "same file". If you merely want to check if the file is equal, but not the very same file, you could simply generate a hash over the file's content and compare that. If the hashes are equal (please use a strong hash, like SHA-256), you can be confident that the files are also. Likewise you could of course also compare the files byte by byte.
If you really want to figure that the two files are actually the same file, i.e. just addressed via different means (like file-URL or UNC path), you have a little more work to do.
First you need to find out the true file system path for each of the addresses. For example, you need to find the file system path behind the UNC path and/or file-URL (which typically is the URL itself). In the case of UNC paths, that are shares on a remote computer, you might even be able to do so.
Also, even if you have the local path figured out somehow, you also need to deal with different redirection mechanisms for local paths (on Windows junctions/reparse points/links; on UNIX symbolic or hard links). For example, you could have a share using file system link as source, while the file URL uses the true source path. So to the casual observer they still look like different files.
Having all that said, the "algorithm" would be something like this:
Figure out the source path for the URLs, UNC paths/shares, etc. you have
Figure out the local source path from those paths (considering links/junctions, subst.exe, etc.)
Normalize those paths, if necessary (i.e. a/b/../c is actually a/c)
Compare the resulting paths.
I think the best way to do it is by temporarily converting one of the paths to the other one's format. I would suggest you change the first to match the second.
string List1 = "file://localhost//FILE/Musik/30%20Seconds%20To%20Mars.mp3"
string List2 = "\\FILE\Musik\30 Seconds To Mars.mp3"
I would recommend you use Replace()-method.
Get rid of "file://localhost":
var tempStr = List1.Replace("file://localhost", "");
Change all '%20' into spaces:
tempStr = List1.Replace("%20", " ");
Change all '/' into '\':
tempStr = List1.Replace("/", "\");
VoilĂ ! To strings in matching format!
Use python: you can easily compare the two files like this
>>> import filecmp
>>> filecmp.cmp('file1.txt', 'file1.txt')
True
>>> filecmp.cmp('file1.txt', 'file2.txt')
False
to open the files with the file:// syntax use URLLIB
>>> import urllib
>>> file1 = urllib.urlopen('file://localhost/tmp/test')
for the normal files path use the standard file open.
>>> file2 = open('/pathtofile','r')
I agree completely with Christian, you should re-think structure of the lists, but the below should get you going.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication5
{
class Program
{
public static List<string> SanitiseList(List<string> list)
{
List<string> sanitisedList = new List<string>();
foreach (string filename in list)
{
String sanitisedFilename = String.Empty;
if (!String.IsNullOrEmpty(filename))
{
sanitisedFilename = filename;
// get rid of the encoding
sanitisedFilename = Uri.UnescapeDataString(sanitisedFilename);
// first of all change all back-slahses to forward slashes
sanitisedFilename = sanitisedFilename.Replace(#"\", #"/");
// if we have two back-slashes at the beginning assume its localhsot
if (sanitisedFilename.Substring(0, 2) == "//")
{
// remove these first double slashes and stick in localhost
sanitisedFilename = sanitisedFilename.TrimStart('/');
sanitisedFilename = sanitisedFilename = "//localhost" + "/" + sanitisedFilename;
}
// remove file
sanitisedFilename = sanitisedFilename.Replace(#"file://", "//");
// remove double back-slashes
sanitisedFilename = sanitisedFilename.Replace("\\", #"\");
// remove double forward-slashes (but not the first two)
sanitisedFilename = sanitisedFilename.Substring(0,2) + sanitisedFilename.Substring(2, sanitisedFilename.Length - 2).Replace("//", #"/");
}
if (!String.IsNullOrEmpty(sanitisedFilename))
{
sanitisedList.Add(sanitisedFilename);
}
}
return sanitisedList;
}
static void Main(string[] args)
{
List<string> listA = new List<string>();
List<string> listB = new List<string>();
listA.Add("file://localhost//FILE/Musik/BritneySpears.mp3");
listA.Add("file://localhost//FILE/Musik/30%20Seconds%20To%20Mars.mp3");
listB.Add("file://localhost//FILE/Musik/120%20Seconds%20To%20Mars.mp3");
listB.Add(#"\\FILE\Musik\30 Seconds To Mars.mp3");
listB.Add(#"\\FILE\Musik\5 Seconds To Mars.mp3");
listA = SanitiseList(listA);
listB = SanitiseList(listB);
List<string> missingFromA = listB.Except(listA).ToList();
List<string> missingFromB = listA.Except(listB).ToList();
}
}
}
In C#, if I have a directory path and a relative file path with wildcard, e.g.
"c:\foo\bar" and "..\blah\*.cpp"
Is there a simple way to get the list of absolute file paths? e.g.
{ "c:\foo\blah\a.cpp", "c:\foo\blah\b.cpp" }
Background
There is a source code tree, where any directory can contain a build definition file. This file uses relative paths with wildcards to specify a list of source files. The task is to generate a list of absolute paths of all source files for each one of these build definition files.
You can get the absolute path first and then enumerate the files inside the directory matching the wildcard:
// input
string rootDir = #"c:\foo\bar";
string originalPattern = #"..\blah\*.cpp";
// Get directory and file parts of complete relative pattern
string pattern = Path.GetFileName (originalPattern);
string relDir = originalPattern.Substring ( 0, originalPattern.Length - pattern.Length );
// Get absolute path (root+relative)
string absPath = Path.GetFullPath ( Path.Combine ( rootDir ,relDir ) );
// Search files mathing the pattern
string[] files = Directory.GetFiles ( absPath, pattern, SearchOption.TopDirectoryOnly );
It's simple.
using System.IO;
.
.
.
string[] files = Directory.GetFiles(#"c:\", "*.txt", SearchOption.TopDirectoryOnly);
I have a C# app that uses the search functions to find all files in a directory, then shows them in a list. I need to be able to filter the files based on extension (possible using the search function) and directory (eg, block any in the "test" or "debug" directories from showing up).
My current code is something like:
Regex filter = new Regex(#"^docs\(?!debug\)(?'display'.*)\.(txt|rtf)");
String[] filelist = Directory.GetFiles("docs\\", "*", SearchOption.AllDirectories);
foreach ( String file in filelist )
{
Match m = filter.Match(file);
if ( m.Success )
{
listControl.Items.Add(m.Groups["display"]);
}
}
(that's somewhat simplified and consolidated, the actual regex is created from a string read from a file and I do more error checking in between.)
I need to be able to pick out a section (usually a relative path and filename) to be used as the display name, while ignoring any files with a particular foldername as a section of their path. For example, for these files, only ones with +s should match:
+ docs\info.txt
- docs\data.dat
- docs\debug\info.txt
+ docs\world\info.txt
+ docs\world\pictures.rtf
- docs\world\debug\symbols.rtf
My regex works for most of those, except I'm not sure how to make it fail on the last file. Any suggestions on how to make this work?
Try Directory.GetFiles. This should do what you want.
Example:
// Only get files that end in ".txt"
string[] dirs = Directory.GetFiles(#"c:\", "*.txt", SearchOption.AllDirectories);
Console.WriteLine("The number of files ending with .txt is {0}.", dirs.Length);
foreach (string dir in dirs)
{
Console.WriteLine(dir);
}
^docs\\(?:(?!\bdebug\\).)*\.(?:txt|rtf)$
will match a string that
starts with docs\,
does not contain debug\ anywhere (the \b anchor ensures that we match debug as an entire word), and
ends with .txt or .rtf.