I am trying Mono on a linux ubuntu.
Enumartion of Files wont work with subdirectories. If i use GetFiles() it will work.
I used a console to get the output of the files so I wont get the enumerat output:
[Test]
public void NotImportentTest ()
{
Directory.CreateDirectory("test");
Directory.CreateDirectory("test/dings");
File.Create("test/dings/hallo").Close();
var curdir = Directory.GetCurrentDirectory();
var searchdir = new DirectoryInfo(curdir + "/test");
var files = searchdir.EnumerateFiles("*",SearchOption.AllDirectories);
foreach (var file in files)
{
Console.WriteLine("Enumerate:{0} in {1}\r\n", file, curdir);
}
foreach (var file in searchdir.GetFiles("*",SearchOption.AllDirectories))
{
Console.WriteLine("GetFiles:{0} in {1}\r\n", file, curdir);
}
}
Related
My folder structure is as .. temp\2016\09\11\16
In the last folder I have multiple text/json files.
I would like to run a console application that would loop through every folder and rename the files with foldernames concatenated.
So a file abcd.json would become 2016091116_abcd.json
Then copy this file to another folder.
I tried..
using System;
using System.IO;
using System.Collections;
namespace concatdf
{
class Program
{
static void Main(string[] args)
{
string folderPath = "D:\\500GBNP\\Projects\\temp";
DirectoryInfo startDir = new DirectoryInfo(folderPath);
RecurseFileStructure recurseFileStructure = new RecurseFileStructure();
recurseFileStructure.TraverseDirectory(startDir);
}
public class RecurseFileStructure
{
public void TraverseDirectory(DirectoryInfo directoryInfo)
{
var subdirectories = directoryInfo.EnumerateDirectories();
foreach (var subdirectory in subdirectories)
{
TraverseDirectory(subdirectory);
}
var files = directoryInfo.EnumerateFiles();
foreach (var file in files)
{
HandleFile(file);
}
}
void HandleFile(FileInfo file)
{
string destfolderPath = "D:\\500GBNP\\Projects\\temp1\\";
file.CopyTo(destfolderPath+file.Name);
}
}
}
}
With the above code I'm able to traverse and copy all files to target directory but file names do not get concatenated with foldernames.
So a file abcd.json in folder temp\2016\09\11\16 would become 2016091116_abcd.json and all files get copied to temp1 folder.
I would sincerely appreciate if someone could help.
You can append the folder name in each recursion and append the destination filename.
using System;
using System.IO;
using System.Collections;
namespace concatdf
{
class Program
{
static void Main(string[] args)
{
string folderPath = "D:\\500GBNP\\Projects\\temp";
DirectoryInfo startDir = new DirectoryInfo(folderPath);
RecurseFileStructure recurseFileStructure = new RecurseFileStructure();
recurseFileStructure.TraverseDirectory(startDir, string.Empty);
}
public class RecurseFileStructure
{
public void TraverseDirectory(DirectoryInfo directoryInfo, string fileAppend)
{
var subdirectories = directoryInfo.EnumerateDirectories();
foreach (var subdirectory in subdirectories)
{
TraverseDirectory(subdirectory, fileAppend + subdirectory.Name);
}
var files = directoryInfo.EnumerateFiles();
foreach (var file in files)
{
HandleFile(file, fileAppend);
}
}
void HandleFile(FileInfo file, string fileAppend)
{
string destfolderPath = "D:\\500GBNP\\Projects\\temp1\\";
file.CopyTo(destfolderPath + fileAppend +"_"+ file.Name);
}
}
}
}
We just need to make HandleFile a bit more intelligent. Let's take the last 4 folder names and add it to the name..
void HandleFile(FileInfo file)
{
string destfolderPath = "D:\\500GBNP\\Projects\\temp1\\";
var pathBits = file.DirectoryName.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
var s = string.Concat(pathBits[^4..]);
file.CopyTo(Path.Combine(destfolderPath, s+'_'+file.Name));
}
This renames the file as it copies (which seemed a more sensible way to go, to me). If you truly want to rename the file before you copy, insert a call to FileInfo.MoveTo() after you copy
Strive to use Path when working with paths, not string concatenation
What about something simpler like this?:
public static void CopyFiles(DirectoryInfo sourceDirectory, DirectoryInfo targetDirectory)
{
// This will provide all files in sourceDirectory and nested directories
foreach (var file in sourceDirectory.EnumerateFiles("*", SearchOption.AllDirectories))
{
// work out what the relative path from sourceDirectory is
// e.g. 2016\09\11\16\abcd.json
string relativePath = Path.GetRelativePath(sourceDirectory.FullName, file.FullName);
// get the directory part and replace the separator with an empty string (this could be
// made more efficient)
string directoryPart = Path.GetDirectoryName(relativePath)
.Replace(Path.DirectorySeparatorChar.ToString(), string.Empty);
// get just the filename
string filePart = Path.GetFileName(relativePath);
// combine the target directory, the directory part, and the filename part
// I've made the assumption that you don't want files in the base directory
// to be called _filename, so we just use filePart when there is no directoryPart
string newFileName = string.IsNullOrEmpty(directoryPart) ? filePart : $"{directoryPart}_{filePart}";
string newFullName = Path.Combine(targetDirectory.FullName, newFileName);
// copy the file to the new location
file.CopyTo(newFullName);
}
}
I would like to run all the .exe files in a certain directory from my winform application.
Is there a way not to hard code the file path of each exe and be not dependent on knowing beforehand how many exe I have to run?
DirectoryInfo d = new DirectoryInfo(filepath);
foreach (var file in d.GetFiles("*.exe"))
{
Process.Start(file.FullName);
}
You can get all executable files using:
static public List<string> GetAllExecutables(string path)
{
return Directory.Exists(path)
? Directory.GetFiles(path, "*.exe").ToList()
: return new List<string>(); // or null
}
You can run one with:
static public Process RunShell(string filePath, string arguments = "")
{
try
{
var process = new Process();
process.StartInfo.FileName = filePath;
process.StartInfo.Arguments = arguments;
process.Start();
return process;
}
catch ( Exception ex )
{
Console.WriteLine($"Can''t run: {filePath}{Environment.NewLine}{Environment.NewLine}" +
ex.Message);
return null;
}
}
Thus you can write:
foreach ( string item in GetAllExecutables(#"c:\MyPath") )
RunShell(item);
//get exe files included in the directory
var files = Directory.GetFiles("<target-directory>", "*.exe");
Console.WriteLine("Number of exe:" + files.Count());
foreach (var file in files)
{
// start each process
Process.Start(file);
}
I have Bluray folder structure
- BMDV
- ANY!
- FAB!
...
I use library https://github.com/DiscUtils/DiscUtils and I tried:
CDBuilder builder = new CDBuilder();
builder.UseJoliet = false;
AddDir("paths", builder, "paths");
builder.Build("stuff.iso");
static void AddDir(string dirPath, CDBuilder builder, string originalPath)
{
var files = Directory.GetFiles(dirPath);
var dirs = Directory.GetDirectories(dirPath);
var pathDiff = string.Join(separator, dirPath.Split(separator).Except(originalPath.Split(separator)));
if (!string.IsNullOrWhiteSpace(pathDiff))
{
Console.WriteLine($"Adding directory {pathDiff}");
builder.AddDirectory(pathDiff);
}
foreach (var file in files)
{
string location = string.IsNullOrWhiteSpace(pathDiff) ?
Path.GetFileName(file) :
$"{pathDiff}{separator}{Path.GetFileName(file)}";
Console.WriteLine($"Adding file: {location}");
builder.AddFile(location, file);
}
foreach (var dir in dirs)
{
AddDir(dir, builder, originalPath);
}
}
When open ISO with BDInfo (https://www.videohelp.com/software/BDInfo), it says that is not valid UDF stream.
How to create UDF ISO file ?
I want to compress Zip to be same structure with folder.
but, ZipFile API seems unable to compress folder.
How to compress these folder structure?
The following code can't compress folder itself.
using (ZipArchive archive = ZipFile.Open(Path.Combine(m_strWorkingDirectory, "build.zip"), ZipArchiveMode.Create))
{
foreach( string path in m_listTargetPath )
{
string strPath = Path.Combine(m_strWorkingDirectory, path);
archive.CreateEntryFromFile(strPath, path);
}
}
If ZipFile.CreateFromDirectory() doesn't do what you need (I thought it would) then you can just get all the files/folders you need and add them in using an extension method:
public static class FileExtensions
{
public static IEnumerable<FileSystemInfo> AllFilesAndFolders(this DirectoryInfo dir)
{
foreach (var f in dir.GetFiles())
{
yield return f;
}
foreach (var d in dir.GetDirectories())
{
yield return d;
foreach (var o in AllFilesAndFolders(d))
{
yield return o;
}
}
}
}
And then using your same format, you should be able to do something like so (not tested):
DirectoryInfo dir = new DirectoryInfo(m_strWorkingDirectory);
using (ZipArchive archive = ZipFile.Open(Path.Combine(m_strWorkingDirectory, "build.zip"), ZipArchiveMode.Create))
{
foreach (FileInfo file in dir.AllFilesAndFolders().Where(o => o is FileInfo).Cast<FileInfo>())
{
var relPath = file.FullName.Substring(dir.FullName.Length + 1);
archive.CreateEntryFromFile(file.FullName, relPath);
}
}
var path = Environment.GetFolderPath(Environment.SpecialFolder.InternetCache);
var dInfo = new DirectoryInfo(path);
foreach (FileInfo f in dInfo.GetFiles())
{
Console.WriteLine(f.ToString());
}
This only prints out one file titled "desktop.ini". I know that Temporary Internet Files is a virtual folder. How can I iterate through files in a virtual folder?
What your accessing with your code is the top level folder. To iterate through all the files you will need to take into account all the sub folders in the Temporary Internet Files.
static void Main(string[] args)
{
var path = Environment.GetFolderPath(Environment.SpecialFolder.InternetCache);
var dInfo = new DirectoryInfo(path);
DoStuff(dInfo);
Console.ReadLine();
}
static void DoStuff(DirectoryInfo directory)
{
foreach (var file in directory.GetFiles())
{
Console.WriteLine(file.FullName);
}
foreach (var subDirectory in directory.GetDirectories())
{
DoStuff(subDirectory);
}
}