check for duplicate filename when copying files in C# - c#

I want to copy files to a directory and rename to a particular format. but if the filename already exists, it should append {1}, {2} or {3} before the file extension.
My code renamed and copied the file and named it to my desired format say filename.pdf, when it checked for duplicate it renamed it to filename1.pdf. but when it tried copying again, it gave an error "file already exists" but i wanted it to have named it to filename02.pdf.
Pls can someone help me out.
Here is the code i have written so far.
{
string fileSource, filesToCopy, target, nextTarget;
string sourceDir = #"C:\HCP_PDFs";
string destinationDir = #"C:\RenamedHcpPdfs";
DirectoryInfo di = new DirectoryInfo(destinationDir);
// create the directory if it dosnt exist
if (!Directory.Exists(destinationDir))
{
Directory.CreateDirectory(destinationDir);
}
foreach (string myFiles in lstBoxFilenames.Items)
{
filesToCopy = myFiles;
fileSource = Path.Combine(sourceDir, filesToCopy);
//Extract only HCP Name by splitting , removing file Extension and removing HCP ID
string hcp = filesToCopy.Split('_')[0];
string hcpCd = filesToCopy.Split('_')[1];
string hcpID = filesToCopy.Split('_')[2];
string hcpName = String.Format((filesToCopy.Split('_')[3]).Replace(".pdf", ""));
//combine the HCP ID, HCP name and date
target = Path.Combine(destinationDir, hcp + "{" + hcpCd + "~" + hcpID + "}" + hcpName + "{2013_03_14}" + ".pdf");
// if file exists in directory then rename and increment filename by 1
int i = +1 ;
nextTarget = Path.Combine(destinationDir, hcp + "{" + hcpCd + "~" + hcpID + "}" + hcpName + "{2013_03_14}" + i + ".pdf");
if (File.Exists(target))
{
File.Copy(fileSource, nextTarget);
break;
}
//if file does not exist, rename
else
{
File.Copy(fileSource, target);
}
}
}

Try this :
string target = Path.Combine(destinationDir, hcp + "{" + hcpCd + "~" + hcpID + "}" + hcpName + "{2013_03_14}.pdf");
while(File.Exists(target))
{
i++;
target = Path.Combine(destinationDir, hcp + "{" + hcpCd + "~" + hcpID + "}" + hcpName + "{2013_03_14}" + i + ".pdf");
}
File.Copy(fileSource, target);
break;

Do this
while(File.Exists(target))
{i++;}
now declare your target path.

Related

Delete file which cannot delete because is used by another process

I know you are going to tell me that this question is stupid but I really cannot find a solution to delete my file.
In fact, I open a connection to an .add file (same style as SQL in a way) but afterwards I cannot delete it because it is used by another process which is the process of my application.
While doing some research on the internet I was able to find the solution to kill the process however if I do this it stops my application. Then I also found the GC collect but it doesn't work : /
There is my code :
try
{
string idClient = "parfilux";
string tableName = "ACT,ACF";
string dataSourceDBF = "C:/winbooks/data/parfilux";
string path = dataSourceDBF ;
string pathTemp = dataSourceDBF + "/CopyTempWebService/";
if (!Directory.Exists(pathTemp)) Directory.CreateDirectory(pathTemp);
string addFile = path + "/" + idClient + ".add";
File.Copy(addFile, pathTemp + idClient.ToUpper() + ".add");
File.Copy(addFile.Replace(".add", ".ai"), pathTemp + "/" + idClient.ToUpper() + ".ai");
File.Copy(addFile.Replace(".add", ".am"), pathTemp + "/" + idClient.ToUpper() + ".am");
tableName = tableName.Replace(" ", "");
string[] tables = tableName.Split(',');
string pathTable = null;
foreach (string tab in tables)
{
pathTable = path + "/" + idClient.ToUpper() + "_" + tab.ToUpper() + ".dbf";
File.Copy(pathTable, pathTemp + idClient.ToUpper() + "_" + tab.ToUpper() + ".dbf");
File.Copy(pathTable.Replace(".dbf", ".cdx"), pathTemp + idClient.ToUpper() + "_" + tab.ToUpper() + ".cdx");
}
AdsConnection dbfCo;
//dbfCo.Close();
dbfCo = new AdsConnection(#"data Source=" + dataSourceDBF + "/CopyTempWebService/" + idClient + ".add;User ID=admin;Password=;ServerType=Local;ReadOnly=true;pooling=true;TrimTrailingSpaces=true;ShowDeleted=TRUE;TableType=CDX;LockMode=COMPATIBLE");
dbfCo.Open();
//QueryDataDBF(tableName, idClient, false);
dbfCo.Close();
dbfCo.Dispose();
//Process process = Process.GetCurrentProcess();
//Console.WriteLine(process.MainModule);
//process.Kill();
//foreach(Process pro in process)
//{
// Console.WriteLine(pro);
// if(pro.ProcessName == pathTemp + idClient.ToUpper() + ".add")
// {
// pro.Kill();
// }
//}
//System.GC.Collect();
//System.GC.WaitForPendingFinalizers();
//File.Delete(pathTemp + idClient.ToUpper() + ".add");
Directory.Delete(dataSourceDBF + "/CopyTempWebService", true);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
I open a connection to my .add with the Advantage Data Provider library.
Do you have any idea to fix this problem ? thank you in advance ;)

How to extract file from ZIP archive without the folder using System.IO in c#

In a WinForms project I am trying to extract archive in destination folder, but I not want to extract the folder from archive in destination folder.
I want to extract only the file.
My code:
private void button1_Click(object sender, EventArgs e)
{
string Info = "";
string extractPath = #"D:\dosfiles\SYNOPD\SYNOPD$$.PD\" + comboBox3.SelectedItem.ToString() + #"\" + comboBox2.SelectedItem.ToString() + #"\";
string zipPath = #"D:\dosfiles\" + comboBox1.SelectedItem.ToString() + "_" + comboBox2.SelectedItem.ToString() + "_" + comboBox3.SelectedItem.ToString() + "S" + ".zip";
if (!Directory.Exists(extractPath))
{
Info += "Folder not exists in D:\\dosfiles\\SYNOPD\\SYNOPD$$.PD\\" + comboBox3.SelectedItem.ToString() + #"\" + comboBox2.SelectedItem.ToString() + #"\" + comboBox1.SelectedItem.ToString();
}
else if(Directory.Exists(extractPath))
{
if (Directory.Exists(extractPath))
{
Directory.Delete(extractPath, true);
}
ZipFile.ExtractToDirectory(zipPath, extractPath);
Info += "Your synoptic files has been extracted in D:\\dosfiles\\SYNOPD\\SYNOPD$$.PD\\" + comboBox3.SelectedItem.ToString() + #"\" + comboBox2.SelectedItem.ToString() + #"\" + comboBox1.SelectedItem.ToString() + Environment.NewLine;
}
if (Info != "")
{
MessageBox.Show(Info);
Application.Exit();
}
}
}
}

Bool does not exist in current context but declared in same way as other variables

I have a bool that the compiler says does not exist in the current scope, however all the other variable are declared and used in the same place/way. Code below, some class names changed and code simplified but the structure remains the same.
iDReq does not exist in the current context
if (button.Click) {
string sourceFileName = "";
string destPathFileName = "";
int exportCount = 0;
bool iDReq = true;
iDReq = (System.Windows.Forms.MessageBox.Show("Include ID in file names?", "ID",MessageBoxButtons.YesNo,MessageBoxIcon.Question) == DialogResult.Yes);
foreach (KeyValueCollection item in SearchControl.SelectedItems)
{
Class.Document doc = Class.Document.GetDocument((long)item["id"].Value);
{
sourceFileName = #"\\server\share" + #"\" + Convert.ToString(doc.GetExtraInfo("docFileName"));
string fileExtension = System.IO.Path.GetExtension(sourceFileName);
//Line below is the one that the compiler does not like.
iDReq = true ? destPathFileName = destPath + #"" + doc.Description + " " + "(" + doc.ID + ")" + fileExtension : destPathFileName = destPath + #"" + doc.Description + fileExtension;
try {
System.IO.Directory.CreateDirectory(destPath);
System.IO.File.Copy(sourceFileName,destPathFileName,true);
System.Windows.Forms.Clipboard.SetText(destPathFileName);
exportCount ++;
}
catch(Exception ex)
{
ErrorBox.Show(ex);
}
}
}
}
Is it because it's a boolean value or am I missing something else?
I think your ternary is badly written, but I am not sure about what you want. I would rewrite you this as a plain if/else. I love ternary operator, but it is just sugar.
I think you are looking for this:
destPathFileName = iDReq == true
? (destPath + #"" + doc.Description + " " + "(" + doc.ID + ")" + fileExtension)
: (destPath + #"" + doc.Description + fileExtension);
and iDReq == true is superflous.
also you can write:
destPathFileName = destPath + #"" + doc.Description
+ (iDReq ? " (" + doc.ID + ")" : string.Empty)
+ fileExtension;
by the way, #"" is string.Empty.
and with string interpolation:
destPathFileName = destPath + doc.Description
+ (iDReq ? $" ({doc.ID})" : string.Empty)
+ fileExtension;
try this:
destPathFileName = iDReq ? destPath + #"" + doc.Description + " " + "(" + doc.ID + ")" + fileExtension : destPath + #"" + doc.Description + fileExtension;

Autoincrement end of filename if previous set of files exist

I need to create x number of files (a set) but I must first check to see if the files exist with a similar name.
For example, tiftest1.tif, tiftest2.tif, ... exist and I must write tiftest again to the same directory. I'd like to append _x to the end of the filename, where x is a number that is auto-incremented, each time that I want to create the set. So I can have tiftest1_1.tif,tiftest2_1.tif, tiftest1_2.tif, tiftest2_2.tif, tiftest1_3.tif, tiftest2_3.tif and so forth.
Here is what I have so far:
...
DirectoryInfo root = new DirectoryInfo(fileWatch.Path);
FileInfo[] exist = root.GetFiles(fout + "*.tif");
if (exist.Length > 0)
{
int cnt = 0;
do
{
cnt++;
DirectoryInfo root1 = new DirectoryInfo(fileWatch.Path);
FileInfo[] exist1 = root.GetFiles(fout + "*" + "_" + cnt + ".tif");
arg_proc = "-o " + "\"" + fileWatch.Path
+ "\\" + fout + "%03d_" + cnt + ".tif\" -r " + "\"" + openDialog.FileName + "\"";
} while (exist1.Length > 0); //exist1 is out of scope so this doesn't work
}
else
{
arg_proc = "-o " + "\"" + fileWatch.Path
+ "\\" + fout + "%03d.tif\" -r " + "\"" + openDialog.FileName + "\"";
}
...
exist1.length is out of scope so the loop will continually run. I'm not certain how to correct this. My method was to originally scan the directory for a match and see if the length of the array is greater than 0. If it is > 0 then the _x will autoincrement until a match isn't found. arg_proc is a string used in a function (not included) which will create the files.
Can't you just reuse your exist variable?
FileInfo[] exist = root.GetFiles(fout + "*.tif");
if (exist.Length > 0)
{
int cnt = 0;
do
{
cnt++;
DirectoryInfo root1 = new DirectoryInfo(fileWatch.Path);
exist = root.GetFiles(fout + "*" + "_" + cnt + ".tif");
arg_proc = "-o " + "\"" + fileWatch.Path + "\\"
+ fout + "%03d_" + cnt + ".tif\" -r " + "\"" + openDialog.FileName + "\"";
} while (exist.Length > 0);
}
...
This way, exist won't be out of scope. It didn't look like you needed the original list of files once you started incrementing your counter, so if that is the case, you can just keep reusing exist to count your existing filenames.

How do I properly auto append to filename if file exist

Here is what I have tried, please note that lblImageAlt.Text property has been set to 'Images/'
string ImgPath1 = lblImageAlt1.Text.ToString();
string ImgPath2 = lblImageAlt2.Text.ToString();
string ImgPath3 = lblImageAlt3.Text.ToString();
string filename1 = "";
string filename2 = "";
string filename3 = "";
if (fileuploadimages1.HasFile)
{
if (File.Exists(Server.MapPath(ImgPath1 + filename1)))
{
string extension = Path.GetExtension(filename1);
string name = Path.GetFileNameWithoutExtension(filename1);
int fileMatchCount = 1;
while (File.Exists(Server.MapPath(ImgPath1 + name + "(" + fileMatchCount + ")" + extension)))
fileMatchCount++;
fileuploadimages1.SaveAs(Server.MapPath(ImgPath1 + name + "(" + fileMatchCount + ")" + extension));
}
else
{
fileuploadimages1.SaveAs(Server.MapPath(ImgPath1 + filename1));
}
}
else
{
filename1 = "noImage.jpg";
}
but the same image does not get a number appended to it. What am I doing wrong here?
Path.GetFileName returns the whole filename with the extension.
Thus your code is checking if a file exists with a name like this:
image.jpg1
You should change the code to split the filename in two parts, the base filename and the extension, then check if the filename exists and then rebuild the filename from its parts adding the increment number until you find a non existant filename
// Extract just the filename from the posted file removing the path part (image.jpg)
filename1 = Path.GetFileName(fileuploadimages1.PostedFile.FileName);
baseFile = Path.GetFileNameWithoutExtension(fileuploadimages1.PostedFile.FileName);
extension = Path.GetExtension(fileuploadimages1.PostedFile.FileName);
int fileMatchCount = 1;
// Check if a file with the given name exists in the Images1 subfolder of the root folder of your site
while(File.Exists(Server.MapPath(Path.Combine(ImgPath1, filename1)))
{
// The given file exists already, so we now need to build
// a different (but related) filename using a counter....
// This will create a filename like 'image(001).jpg'
// and then we will restart the loop
fileName1 = string.Format("{0}({1:D3}){2}", baseFile, fileMatchCount, extension);
// ... but first increment the counter in case even the new name exists
fileMatchCount++;
}
// We exit the loop with a name that should not exists in the destination folder
fileuploadimages1.SaveAs(Server.MapPath(Path.Combine(ImgPath1, filename1));
You're not actually modifying filename1. You're checking if it ends in a (0), (1), etc. and incrementing your index, but never actually modifying the variable.
Try using
if(File.Exists(Server.MapPath(ImgPath1 + filename1)))
{
string extension = Path.GetExtension(filename1);
string name = Path.GetFileNameWithoutExtension(filename1);
int fileMatchCount = 1;
while(File.Exists(Server.MapPath(ImgPath1 + name + "(" + fileMatchCount + ")" + extension)))
fileMatchCount++;
fileuploadimages1.SaveAs(Server.MapPath(ImgPath1 + name + "(" + fileMatchCount + ")" + extension));
}
else
fileuploadimages1.SaveAs(Server.MapPath(ImgPath1 + filename1));

Categories

Resources