private void btn_Backup_Click(object sender, EventArgs e)
{
List<DirectoryInfo> SourceDir = this.lbox_Sources.Items.Cast<DirectoryInfo>().ToList();
string TargetDir = this.tbox_Target.Text;
foreach (DirectoryInfo directory in SourceDir)
{
foreach (var file in directory.GetFiles())
if (this.checkbox_zipfiles.Checked == true)
{
System.IO.Compression.ZipFile.CreateFromDirectory(directory.FullName, TargetDir + #"\test.zip");
}
else
{
Microsoft.VisualBasic.FileIO.FileSystem.CopyDirectory(directory.FullName, TargetDir, true);
}
}
}
I'm creating a backup application and when I try to zip the files I need to backup it says: "The file 'C:\Users\Lada1208\Desktop\test\test.zip' already exists."
even thought the folder is empty before so it's trying to create the test.zip file two times for some reason. Any idea why?
As pointed out by s.m. in the comment above, the call to ZipFile.CreateFromDirectory() will attempt to create a zip file with the same location and file name for all the source directories.
If the intention is to create a single archive containing files from all the source directories, then the Zipfile.CreateFromDirectory() "shortcut" method cannot be used. Instead, you need to call ZipFile.Open(), get a ZipArchive object and use its CreateEntry() method to add every file individually.
Related
The product I'm using is a Beijer HMI, currently i can generate a report and save it to a known location (my desktop - C:\Users\mrdav\Desktop).
I need to be able to search on my desktop for a file extension .xls and change its name.
When the report is generated by the HMI, it uses the date and time which means when the file is generated the name will be different every time.
On the press of a button i need to search my desktop for the .xls file and change its name to a variable.
// This is my variable with my program
string NewName = Globals.Tags.Tag1.Value;
The code that is generated needs to sit within the below example.
public partial class Screen1
{
void Button1_Click(System.Object sender, System.EventArgs e)
{
// Code to be added here...
}
}
Hopefully someone can help, I’m using windows compact framework so limited on functionality.
Any questions please let me know.
Thanks in advance,
Dave
Here is an example how you can do that:
DirectoryInfo dir = new DirectoryInfo(sExportPath);
FileInfo[] Files = dir.GetFiles("*.csv");
foreach(FileInfo file in Files )
{
// rename file
System.IO.File.Move(file.FullName, GenerateNewFileName());
}
//elsewhere in the class
private string GenerateNewFileName()
{
//here is where you implement creating or getting the filename that you want your file to be renamed to. An example might look like the below
string serialNumber = GetSerialNumber(); //Get the serial number that you talked about in the question. I've made it a string, but it could be an int (it should be a string)
return Path.ChangeExtension(serialNumber,".xls"); //to use path you will need a using statement at the top of your class file 'using System.IO'
}
This seems to work...but i know its not as tidy as it could be.
Any suggestions?
Thanks to all that helped, got there in the end!
void Button_Click(System.Object sender, System.EventArgs e)
{
try
{
// Location for new file
string NewFileName = #"c:\users\mrdav\desktop\testfolder\";
// Add varibale name to new file
NewFileName += Globals.Tags.Tag1.Value;
// add .xls extention to new file
NewFileName += ".xls";
//show new file name to check all ok
MessageBox.Show (NewFileName);
//search for .xls in known directory
DirectoryInfo di = new DirectoryInfo(#"c:\users\mrdav\desktop");
FileInfo[] Files = di.GetFiles("*.xls");
// if files exist with .xls extention
foreach(FileInfo file in Files )
{
// show full file name
MessageBox.Show (file.FullName);
//rename old file to new file name and move to new folder
File.Move(file.FullName, NewFileName);
}
}
catch (Exception ex)
{
MessageBox.Show (ex.ToString());
}
}
I have the following lines of code that work for creating a zip using ZipFile.CreateFromDirectory(selectedFile, zipPath)
if (selectedFolder == string.Empty)
{
Console.WriteLine("Invalid folder, try again");
}
else
{
Console.WriteLine("\nSelect zipfile name: ");
var zipName = Console.ReadLine();
// Also available: extractToDirectory
var zipPath = #"C:\Users\User\Documents\Dev\" + zipName + ".zip";
ZipFile.CreateFromDirectory(selectedFolder, zipPath);
However, the following code which should for all intents and purposes do the same thing except for multiple files being archived into a single zip folder refuses to work:
public static void CreateZipFile(string folderToCreateZip, IEnumerable<string> files)
{
var zipPath = folderToCreateZip + "\\test6.zip";
// Create a new ZIP in this location
using (var zip = ZipFile.Open(zipPath, ZipArchiveMode.Create))
{
foreach (var file in files)
{
// Add entry for files
zip.CreateEntryFromFile(file, zipPath, CompressionLevel.Optimal);
}
}
// Dispose of zip object after files have been zipped
//zip.Dispose();
}
var zip == ZipArchive zip
I've tried disabling read-only mode on the folders where the zip should get created, but I don't think this matters since the prior function with CreateFromDirectory() works fine. I've also tried creating a ZIP on desktop, but I get the same error.
This is the exception I'm getting:
As a note, I noticed that it does initially create the zip despite this error, just that it cannot add anything to it unlike CreateFromDirectory() can due to the folder either being in use, no permissions to that area or the folder already existing. Is there a way I can get CreateEntryFromFile() working or an alternative that would work for multiple files?
I had the same problem. The solution was post the full path name at the destinationArchiveFileName parameter (and also a write alowed path). For example c:\my apps folder\my app\my temp\zipfile.zip
Trying to copy all files/directories inside a directory to a new location that I create.
Users select the 'backup drive' to work with to in a combobox, then when they click the backup desktop button it simply creates a backup directory on that drive and copies all the files into that directory.
The backup directory gets created on the drive appropriately - but the first file it hits it kicks off an error.
private void backupDesktopButton_Click(object sender, EventArgs e)
{
//set the destionationLocation to the selectedDrive
string selectedDrive = backupDriveCombo.SelectedItem.ToString();
string destinationLocation = selectedDrive+"Backups-" + DateTime.Now.Month.ToString()+"-"+DateTime.Now.Year.ToString()+"\\Desktop\\";
if (!Directory.Exists(destinationLocation))
{
Directory.CreateDirectory(destinationLocation);
}
string desktopFolder = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
string[] fileList = Directory.GetFiles(desktopFolder);
foreach (string file in fileList)
{
//move the file
File.Copy(file, destinationLocation);
}
}
I get the error:
IOException was unhandled.
The filename, directory name, or volume label syntax is incorrect.
In the 'Autos' window (VS2010) I see the locations are set correctly:
destinationLocation = the appropriate directory (C:\Backups-8-2016\Desktop\)
file = the appropriate first file (C:\Users\myusername\Desktop\myshortcut.url)
What am I missing? I have all rights to be able to copy/paste/create things and the directory to store it gets created - just a problem moving the file.
From the documentation https://msdn.microsoft.com/en-us/library/c6cfw35a(v=vs.110).aspx
the second parameter:
The name of the destination file. This cannot be a directory or an existing file.
you need to concat the filename to the folder.
Try something like this
string[] fileList = Directory.GetFiles(desktopFolder);
foreach (string file in fileList)
{
string targetFile = Path.Combine(destinationLocation, Path.GetFileName(file));
if (File.Exists(targetFile)) File.Delete(targetFile);
File.Copy(file, targetFile);
}
i want to create C# mass file renamer, here is my UI
i have created tes folder, inside of tes there's a file which is 1.txt.
i want to create my program to add prefix and suffix to the files, so 1.txt will become
prefix1suffix
but then i got an error
it's said file already exist though there's only one file on tes folder, which is 1.txt how do i make it work ? where's the error comes from ?
i have tried the following code
private void Rename(string prefix, string filepath, string suffix)
{
//i don't use prefix suffix yet to make sure if my function works
DirectoryInfo d = new DirectoryInfo(filepath);
FileInfo[] file = d.GetFiles();
try
{
foreach (FileInfo f in file )
{
File.Move(f.FullName,"stackoverflow");
}
}
catch (Exception e)
{
cmd.cetakGagal(e.ToString(), title);
}
cmd.cetakSukses("Rename Success", title);
}
and it returns same error as the second picture above.
the following picture is tes folder, there's nothing in tes folder except 1.txt
You are calling File.Move() with a full path for your sourceFileName and a relative path for your destFileName. The relative file path is relative to the current working directory and not to the source file path. I expect that a stackoverflow file exists in the current working directory, most likely created the first time you ran this code.
your File.Move is changing them all to StackOverflow not using the prefix and suffix. If you only have one file in the directory it shouldn't be an issue. Are you sure there is only 1 file?
public static void Move(
string sourceFileName,
string destFileName
)
Looking at this answer might be the clue as you are specifying relative path for the destination file. To obtain the current working directory, see GetCurrentDirectory
The sourceFileName and destFileName arguments are permitted to specify
relative or absolute path information. Relative path information is
interpreted as relative to the current working directory.
You should change
File.Move(f.FullName,"stackoverflow");
to
string fileName = f.Name.Replace(f.Extenstion,string.Empty);
string newFileName = string.Format("{0}{1}{2}",prefix,fileName,suffix);
string newFileWithPath = Path.Combine(f.Directory,newFileName);
if (!File.Exists(newFileWithPath))
{
File.Move(f.FullName,newFileWithPath);
}
The code above will give you that error since, after the first run through, "stackoverflow" exists as a file. Make sure that you check if the destination file exists (using File.Exists) before calling File.Move.
Since your goal is renaming, I would suggest using a test folder filled with files rather than using a piecemeal approach. See if something like this helps:
private void Rename(string prefix, string filepath, string suffix)
{
//i don't use prefix suffix yet to make sure if my function works
DirectoryInfo d = new DirectoryInfo(filepath);
FileInfo[] file = d.GetFiles();
try
{
foreach (FileInfo f in file )
{
f.MoveTo(#filepath + #"\" + prefix + f.Name.Insert(f.Name.LastIndexOf('.'),suffix));
}
}
catch (Exception e)
{
cmd.cetakGagal(e.ToString(), title);
}
cmd.cetakSukses("Rename Success", title);
}
on a side note using a listview to display the filenames and the changes before they're committed will help prevent unwanted changes.
I need to Copy folder C:\FromFolder to C:\ToFolder
Below is code that will CUT my FromFolder and then will create my ToFolder.
So my FromFolder will be gone and all the items will be in the newly created folder called ToFolder
System.IO.Directory.Move(#"C:\FromFolder ", #"C:\ToFolder");
But i just want to Copy the files in FromFolder to ToFolder.
For some reason there is no System.IO.Directory.Copy???
How this is done using a batch file - Very easy
xcopy C:\FromFolder C:\ToFolder
Regards
Etienne
This link provides a nice example.
http://msdn.microsoft.com/en-us/library/cc148994.aspx
Here is a snippet
// To copy all the files in one directory to another directory.
// Get the files in the source folder. (To recursively iterate through
// all subfolders under the current directory, see
// "How to: Iterate Through a Directory Tree.")
// Note: Check for target path was performed previously
// in this code example.
if (System.IO.Directory.Exists(sourcePath))
{
string[] files = System.IO.Directory.GetFiles(sourcePath);
// Copy the files and overwrite destination files if they already exist.
foreach (string s in files)
{
// Use static Path methods to extract only the file name from the path.
fileName = System.IO.Path.GetFileName(s);
destFile = System.IO.Path.Combine(targetPath, fileName);
System.IO.File.Copy(s, destFile, true);
}
}
there is a file copy.
Recreate folder and copy all the files from original directory to the new one
example
static void Main(string[] args)
{
DirectoryInfo sourceDir = new DirectoryInfo("c:\\a");
DirectoryInfo destinationDir = new DirectoryInfo("c:\\b");
CopyDirectory(sourceDir, destinationDir);
}
static void CopyDirectory(DirectoryInfo source, DirectoryInfo destination)
{
if (!destination.Exists)
{
destination.Create();
}
// Copy all files.
FileInfo[] files = source.GetFiles();
foreach (FileInfo file in files)
{
file.CopyTo(Path.Combine(destination.FullName,
file.Name));
}
// Process subdirectories.
DirectoryInfo[] dirs = source.GetDirectories();
foreach (DirectoryInfo dir in dirs)
{
// Get destination directory.
string destinationDir = Path.Combine(destination.FullName, dir.Name);
// Call CopyDirectory() recursively.
CopyDirectory(dir, new DirectoryInfo(destinationDir));
}
}
Copying directories (correctly) is actually a rather complex task especially if you take into account advanced filesystem techniques like junctions and hard links. Your best bet is to use an API that supports it. If you aren't afraid of a little P/Invoke, SHFileOperation in shell32 is your best bet. Another alternative would be to use the Microsoft.VisualBasic.FileIO.FileSystem.CopyDirectory method in the Microsoft.VisualBasic assembly (even if you aren't using VB).
yes you are right.
http://msdn.microsoft.com/en-us/library/system.io.directoryinfo.aspx
has provided copy function ..
or you can use another function
http://msdn.microsoft.com/en-us/library/ms127960.aspx
You'll need to create a new directory from scratch then loop through all the files in the source directory and copy them over.
string[] files = Directory.GetFiles(GlobalVariables.mstrReadsWellinPath);
foreach(string s in files)
{
fileName=Path.GetFileName(s);
destFile = Path.Combine(DestinationPath, fileName);
File.Copy(s, destFile);
}
I leave creating the destination directory to you :-)
You're right. There is no Directory.Copy method. It would be a very powerful method, but also a dangerous one, for the unsuspecting developer. Copying a folder can potentionaly be a very time consuming operation, while moving one (on the same drive) is not.
I guess Microsoft thought it would make sence to copy file by file, so you can then show some kind of progress information. You could iterate trough the files in a directory by creating an instance of DirectoryInfo and then calling GetFiles(). To also include subdirectories you can also call GetDirectories() and enumerate trough these with a recursive method.
A simple function that copies the entire contents of the source folder to the destination folder and creates the destination folder if it doesn't exist
class Utils
{
internal static void copy_dir(string source, string dest)
{
if (String.IsNullOrEmpty(source) || String.IsNullOrEmpty(dest)) return;
Directory.CreateDirectory(dest);
foreach (string fn in Directory.GetFiles(source))
{
File.Copy(fn, Path.Combine(dest, Path.GetFileName(fn)), true);
}
foreach (string dir_fn in Directory.GetDirectories(source))
{
copy_dir(dir_fn, Path.Combine(dest, Path.GetFileName(dir_fn)));
}
}
}
This article provides an alogirthm to copy recursively some folder and all its content
From the article :
Sadly there is no built-in function in System.IO that will copy a folder and its contents. Following is a simple recursive algorithm that copies a folder, its sub-folders and files, creating the destination folder if needed. For simplicity, there is no error handling; an exception will throw if anything goes wrong, such as null or invalid paths or if the destination files already exist.
Good luck!
My version of DirectoryInfo.CopyTo using extension.
public static class DirectoryInfoEx {
public static void CopyTo(this DirectoryInfo source, DirectoryInfo target) {
if (source.FullName.ToLower() == target.FullName.ToLower())
return;
if (!target.Exists)
target.Create();
foreach (FileInfo f in source.GetFiles()) {
FileInfo newFile = new FileInfo(Path.Combine(target.FullName, f.Name));
f.CopyTo(newFile.FullName, true);
}
foreach (DirectoryInfo diSourceSubDir in source.GetDirectories()) {
DirectoryInfo nextTargetSubDir = target.CreateSubdirectory(diSourceSubDir.Name);
diSourceSubDir.CopyTo(nextTargetSubDir);
}
}
}
And use like that...
DirectoryInfo d = new DirectoryInfo("C:\Docs");
d.CopyTo(new DirectoryInfo("C:\New"));