I have a unique file extension which is really just a zip. I am trying to in one event change the extension name, extract the files, then merge them all into one file.
I can move the file, change the extension but it stops there. It won't extract the files. I have tried to put a Thread.Sleep(10000) in thinking maybe it didn't see the zips because they were still copying but that didn't work either.
string path = txtField.text;
string[] originalFiles = Directory.GetFiles(path, "*.unique");
string[] newZips = Directory.GetFiles(path, "*.zip");
try
{
foreach (var item in originalFiles)
{
File.Copy(item, Path.ChangeExtension(item, ".zip"));
}
foreach (var item in newZips)
{
ZipFile.CreateFromDirectory(path, item);
Zipfile.ExtractToDirectory(item, path);
}
}
catch (exception ex)
{
MessageBox.Show(ex.Message, "Fail....");
}
The problem is that newZips gets set before you actually create the renamed zip files. You would need to move the line:
string[] newZips = Directory.GetFiles(path, "*.zip");
..so that it appears after the first foreach loop.
If your ultimate objective is only to create a new zip with the contents of the *.unique files, perhaps you can avoid renaming the files. You could do something similar to the following to extract the files to a temporary folder and create the new zip from those files:
string path = txtField.text;
string[] originalFiles = Directory.GetFiles(path, "*.unique");
try
{
var extractedFilesPath = Path.Combine(path, "ExtractedFiles");
var newZipFile = Path.Combine(path, "NewZipFile.zip");
foreach (var item in originalFiles)
{
ZipFile.ExtractToDirectory(item, extractedFilesPath);
}
ZipFile.CreateFromDirectory(extractedFilesPath, newZipFile);
Directory.Delete(extractedFilesPath, true);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Fail....");
}
Related
I am looking to read folders and files from a directory structure like so..
e.g
C:\RootFolder
SubFolder1
SubFolder2
File1
File2
SubFolder3
File3
Files....
Files....
I would like to read both, files and folders and write to another directory I cant use copy , because the directory I want to write to is remote and not local.
I read the files here.... Id love to be able to read folders and files and write both to another directory.
public static IEnumerable<FileInfo> GetFiles(string dir)
{
return Directory.EnumerateFiles(dir, "*", SearchOption.AllDirectories)
.Select(path =>
{
var stream = File.OpenRead(path);
return new FileInfo(Path.GetFileName(path), stream);
})
.DisposeEach(c => c.Content);
}
this function writes files to a remote sftp site.
public Task Write(IEnumerable<FileInfo> files)
{
return Task.Run(() =>
{
using (var sftp = new SftpClient(this.sshInfo))
{
sftp.Connect();
sftp.ChangeDirectory(this.remoteDirectory);
foreach (var file in files)
{
sftp.UploadFile(file.Content, file.RelativePath);
}
}
});
}
In this function I write the read files from the above function.
private async static Task SendBatch(Config config, Batch batch, IRemoteFileWriter writer)
{
var sendingDir = GetClientSendingDirectory(config, batch.ClientName);
Directory.CreateDirectory(Path.GetDirectoryName(sendingDir));
Directory.Move(batch.LocalDirectory, sendingDir);
Directory.CreateDirectory(batch.LocalDirectory);
//Use RemoteFileWriter...
var files = GetFiles(sendingDir);
await writer.Write(files).ContinueWith(t =>
{
if(t.IsCompleted)
{
var zipArchivePath = GetArchiveDirectory(config, batch);
ZipFile.CreateFromDirectory(
sendingDir,
zipArchivePath + " " +
DateTime.Now.ToString("yyyy-MM-dd hh mm ss.Zip")
);
}
});
}
Thank you!
You are getting UnauthorizedAccessException: Access to the path 'C:\temp' is denied. because you can't open a stream from a folder as it doesn't contain bytes.
From what I can understand you are looking to copy the files from one folder to another.
This answer seems to cover what you are doing. https://stackoverflow.com/a/3822913/3634581
Once you have copied the directories you can then create the zip file.
If you don't need to copy the files and just create the Zip I would recommend that since it will reduce the disk IO and speed up the process.
ZipArchive (https://msdn.microsoft.com/en-us/library/system.io.compression.ziparchive(v=vs.110).aspx) can be used to create a zip file straight to a stream.
I figured it out here is the solution
public Task Write(IEnumerable<FileInfo> files)
{
return Task.Run(() =>
{
using (var sftp = new SftpClient(this.sshInfo))
{
sftp.Connect();
sftp.ChangeDirectory(this.remoteDirectory);
foreach (var file in files)
{
var parts = Path.GetDirectoryName(file.RelativePath)
.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries);
sftp.ChangeDirectory(this.remoteDirectory);
foreach (var p in parts)
{
try
{
sftp.ChangeDirectory(p);
}
catch (SftpPathNotFoundException)
{
sftp.CreateDirectory(p);
sftp.ChangeDirectory(p);
}
}
sftp.UploadFile(file.Content, Path.GetFileName(file.RelativePath));
}
}
});
}
****Key point to the solution was
this
var parts = Path.GetDirectoryName(file.RelativePath)
.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries);
We call *Path.GetDirectoryName
on the file itself to get the directory that correlates to the file.
We split the file directory to get the folder name and finally create the folder name we obtained from the split and upload the file to it.
I hope this helps others who may encounter such issue.
I want to know how to read multiple (about 500-1000) text files which are located on a server.
So far, I've written code for a program that only reads a single text file.
Here's how I'm currently reading a single file.
public void button1_Click(object sender, EventArgs e)
{
// Reading/Inputing column values
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string[] fileLines = File.ReadAllLines(ofd.FileName);
I would like to get rid of the open file dialog box, and let the program automatically read the 500-1000 text files where are located in the sever.
I'm thinking something along the lines of
for (int i =0; i<numFiles; i++)
{
//just use string[] fileLines =File.ReadAllLines()
//how would i specify the path for multiple files?
}
Questions are then:
How would I approach this?
How exactly should I get the number of files?
(I'm guessing I'd have to read the server file which contains them.)
You can use Directory.GetFiles(string path) to get all files from a certain directory. You can then use a foreach loop to iterate through all the files in that directory and do your processing.
You can use recursion to loop through all directories. Using Directory.EnumerateFiles also allows you to use a foreach loop so you don't have to worry about the file count.
private static void ReadAllFilesStartingFromDirectory(string topLevelDirectory)
{
const string searchPattern = "*.txt";
var subDirectories = Directory.EnumerateDirectories(topLevelDirectory);
var filesInDirectory = Directory.EnumerateFiles(topLevelDirectory, searchPattern);
foreach (var subDirectory in subDirectories)
{
ReadAllFilesStartingFromDirectory(subDirectory);//recursion
}
IterateFiles(filesInDirectory, topLevelDirectory);
}
private static void IterateFiles(IEnumerable<string> files, string directory)
{
foreach (var file in files)
{
Console.WriteLine("{0}", Path.Combine(directory, file));//for verification
try
{
string[] lines = File.ReadAllLines(file);
foreach (var line in lines)
{
//Console.WriteLine(line);
}
}
catch (IOException ex)
{
//Handle File may be in use...
}
}
}
Also note Directory.EnumerateFiles provides overload that lets you provide a search pattern to narrow the scope of the files.
How you go about getting your files depends on if they are all located in the same directory of if you'll need to recursively search through a directory and all child directories. Directory.GetFiles is where you want to start. It has 3 overloads seen here. So you might try something like this:
string path = "\mypath\tosomehwere";
string searchPattern = "*.txt";
string[] MyFiles = Directory.GetFiles(path, searchPattern, SearchOption.AllDirectories);
Then just loop through the string array and proccess each file as you would normally.
foreach (string filePath in MyFiles)
{
MyFileProcessMethod(filePath)
}
Path.GetFileName(filePath) will return the individual text file name should you need it for your processing requirements.
I have 800-1000 Uniquely named folders in one large folder.
Inside of each uniquely named folder is another folder called /images.
And inside of each image folder is a file named "Rock-Star-Site-Design-{UNIQUEFOLDERNAME}-ca-logo.png"
I write a code that replaces all .png files (while keeping the original name) from a .png file which I supply.
The folder structure and filenames need to remain the same. Basically i am updating the old file with a new file, using the same (unique) name, 800-1000 times.
The code i have tried working properly but there is one mistake.There are plenty of images inside Image folder,But i need to update only "Rock-Star-Site-Design-{UNIQUEFOLDERNAME}-ca-logo.png"file every folder.
is there any way so i can get file.startwith("Rock-Star").So i can update particular file i want.
Here is my code:
private List<String> DirSearch(string sDir)
{
List<String> files = new List<String>();
try
{
foreach (string f in Directory.GetFiles(sDir))
{
files.Add(f);
}
foreach (string d in Directory.GetDirectories(sDir))
{
files.AddRange(DirSearch(d));
}
foreach (var file in files)
{
if (!string.IsNullOrWhiteSpace(file))
{
File.Copy(Server.MapPath("ca-logo.jpg"), file,true);
}
}
}
catch (System.Exception excpt)
{
//MessageBox.Show(excpt.Message);
}
return files;
}
You can use this to get files based on a regular expression
Directory.GetFiles(sDir, "Rock-Star*.png");
Rock-Star*.png means files starting with Rock-Star, * means any character or sequence of characters, ending with .png
First get the file name from file full path using Path.GetFileName(). Then Use StartsWith(). When you add files to the list check if the file name starts with the name you want and then add to the list.
List<String> files = new List<String>();
foreach (string f in Directory.GetFiles(""))
{
//Get file name from full file path
string fileName = Path.GetFileName(f);
//Get only the files starts with Rock-Star
if (fileName.StartsWith("Rock-Star"))
{
files.Add(f);
}
}
EDIT
If you want to update the files with both upper and lower case lettes then you have to pass StringComparison.OrdinalIgnoreCase enumeration to your StartsWith() method
//Get only the files starts with Rock-Star or rock-start
if (fileName.StartsWith("Rock-Star",StringComparison.OrdinalIgnoreCase))
{
files.Add(f);
}
EDIT
To get files within all sub directories and replace, Pass SearchOption.AllDirectories to the GetFiles() method. Following code will search all the sub directories for files with .png extension
foreach (string f in Directory.GetFiles(sDir, "*.png", SearchOption.AllDirectories))
I am looking to create a program that finds all files of a certain type on my desktop and places them into specific folders, for example, I would have all files with .txt into the Text folder.
Any ideas what the best way would be to accomplish this? Thanks.
I have tried this:
string startPath = #"%userprofile%/Desktop";
string[] oDirectories = Directory.GetDirectories(startPath, "");
Console.WriteLine(oDirectories.Length.ToString());
foreach (string oCurrent in oDirectories)
Console.WriteLine(oCurrent);
Console.ReadLine();
It was not successful in finding all of the files.
A lot of these answers won't actually work, having tried them myself. Give this a go:
string filepath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
DirectoryInfo d = new DirectoryInfo(filepath);
foreach (var file in d.GetFiles("*.txt"))
{
Directory.Move(file.FullName, filepath + "\\TextFiles\\" + file.Name);
}
It will move all .txt files on the desktop to the folder TextFiles.
First off; best practice would be to get the users Desktop folder with
string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
Then you can find all the files with something like
string[] files = Directory.GetFiles(path, "*.txt", SearchOption.AllDirectories);
Note that with the above line you will find all files with a .txt extension in the Desktop folder of the logged in user AND all subfolders.
Then you could copy or move the files by enumerating the above collection like
// For copying...
foreach (string s in files)
{
File.Copy(s, "C:\newFolder\newFilename.txt");
}
// ... Or for moving
foreach (string s in files)
{
File.Move(s, "C:\newFolder\newFilename.txt");
}
Please note that you will have to include the filename in your Copy() (or Move()) operation. So you would have to find a way to determine the filename of at least the extension you are dealing with and not name all the files the same like what would happen in the above example.
With that in mind you could also check out the DirectoryInfo and FileInfo classes.
These work in similair ways, but you can get information about your path-/filenames, extensions, etc. more easily
Check out these for more info:
http://msdn.microsoft.com/en-us/library/system.io.directory.aspx
http://msdn.microsoft.com/en-us/library/ms143316.aspx
http://msdn.microsoft.com/en-us/library/system.io.file.aspx
You can try with Directory.GetFiles and fix your pattern
string[] files = Directory.GetFiles(#"c:\", "*.txt");
foreach (string file in files)
{
File.Copy(file, "....");
}
Or Move
foreach (string file in files)
{
File.Move(file, "....");
}
http://msdn.microsoft.com/en-us/library/wz42302f
I am looking for a recursive function that scan a specific folder and send result in a text file.
I would like to list in a text file all files and folder with size, path, creation date, file version if existing but I have no idea on how to proceed.
I found some way to scan recursively but not to recover all needed information.
You can do the following,
GetFileInfo(string dir)
{
try
{
FileInfo info = null;
foreach (string d in Directory.GetDirectories(sDir))
{
foreach (string file in Directory.GetFiles(d))
{
info = new FileInfo(file);
//get all information using info here
}
GetFileInfo(d);
}
}
catch (System.Exception excpt)
{
Console.WriteLine(excpt.Message);
}
}
Use the System.IO.FileInfo object and System.IO.DirectoryInfo object....other than that, show us what you've tried.
You can list a folder using System.IO.DirectoryInfo and System.IO.FileInfo as ganders said.If you can list one folder's content the rest is simple recursion.The idea is while listing root directory if one item in the root directory is a directory call the same function on this directory.