I am looking to create a Method which I can use to delete files from a directory when the filename contains the wildcard parameter.
So far I have the below but I cannot seem to work out how I can delete any files from my fileEntries collection that contain the wildcard.
public static void DeleteFileContaining(string targetDirectory, string wildcard)
{
// Process the list of ALL files found in the directory.
string[] fileEntries = Directory.GetFiles(targetDirectory);
foreach (var item in fileEntries)
{
var itemToDelete = fileEntries.Contains(wildcard);
// delete where contains
}
}
Can anyone finish this or suggest a more efficient way of doing this in one neat method call which takes the directory and wildcard?
You can use the search-pattern of GetFiles/EnumerateFiles(which can be more efficient):
public static void DeleteFileContaining(string targetDirectory, string wildcard)
{
string searchPattern = string.Format("*{0}*", wildcard);
var filesToDelete = Directory.EnumerateFiles(targetDirectory, searchPattern);
foreach (var fileToDelete in filesToDelete)
{
try{
File.Delete(fileToDelete);
}catch(Exception ex){
// log this...
}
}
}
Look at the remarks section for further information.
First off, this line is wrong:
var itemToDelete = fileEntries.Contains(wildcard);
This returns a boolean indicating whether at least one of the filenames is an exact match. What you want is:
var items = fileEntries.Where(name => name.Contains(wildcard));
Second, you don't even need to filter the filenames like this, you can simply use this other GetFiles overload that takes a search pattern.
Finally, you can then use File.Delete to actually delete those files.
This is my first stab at something like this with LINQ, but this worked for me:
public static void DeleteFileContaining(string targetDirectory, string wildcard)
{
Directory.GetFiles(targetDirectory).Where(j => j.Contains(wildcard)).ToList().ForEach(i => File.Delete(i));
}
Or this uses a multiline lambda expression to include error handling:
public static void DeleteFileContaining(string targetDirectory, string wildcard)
{
Directory.GetFiles(targetDirectory).Where(j => j.Contains(wildcard)).ToList().ForEach(i =>
{
try
{
File.Delete(i);
}
catch (Exception ex)
{
//do something here on exception.
}
});
}
I would use the wildcard to get only the files that I am interested in.
public static void DeleteFileContaining(string targetDirectory, string wildcard){
string[] fileEntries = Directory.GetFiles(targetDirectory, wildcard);//something like *.jpg
// delete all matching files.
foreach (string f in fileEntries)
{
File.Delete(f);
}
}
I am not sure you want to delete from folder but as you have mentioned you want to remove from fileEntries collection you can achieve by this
fileEntries = fileEntries.Where(a => !a.Contains(wildcard)).ToArray();
You might want to look at the System.IO-Class to delete files (http://msdn.microsoft.com/en-us/library/System.IO(v=vs.110).aspx)
Related
Is it possible to get only list of Excel filenames (like : 2021070701.CSV) in a folder ?
I'm getting the full path of the .csv excel when I use this "Directory.GetFiles" but I want to filter only excel filename with extension (like : 2021070701.CSV)
I used "FileInfo fi = new FileInfo();" but I didn't get the proper solution.
public static void getExcelFileName()
{
string[] filename = Directory.GetFiles(#"C:\Users\Ashok
Kumar\OneDrive\Desktop\Ashok\MarketPrice\NSE\Futures\Live", "*.csv");
foreach (var item in filename)
{
Console.WriteLine(item);
}
}
This is the path I'm getting
Help me out form this I'm new to coding.
You can use the GetFileNameWithoutExtension() method from the Path class to get the names of your files.
public static void getExcelFileName()
{
string[] filename = Directory.GetFiles(#"C:\Users\Ashok
Kumar\OneDrive\Desktop\Ashok\MarketPrice\NSE\Futures\Live", "*.csv");
foreach (var item in filename)
{
Console.WriteLine(Path.GetFileNameWithoutExtension(item));
}
}
Sure, you can call Path.GetFileName(string) which returns exactly what you're asking for!
public static void getExcelFileName()
{
string[] filesPaths = Directory.GetFiles(#"C:\Users\Ashok Kumar\OneDrive\Desktop\Ashok\MarketPrice\NSE\Futures\Live",
"*.csv");
foreach (var filePath in filesPaths)
{
Console.WriteLine(Path.GetFileName(filePath));
}
}
I want to get from this
"../lib/../data/myFile.xml"
to this
"../data/myFile.xml"
I guess I could do it by manipulating the string, searching for "../" and canceling them out with the preceding folders but I was looking for an already existing C# solution.
Tried instantiating an Uri from this string and going back toString(). Didn't help. It leaves the string unchanged.
You can always try to use:
Path.GetFullPath("../lib/../data/myFile.xml")
It behaves as you want with absolute paths but you might end up with strange behaviors with relative paths since it always bases itself from the current working directory. For instance:
Path.GetFullPath("/lib/../data/myFile.xml") // C:\data\myFile.xml
Path.GetFullPath("../lib/../data/myFile.xml") // C:\Program Files (x86)\data\myFile.xml
Sounds like you may either need to parse/rebuild the path yourself, or use some kind of well constructed regular expression to do this for you.
Taking the parse/rebuild route, you could do something like:
public static string NormalisePath(string path)
{
var components = path.Split(new Char[] {'/'});
var retval = new Stack<string>();
foreach (var bit in components)
{
if (bit == "..")
{
if (retval.Any())
{
var popped = retval.Pop();
if (popped == "..")
{
retval.Push(popped);
retval.Push(bit);
}
}
else
{
retval.Push(bit);
}
}
else
{
retval.Push(bit);
}
}
var final = retval.ToList();
final.Reverse();
return string.Join("/", final.ToArray());
}
(and yes, you'd probably want better variable names/commenting/etc.)
You can use a regular expression to do this:
public static string NormalisePath(string path)
{
return new Regex(#"\.{2}/.*/(?=\.\.)").Replace(path, "");
}
Thanks all for the suggestion made for my earlier query regarding to the getlist and copy.
I have only one issue here
String realname= "test" //am getting this value from Db,so is this anyway i can use like that rather than
string realname="test"//i know i can do like string realname=""+Dbvalue+"";
Am just wondering why it doesn't return anyvalue if don't use "*" ?
class Program
{
static void Main(string[] args)
{
var getfiles = new fileshare.Program();
string realname = "*test*";
foreach (var file in getfiles.GetFileList(realname))
{getfiles.copytolocal(file.FullName); }
}
private FileInfo[] GetFileList(string pattern)
{
var di = new DirectoryInfo(#"\\testserv01\dev");
return di.GetFiles(pattern);
}
private void copytolocal(string filename)
{
string nameonly = Path.GetFileName(filename);
File.Copy(filename,Path.Combine(#"c:\",nameonly));
}
}
Thanks in Advance.
I know this is a bit glib but really you need to start looking at the documentation of the functionality you are using: http://msdn.microsoft.com/en-us/library/8he88b63.aspx
that said the reason is that * is a wildcard - if you use "test" then you will only retrieve exact matches for "test".
the link above has some more examples.
I have this piece of code that searches for a folder given a starting directory. Once the folder is found I need the name of it's parent. The following piece of code works but it is terribly ugly. I have a flag, "sessionFound" to assist with breaking from nested foreach loops. The following works. I was hoping I could get some eyes on this and see if I could get some suggestions on how to make this less verbose and a bit more concise.
Thanks.
private void SetProjectFolder(string sessionid)
{
//IoC container gives the root directory to begin search.
string[] supportDirs = Directory.GetDirectories(ApplicationContainer.SupportDirectory);
bool sessionFound = false;
foreach (string directory in supportDirs)
{
if (!sessionFound)
{
foreach (string folder in Directory.GetDirectories(directory))
{
if (!sessionFound)
{
foreach (string productSubFolder in Directory.GetDirectories(folder))
{
if (productSubFolder.Contains(sessionid))
{
_productName = Directory.GetParent(productSubFolder).Parent.Name;
sessionFound = true;
break;
}
}
}
else
{
break;
}
}
}
else
{
break;
}
}
}
Try this:
private void SetProjectFolder(string sessionid)
{
//This will simulate the contains statement
string searchPattern = string.Format("*{0}*", sessionid);
string[] supportDirs = Directory.GetDirectories(ApplicationContainer.SupportDirectory, searchPattern);
foreach (string filteredFolder in supportDirs)
{
_productName = Directory.GetParent(filteredFolder).Name;
break;
}
}
By removing sessionFound you end up with a pretty clear and straightforward code:
private void SetProjectFolder(string sessionid)
{
//IoC container gives the root directory to begin search.
string[] supportDirs = Directory.GetDirectories(ApplicationContainer.SupportDirectory);
// search for product subfolder
foreach (string directory in supportDirs)
{
foreach (string folder in Directory.GetDirectories(directory))
{
foreach (string productSubFolder in Directory.GetDirectories(folder))
{
if (productSubFolder.Contains(sessionid))
{
// product sub-folder found, set it and exit
_productName = Directory.GetParent(productSubFolder).Parent.Name;
return;
}
}
}
}
// product sub-folder not found
!!! handle error path
}
In case your directory structure is static in the sense of the abovementioned search algorithm, I don't think there's something wrong with the nested foreach statements. Maybe you could extract the code starting with the middle foreach into a separate method like string FindProductSubfolderInFolder(Directory).
I am trying to create a program to copy all the files from one directory to another. But I am running in a basic issue. It says indentifier expected when I try to compile on line 52.
public bool RecursiveCopy()
{
string origDir = #"D:\Documents and Settings\Dub\My Documents\HoN Updates\test";
string destDir = #"C:\Games\HoN";
bool status = false;
//get all the info about the original directory
var dirInfo = new DirectoryInfo(origDir);
//retrieve all the _fileNames in the original directory
var files = dirInfo.GetFiles(origDir);
//always use a try...catch to deal
//with any exceptions that may occur
try
{
//loop through all the file names and copy them
foreach (string file in Directory.GetFiles(origDir))
{
var origFile = new FileInfo(file);
var destFile = new FileInfo(file.Replace(origDir, destDir));
//copy the file, use the OverWrite overload to overwrite
//destination file if it exists
System.IO.File.Copy(origFile.FullName, destFile.FullName, true);
//TODO: If you dont want to remove the original
//_fileNames comment this line out
File.Delete(origFile.FullName);
status = true;
}
Console.WriteLine("All files in " + origDir + " copied successfully!");
}
catch (Exception ex)
{
status = false;
//handle any errors that may have occurred
Console.WriteLine(ex.Message);
}
return status;
}
public string origDir = #"D:\Documents and Settings\Dub\My Documents\HoN Updates\test"; // ERROR HERE
public string destDir = #"C:\Games\HoN"; // ERROR HERE
private static void RecursiveCopy(origDir, destDir)
{
Console.WriteLine("done");
Console.ReadLine();
}
You did not give type identifiers to your argument list here
static void RecursiveCopy(origDir, destDir)
should be
static void RecursiveCopy(string origDir, string destDir)
Your method RecursiveCopy has two parameters listed without their types. It should be this:
static void RecursiveCopy(string origDir, string destDir)
Here is your problem:
static void RecursiveCopy(origDir, destDir)
You don't specify the types for the parameters, perhaps you intended the following:
static void RecursiveCopy(string origDir, string destDir)
There are more issues however that I've noticed. It's possible you're still working on these, but from what you've posted:
You never call your RecursiveCopy method. Perhaps you meant to call it from Main() instead of declaring an overload with two parameters?
You declare two public fields origDir and destDir but then never use them. Instead you create two local variables in RecursiveCopy() and use these instead. Did you intend to create parameters or use the public fields instead?
Your copy is not actually true to its name of "recursive".
cYou are missing the parameter types in the RecursiveCopy method declaration. Just Change
static void RecursiveCopy(origDir, destDir)
to
static void RecursiveCopy(String origDir, String destDir)
and all is fine.