I have some code that is extracting a file to a directory. In the code below Global.fullpath is the full path to the file its self where as Global.path is the path to the directory. This code works:
private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
{
AppendTextBox("Extracting Files...\r\n");
ZipFile.ExtractToDirectory(Global.fullPath, Global.path);
}
However I am trying to do an overwrite if any files exist so I have this code which doesn't seem to extract anything even when there are no existing files:
private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
{
AppendTextBox("Extracting Files...\r\n");
using (ZipArchive archive = ZipFile.OpenRead(Global.fullPath))
{
foreach (ZipArchiveEntry entry in archive.Entries)
{
AppendTextBox("Extracting file: " + entry.FullName + "...\r\n");
entry.ExtractToFile(Path.Combine(Global.path, entry.FullName), true);
}
}
}
Based on the comments, if you're trying to extract a directory ExtractToFile() is not going to do what you expect. Directories can't be easily overwritten like files. I think you have two options:
Check if the directory specified by FullName exists, and delete it before writing.
Check if the directory specified by FullName exists, and then rename your folder you're going to write something like FullName = FullName + "_Copy";
Make sure you check if the combined path is a valid filename. The ExtractToFile method expects a path that ends with the filename, and some Zip archives can contain folders. In such a case, the entry.FullName property results in an invalid path.
Related
I have recently started to get an error which states my directory can not be found I have tried a number of ways to solve this but have yet to find a solution.
The method should allow the user to select an image for their computer and add it to a folder called images inside the applications folder structure. The problem is that when using the File.copy(imageFilename, path); it throws the error. I have tried changing the path and you will see from the code snip it. It is even doing it when the program itself has passed the file path for the application and is still throwing me the error.
this is the method.
private void btnImageUpload_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog imageFile = new OpenFileDialog();
imageFile.InitialDirectory = #"C:\";
imageFile.Filter = "Image Files (*.jpg)|*.jpg|All Files(*.*)|*.*";
imageFile.FilterIndex = 1;
if (imageFile.ShowDialog() == true)
{
if(imageFile.CheckFileExists)
{
string path = AppDomain.CurrentDomain.BaseDirectory;
System.IO.File.Copy(imageFile.FileName, path);
}
}
}
I am using VS2013 and have included the using Microsoft.win32
Any further information needed please ask.
Thanks
There are 2 things need to be taken into consideration
private void btnImageUpload_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog imageFile = new OpenFileDialog();
imageFile.InitialDirectory = #"C:\";
imageFile.Filter = "Image Files (*.jpg)|*.jpg|All Files(*.*)|*.*";
imageFile.FilterIndex = 1;
if (imageFile.ShowDialog() == true)
{
if(imageFile.CheckFileExists)
{
string path = AppDomain.CurrentDomain.BaseDirectory; // You wont need it
System.IO.File.Copy(imageFile.FileName, path); // Copy Needs Source File Name and Destination File Name
}
}
}
string path = AppDomain.CurrentDomain.BaseDirectory; You won need this because the default directory is your current directory where your program is running.
Secondly
System.IO.File.Copy(imageFile.FileName, path); Copy Needs Source File Name and Destination File Name so you just need to give the file name instead of path
so your updated code will be
private void btnImageUpload_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog imageFile = new OpenFileDialog();
imageFile.InitialDirectory = #"C:\";
imageFile.Filter = "Image Files (*.jpg)|*.jpg|All Files(*.*)|*.*";
imageFile.FilterIndex = 1;
if (imageFile.ShowDialog() == true)
{
if(imageFile.CheckFileExists)
{
System.IO.File.Copy(imageFile.FileName, SomeName + ".jpg"); // SomeName Must change everytime like ID or something
}
}
}
I'm not sure if that's the problem, but the File.Copy method expects a source file name and a target file name, not a source file name and directory: https://msdn.microsoft.com/en-us/library/c6cfw35a(v=vs.110).aspx
So, to make this work, in your case you'd have to do something like the following (namespaces omitted):
File.Copy(imageFile.FileName, Path.Combine(path, Path.GetFileName(imageFile.FileName));
Note that this will fail if the destination file exists, to overwrite it, you need to add an extra parameter to the Copy method (true).
EDIT:
Just a note, the OpenFileDialog.CheckFileExists does not return a value indicating if the selected file exists. Instead, it is a value indicating whether a file dialog displays a warning if the user specifies a file name that does not exist. So instead of checking this property after the dialog is closed, you should set it to true before you open it (https://msdn.microsoft.com/en-us/library/microsoft.win32.filedialog.checkfileexists(v=vs.110).aspx)
I have several issues within a windows forms application. So far, I have managed to loop though a folder and display the reuslts in a text box. Once these have returned, the user can check the results and the error files can be removed using the following;
private void button2_Click(object sender, EventArgs e)
{
foreach (string file in Directory.GetFiles(#"\\" + textBox1.Text + #"\\d$\\NSB\\Coalition\\EDU", "*.err").Where(item => item.EndsWith(".err")))
{
File.Delete(file);
}
}
What I want to do now, after the error files have been removed, is copy the same files from a backup folder (the only difference in the filenames is the file extention) I am using a seperate button for this action. Any help on this final step would be greatly appreciated.
Use Path class to get File names without extensions, combine paths and more, as an example:
StringCollection filesToBeReplaced = new StringCollection();
private void button2_Click(object sender, EventArgs e)
{
foreach (string file in Directory.GetFiles(#"\\" + textBox1.Text + #"\\d$\\NSB\\Coalition\\EDU", "*.err").Where(item => item.EndsWith(".err")))
{
//Now you have file names without extension
filesToBeReplaced.Add(Path.GetFileNameWithoutExtension (file));
File.Delete(file);
}
}
private void CopyGoodFilesFromSource()
{
foreach(string fileName in filesToBeReplaced)
{
string sourceFilePath = Path.Combine("YOUR FOLDER FOR GOOD FILES",
Path.ChangeExtension(fileName,"Your Extension")) ;
string destinationPath = Path.Combine("Destination Folder",
Path.ChangeExtension(fileName, "Your Extension in destination folder");
File.Copy(sourceFilePath , destinationPath, true);
}
}
Okay, I have a button (button1) which I want to copy the static directory to the chosen directory. Essentially I have textbox1 in which different numeric values are added which correlate with different directories. I have a dictionary that sets the string to mapping which links to codes from textbox2 to the path of the origination folder. . This determines where we copy our data from. I want this data to then be copied into the folder selected in textbox2 through the folderBrowserDialog1.ShowDialog(); command. how to i create the dictionary and where do i put it for textbox1, and how do i then get the button to take whatever is in textbox1 and copy the entire directory to textbox2?
private Dictionary<string, string> mapping = new Dictionary<string, string>
{
{ "111", #"C:\Program Files\Example" },
{ "112", #"C:\Program Files\Example2" },
{ "113", #"C:\Program Files\Example3" },
};
public static string[] GetFiles(string mapping);
public static void Copy(string sourceFileName, string destFileName);
private void button2_Click(object sender, EventArgs e)
{
string destination = textBox1.Text;
foreach (var f in Directory.GetFiles(mapping))
{
File.Copy(Path.Combine(mapping, f)); destination;
}
}
Here is an answeer to "How copy an entire directory of files":
Use Directory.GetFiles() (see documentation) to get a list of all files in a directory.
Then use File.Copy() (see documenation) to copy a single file:
foreach(var f in Directory.GetFiles(srcPath))
{
File.Copy(Path.Combine(srcPath, f), dstPath);
}
EDIT
Directory.GetFiles() requires a path:
private void button2_Click(object sender, EventArgs e)
{
string destination = textBox1.Text;
string srcdir = mapping["111"];
foreach(var f in Directory.GetFiles(srcdir))
{
string srcpath = Path.Combine(srcdir, f)
File.Copy(srcpath, destination);
}
}
I'm not 100% sure I understood the details of your question, as the uses of TextBox1 and TextBox2 don't seem consistent, but here's what I read:
TextBox1 has the codes that the dictionary maps to a source directory.
TextBox2 has the path (from the dialog box) to the destination directory.
If that is correct, you're close. Some things to note:
I'm not sure why you have these two lines. They look like method definitions, but there's no implementation. I think you can remove them and use the equivalent System.IO calls:
public static string[] GetFiles(string mapping);
public static void Copy(string sourceFileName, string destFileName);
Directory.GetFiles(mapping) won't work, because mapping is a Dictionary<string, string>, not a string. You need to select the corresponding value (path) based on the key (numeric code) from TextBox1 and use that in the Directory.GetFiles() method.
File.Copy(Path.Combine(mapping, f)); destination; is an incorrect syntax and won't compile (should be File.Copy(Path.Combine(mapping, f), destination);. Additionally, you don't need to combine the source path and filename for the first argument, as GetFiles returns the path along with the filename (including extension). You will need to get the filename alone and combine it with the sourece path for the destination file, however. You can use Path.GetFileName to do this.
Try this code below - it addresses the issues noted above, with the assumption being that textBox1 is the source in mappings and textBox2 is the destination from the dialog window:
private void button2_Click(object sender, EventArgs e)
{
string source = textBox1.Text
string destination = textBox2.Text;
if (mappings.ContainsKey(source))
{
foreach (var f in Directory.GetFiles(source))
{
File.Copy(f, Path.Combine(destination, Path.GetFileName(f)));
}
}
else
{
// No key was found, how you handle it will be dictated by the needs of the application and/or users.
}
}
The above code does the following:
Gets the numeric value for the path of the source directory. This should correspond to one of the keys in the dictionary.
Gets the path for the destination directory based on the user selected value from the dialog box.
Checks to see if the key from textBox1 is present in the directory.
If it is, it gets the corresponding value for that key, which is the path for the source directory.
Next, it loops through the files in the specified source directory, copying each one in turn to the destination directory. Note that f (the file) is used as the source file for the first argument (as it contains the path as well, as Directory.GetFiles() returns both the path and the filename), and the destination directory is combined with the filename (retrieved by a call to Path.GetFileName). If f alone was used in the Path.Combine() method, you'd wind up with sourcePath\originalPath\filename.
If the key wasn't found, you ignore it or do something with it.
Again, the above code is based on my understanding of your question. If my understanding was less than correct, the principles I outlined should still be able to assist you in resolving the issue.
** EDIT **
Per the comments below, it sounds like all you need to do is flip the assignments for source and destination. textBox2 will contain the code that corresponds to a key in the mappings directory, which will give you the path of the source directory. textBox1 will contain the destination path. Like this:
string source = textBox2.Text
string destination = textBox1.Text;
The rest of the code stays the same.
After going through all the related stuff to copying files i am unable to find an answer to my
problem of an exception occurring while i was trying to copy a file to an empty folder in WPF application. Here is the code snippet.
public static void Copy()
{
string _finalPath;
foreach (var name in files) // name is the filename extracted using GetFileName in a list of strings
{
_finalPath = filePath; //it is the destination folder path e.g,C:\Users\Neha\Pictures\11-03-2014
if(System.IO.Directory.Exists(_finalPath))
{
_finalPath = System.IO.Path.Combine(_finalPath,name);
System.IO.File.Copy(name, _finalPath , true);
}
}
}
While debugging exception is occuring at file.copy() statement which says
"FileNotFoundException was unhandled" could not find file
i already know about the combining path and other aspects of copy but i dont know why this exception is being raised.
I am a noob to WPF please help.........
Use following code:
public static void Copy()
{
string _finalPath;
var files = System.IO.Directory.GetFiles(#"C:\"); // Here replace C:\ with your directory path.
foreach (var file in files)
{
var filename = file.Substring(file.LastIndexOf("\\") + 1); // Get the filename from absolute path
_finalPath = filePath; //it is the destination folder path e.g,C:\Users\Neha\Pictures\11-03-2014
if (System.IO.Directory.Exists(_finalPath))
{
_finalPath = System.IO.Path.Combine(_finalPath, filename);
System.IO.File.Copy(file, _finalPath, true);
}
}
}
The GetFileName ()
only returns the actual name of the file (drops the path) what you want is a full path to the file. So you getting an exception because the 'name' does not exist on your drive (path is unknown)
You're variable, name, is most likely just the file name (i.e. something.jpg). When you use the File.Copy(...) method, if you do not supply an absolute path the method assumes a path relative to the executable.
Basically, if you are running your app in, for example, C:\Projects\SomeProject\bin\Debug\SomeProject.exe, then it is assuming your file is C:\Projects\SomeProject\bin\Debug\something.jpg.
I need some help in renaming some images in a directory located at /images/graphicsLib/.
All image names in /graphicsLib/ have naming convention that looks like this:
400-60947.jpg. We call the "400" part of the file the prefix and we call the "60957" part the suffix. The entire file name we call the sku.
So if you saw the contents of /graphicLib/ it would look like:
400-60957.jpg
400-60960.jpg
400-60967.jpg
400-60968.jpg
402-60988.jpg
402-60700.jpg
500-60725.jpg
500-60733.jpg
etc...
Using C# & System.IO , what is an acceptable way to rename all image files base on the prefix of the file name? Users need to be able to enter in the current prefix, see all images in the /graphicsLib/ that match, then enter in the new prefix to have all those files renamed with the new prefix. Only the prefix of the file gets renamed, the rest of the file name needs to be unchanged.
What I have so far is:
//enter in current prefix to see what images will be affected by
// the rename process,
// bind results to a bulleted list.
// Also there is a textbox called oldSkuTextBox and button
// called searchButton in .aspx
private void searchButton_Click(object sender, EventArgs e)
{
string skuPrefix = oldSkuTextBox.Text;
string pathToFiles = "e:\\sites\\oursite\\siteroot\\images\graphicsLib\\";
string searchPattern = skuPrefix + "*";
skuBulletedList.DataSource = Directory.GetFiles(pathToFiles, searchPattern);
skuBulletedList.DataBind();
}
//enter in new prefix for the file rename
//there is a textbox called newSkuTextBox and
//button called newSkuButton in .aspx
private void newSkuButton_Click(object sender, EventArgs e)
{
//Should I loop through the Items in my List,
// or loop through the files found in the /graphicsLib/ directory?
//assuming a loop through the list:
foreach(ListItem imageFile in skuBulletedList.Items)
{
string newPrefix = newSkuTextBox.Text;
//need to do a string split here?
//Then concatenate the new prefix with the split
//of the string that will remain changed?
}
}
You could look at string.Split.
Loop over all files in your directory.
string[] fileParts = oldFileName.Split('-');
This will give you an array of two strings:
fileParts[0] -> "400"
fileParts[1] -> "60957.jpg"
using the first name in your list.
Your new filename then becomes:
if (fileParts[0].Equals(oldPrefix))
{
newFileName = string.Format("(0)-(1)", newPrefix, fileParts[1]);
}
Then to rename the file:
File.Move(oldFileName, newFileName);
To loop over the files in the directory:
foreach (string oldFileName in Directory.GetFiles(pathToFiles, searchPattern))
{
// Rename logic
}
Actually you should iterate each of the files in the directory and rename one by one
To determine the new file name, you may use something like:
String newFileName = Regex.Replace("400-60957.jpg", #"^(\d)+\-(\d)+", x=> "NewPrefix" + "-" + x.Groups[2].Value);
To rename the file, you may use something like:
File.Move(oldFileName, newFileName);
If you are not familiar with regular expressions, you should check:
http://www.radsoftware.com.au/articles/regexlearnsyntax.aspx
And download this software to pratice:
http://www.radsoftware.com.au/regexdesigner/