I have a problem, i am trying to write a program that will copy a file with the same name from A to B and i want to change the exension from bk2 to bk3,4,5,6,7 or just rename the filename so the program can copy the file even if the same name allready exist.
I am very beginner in C# everything is dificult now.
Below the code
enter code here
static void Main(string[] args)
{
//path of file
string pathToOriginalFile = #"D:\C#\LOGS_PROG\SystemLog.bk2";
string extension = ".bk2";
//duplicate file path
string PathForDuplicateFile = #"D:\C#\Backup\Systemlog";
//provide source and destination file paths
File.Copy(pathToOriginalFile, PathForDuplicateFile + extension);
}
}
There is few tips.
You can use System.IO.Path.
path of file
string pathToOriginalFile = #"D:\C#\LOGS_PROG\SystemLog.bk2";
Where the file is located (D:\C#\LOGS_PROG) be careful, there is no \ at the end
string where = Path.GetDirectoryName(pathToOriginalFile);
THe name of the wile without its extension (SystemLog)
string name = Path.GetFileNameWithoutExtension(pathToOriginalFile);
its extension (.bk2)
string extension = Path.GetExtension(pathToOriginalFile);
The name and the extension (SystemLog.bk2)
string nameAndExtension = Path.GetFileName(pathToOriginalFile);
Now, if your purpose is to duplicate the file :
//path of file
string pathToOriginalFile = #"D:\C#\LOGS_PROG\SystemLog.bk2";
for (int i = 1; ; ++i)
{
// For example : D:\C#\LOGS_PROG\SystemLog (9).bk2 if there is the original + 8 copy
string pathToNewFile = Path.Combine(Path.GetDirectoryName(pathToOriginalFile), Path.GetFileNameWithoutExtension(pathToOriginalFile) + " (" + i + ")" + Path.GetExtension(pathToOriginalFile));
if (!File.Exists(pathToNewFile))
{
File.Copy(pathToOriginalFile, pathToNewFile);
break;
}
}
I separated the structure so you can see how it is built but you can use already known variables.
try this:
static void Main(string[] args)
{
//path of file
string pathToOriginalFile = #"D:\C#\LOGS_PROG\SystemLog.bk2";
string extension = ".bk2";
//duplicate file path
string PathForDuplicateFile = #"D:\C#\Backup\Systemlog";
//rename fileName if Exists
FixFileName(ref PathForDuplicateFile, extension);
//provide source and destination file paths
File.Copy(pathToOriginalFile, PathForDuplicateFile + extension);
}
static void FixFileName(ref string PathForDuplicateFile, string extention)
{
int i = 0;
while (true)
{
i++;
if (File.Exists(PathForDuplicateFile + extention))
PathForDuplicateFile += i;
else
break;
}
}
Problem solved.
The program copy the file and if the file exist it renames the extension.
Winndow runs it every day and so i got my autobackup
Thakns for the help!
static void Main(string[] args)
{
//path of file
string pathToOriginalFile = #"C:\Desktop\c#\Logging\Systemlog.bk66";
//duplicate file path
string PathForDuplicateFile = #"C:\\Desktop\c#\Systemlog";
//rename fileName if Exists
FixFileName(ref PathForDuplicateFile, ".bk");
if (File.ReadAllText(pathToOriginalFile).Length > 2000)
{
File.Copy(pathToOriginalFile, PathForDuplicateFile);
}
else
{
}
//provide source and destination file paths
}
static void FixFileName(ref string PathForDuplicateFile, string extention)
{
int i = 0;
while (true)
{
i++;
if (File.Exists(PathForDuplicateFile + extention))
extention += i;
else
break;
}
PathForDuplicateFile += extention;
}
}
I am Getting this error An unhandled exception of type 'System.StackOverflowException' occurred in mscorlib.dll I know you are not supposed to have an infinite loop but its not an infinate loop because it just has too go till it gets a file number that has not been made yet. How can i go about this a better way?
private int x = 0;
public string clients = #"F:\Internal Jobs\Therm-Air Files\Program\P-1-2.0\Clients\";
public string tdate = DateTime.Today.ToString("MM-dd-yy");
public void saveloop()
{
string path = LoadPO.Text.Substring(0, LoadPO.Text.LastIndexOf("\\"));
string name = Path.GetFileName(path);
string t = Convert.ToString(x);
if (!File.Exists(path + #"\" + name + ".xlsx")) // This Line throws error
{
oSheet.SaveAs(path + #"\" + name + "-" + t + ".xlsx");
string prop = /* snipped for space reasons, just string concats */
string Combine = string.Empty;
int b = 0;
int c = cf.cPanel.Controls.Count;
string[] items = new string[c];
foreach (WProduct ewp in cf.cPanel.Controls)
{
string item = /* snipped for space reasons, just string concats */
items[b] = item;
b += 1;
}
Combine = prop + "^<";
foreach (var strings in items)
{
Combine += strings + "<";
}
File.WriteAllText(path + #"\" + name + ".txt", Combine);
}
else
{
x += 1;
saveloop();
}
The reason the code above is failing is because you do not use i in the name of the file so you can increment all you want it does not change the name.
You need to abstract the creation of the name of the file from the code that does the writing. Think of it as writing code in blocks of functionality.
public static string GetFileName(string path, string name)
{
var fileName = $#"{path}\{name}.xlsx";
int i = 0;
while (System.IO.File.Exists(fileName))
{
i++;
fileName = $#"{path}\{name}({i}).xlsx";
}
return fileName;
}
public void saveloop()
{
var fileName = GetFileName(path, name);
// use fileName from this point on
}
I'm using 2008 and am unable to use the EnumerateFiles class.
Any folder beyond the root level are essentially ignored when attempting to sum the files within listed network path. Here's my code:
public void getLeverageServer(string Server)
{
int Inp = 0;
int Out = 0;
int Ex = 0;
string output = "\\\\" + Server + "\\F\\Output";
string input = "\\\\" + Server + "\\F\\Input";
string exceptions = "\\\\" + Server + "\\F\\Exceptions";
string[] pathIn = Directory.GetFiles(input);
string[] pathOut = Directory.GetFiles(output);
string[] pathExceptions = Directory.GetFiles(exceptions);
foreach (string element in pathIn)
{
Inp++;
}
foreach (string element in pathOut)
{
Out++;
}
foreach (string element in pathExceptions)
{
Ex++;
}
txtLevInp.Text = Convert.ToString(Inp);
txtLevOut.Text = Convert.ToString(Out);
txtLevExc.Text = Convert.ToString(Ex);
txtLevTotal.Text = Convert.ToString(Out + Ex);
}
You need a different overload of Directory.GetFiles
string[] pathIn = Directory.GetFiles(input, "*.*", SearchOption.AllDirectories);
And you don't need to count the files found. Just read the value of the property Length of the returned array....
txtLevInp.Text = pathIn.Length;
My C# code is generating several text files based on input and saving those in a folder. Also, I am assuming that the name of the text file will be same as input.(The input contains only letters)
If two files has same name then it is simply overwriting the previous file.
But I want to keep both files.
I don't want to append current date time or a random number to the 2nd file name. Instead I want to do it the same way Windows does. If the fisrt file name is AAA.txt , then second file name is AAA(2).txt, third file name will be AAA(3).txt.....N th file name will be AAA(N).txt.
string[] allFiles = Directory.GetFiles(folderPath).Select(filename => Path.GetFileNameWithoutExtension(filename)).ToArray();
foreach (var item in allFiles)
{
//newFileName is the txt file which is going to be saved in the provided folder
if (newFileName.Equals(item, StringComparison.InvariantCultureIgnoreCase))
{
// What to do here ?
}
}
This will check for the existence of files with tempFileName and increment the number by one until it finds a name that does not exist in the directory.
int count = 1;
string fileNameOnly = Path.GetFileNameWithoutExtension(fullPath);
string extension = Path.GetExtension(fullPath);
string path = Path.GetDirectoryName(fullPath);
string newFullPath = fullPath;
while(File.Exists(newFullPath))
{
string tempFileName = string.Format("{0}({1})", fileNameOnly, count++);
newFullPath = Path.Combine(path, tempFileName + extension);
}
With this code if file name is "Test (3).txt" then it will become "Test (4).txt".
public static string GetUniqueFilePath(string filePath)
{
if (File.Exists(filePath))
{
string folderPath = Path.GetDirectoryName(filePath);
string fileName = Path.GetFileNameWithoutExtension(filePath);
string fileExtension = Path.GetExtension(filePath);
int number = 1;
Match regex = Regex.Match(fileName, #"^(.+) \((\d+)\)$");
if (regex.Success)
{
fileName = regex.Groups[1].Value;
number = int.Parse(regex.Groups[2].Value);
}
do
{
number++;
string newFileName = $"{fileName} ({number}){fileExtension}";
filePath = Path.Combine(folderPath, newFileName);
}
while (File.Exists(filePath));
}
return filePath;
}
The other examples don't take into account the filename / extension.
Here you go:
public static string GetUniqueFilename(string fullPath)
{
if (!Path.IsPathRooted(fullPath))
fullPath = Path.GetFullPath(fullPath);
if (File.Exists(fullPath))
{
String filename = Path.GetFileName(fullPath);
String path = fullPath.Substring(0, fullPath.Length - filename.Length);
String filenameWOExt = Path.GetFileNameWithoutExtension(fullPath);
String ext = Path.GetExtension(fullPath);
int n = 1;
do
{
fullPath = Path.Combine(path, String.Format("{0} ({1}){2}", filenameWOExt, (n++), ext));
}
while (File.Exists(fullPath));
}
return fullPath;
}
How about just:
int count = 1;
String tempFileName = newFileName;
foreach (var item in allFiles)
{
if (tempFileName.Equals(item, StringComparison.InvariantCultureIgnoreCase))
{
tempFileName = String.Format("{0}({1})", newFileName, count++);
}
}
This will use the original file name if it's not there, if not it'll take a new file name with the index in brackets (although this code isn't taking the extension into account). If the newly generated name "text(001)" is used then it'll increment until it finds a valid unused file name.
public static string AutoRenameFilename(FileInfo file)
{
var filename = file.Name.Replace(file.Extension, string.Empty);
var dir = file.Directory.FullName;
var ext = file.Extension;
if (file.Exists)
{
int count = 0;
string added;
do
{
count++;
added = "(" + count + ")";
} while (File.Exists(dir + "\\" + filename + " " + added + ext));
filename += " " + added;
}
return (dir + filename + ext);
}
int count= 0;
file is the name of file
while (File.Exists(fullpathwithfilename)) //this will check for existence of file
{
// below line names new file from file.xls to file1.xls
fullpathwithfilename= fullpathwithfilename.Replace("file.xls", "file"+count+".xls");
count++;
}
I was looking for a solution that would move a file, and make sure that if the destination file name is not already taken. It would follow the same logic as Windows and append a number, with brackets after the duplicate file.
The top answer, thanks to #cadrell0, helped me arrive to the following solution:
/// <summary>
/// Generates full file path for a file that is to be moved to a destinationFolderDir.
///
/// This method takes into account the possiblity of the file already existing,
/// and will append number surrounded with brackets to the file name.
///
/// E.g. if D:\DestinationDir contains file name file.txt,
/// and your fileToMoveFullPath is D:\Source\file.txt, the generated path will be D:\DestinationDir\file(1).txt
///
/// </summary>
/// <param name="destinationFolderDir">E.g. D:\DestinationDir </param>
/// <param name="fileToMoveFullPath">D:\Source\file.txt</param>
/// <returns></returns>
public string GetFullFilePathWithDuplicatesTakenInMind(string destinationFolderDir, string fileToMoveFullPath)
{
string destinationPathWithDuplicatesTakenInMind;
string fileNameWithExtension = Path.GetFileName(fileToMoveFullPath);
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileToMoveFullPath);
string fileNameExtension = Path.GetExtension(fileToMoveFullPath);
destinationPathWithDuplicatesTakenInMind = Path.Combine(destinationFolderDir, fileNameWithExtension);
int count = 0;
while (File.Exists(destinationPathWithDuplicatesTakenInMind))
{
destinationPathWithDuplicatesTakenInMind = Path.Combine(destinationFolderDir, $"{fileNameWithoutExtension}({count}){fileNameExtension}");
count = count + 1; // sorry, not a fan of the ++ operator.
}
return destinationPathWithDuplicatesTakenInMind;
}
With regard to Giuseppe's comment on the way windows renames files I worked on a version that finds any existing index i.e. (2) in the file name and renames the file as per windows accordingly. The sourceFileName is assumed to be valid and the user is assumed to have write permission on the destination folder by this point:
using System.IO;
using System.Text.RegularExpressions;
private void RenameDiskFileToMSUnique(string sourceFileName)
{
string destFileName = "";
long n = 1;
// ensure the full path is qualified
if (!Path.IsPathRooted(sourceFileName)) { sourceFileName = Path.GetFullPath(sourceFileName); }
string filepath = Path.GetDirectoryName(sourceFileName);
string fileNameWOExt = Path.GetFileNameWithoutExtension(sourceFileName);
string fileNameSuffix = "";
string fileNameExt = Path.GetExtension(sourceFileName);
// if the name includes the text "(0-9)" then we have a filename, instance number and suffix
Regex r = new Regex(#"\(\d+\)");
Match match = r.Match(fileNameWOExt);
if (match.Success) // the pattern (0-9) was found
{
// text after the match
if (fileNameWOExt.Length > match.Index + match.Length) // remove the format and create the suffix
{
fileNameSuffix = fileNameWOExt.Substring(match.Index + match.Length, fileNameWOExt.Length - (match.Index + match.Length));
fileNameWOExt = fileNameWOExt.Substring(0, match.Index);
}
else // remove the format at the end
{
fileNameWOExt = fileNameWOExt.Substring(0, fileNameWOExt.Length - match.Length);
}
// increment the numeric in the name
n = Convert.ToInt64(match.Value.Substring(1, match.Length - 2)) + 1;
}
// format variation: indexed text retains the original layout, new suffixed text inserts a space!
do
{
if (match.Success) // the text was already indexed
{
if (fileNameSuffix.Length > 0)
{
destFileName = Path.Combine(filepath, String.Format("{0}({1}){2}{3}", fileNameWOExt, (n++), fileNameSuffix, fileNameExt));
}
else
{
destFileName = Path.Combine(filepath, String.Format("{0}({1}){2}", fileNameWOExt, (n++), fileNameExt));
}
}
else // we are adding a new index
{
destFileName = Path.Combine(filepath, String.Format("{0} ({1}){2}", fileNameWOExt, (n++), fileNameExt));
}
}
while (File.Exists(destFileName));
File.Copy(sourceFileName, destFileName);
}
You can declare a Dictionary<string,int> to keep the number of times each root file name was saved. After that, on your Save method, just increase the counter and append it to the base file name:
var key = fileName.ToLower();
string newFileName;
if(!_dictionary.ContainsKey(key))
{
newFileName = fileName;
_dictionary.Add(key,0);
}
else
{
_dictionary[key]++;
newFileName = String.Format("{0}({1})", fileName, _dictionary[key])
}
This way, you'll have a counter for each distinct file name: AAA(1), AAA(2); BBB(1)...
It's working fine now. thanks guys for the answers..
string[] allFiles = Directory.GetFiles(folderPath).Select(filename => Path.GetFileNameWithoutExtension(filename)).ToArray();
string tempFileName = fileName;
int count = 1;
while (allFiles.Contains(tempFileName ))
{
tempFileName = String.Format("{0} ({1})", fileName, count++);
}
output = Path.Combine(folderPath, tempFileName );
string fullPath=output + ".xml";
I am trying to make a web server in C#, i need to get the requested url and then list the files and folders requested.This is good to get the first directory .
For Eg. My webserver root is c:\test when i open localhost i get the contents of test folder. Say Data is subfolder of c:\test, i can click on data from the browser and get into C:\test\data now when i click on any folder then the get request comes with %2F instead of c:\test\data\ok and so i am stuck.
Code to Recieve The Request :
sRequest = sBuffer.Substring(0, iStartPos - 1);
sRequest.Replace("\\", "/");
if ((sRequest.IndexOf(".") < 1) && (!sRequest.EndsWith("/")))
{
sRequest = sRequest + "/";
}
iStartPos = sRequest.LastIndexOf("/") + 1;
sRequestedFile = sRequest.Substring(iStartPos);
sDirName = sRequest.Substring(sRequest.IndexOf("/"), sRequest.LastIndexOf("/") - 3);
if (sDirName == "/")
sLocalDir = sMyWebServerRoot;
else
{
//Get the Virtual Directory
// sLocalDir = GetLocalPath(sMyWebServerRoot, sDirName);
Console.WriteLine("i am here");
sDirName = sDirName.Substring(1, sDirName.Length - 2);
//sDirName = sDirName.Replace("/", "\\");
Console.WriteLine("Amit:" + sDirName);
string test1 = Path.Combine("C:\\test\\", sDirName);
sLocalDir = Path.Combine(#"C:\\test", sDirName);
}
Now to List Dir I have the following Function :
public String listdir(string sLocaldir,string sDirName)
{
string sresult = "";
StringBuilder sb = new StringBuilder();
sb.AppendLine("<html>");
sb.AppendLine("<head>");
sb.AppendLine("<title>Test</title>");
sb.AppendLine("</head>");
sb.AppendLine("<body>");
sb.AppendLine("<h1><center><u>Listing Folders Under " + sLocaldir + "</h1></u></center>");
string[] folderpaths = Directory.GetDirectories(sLocaldir);
sb.AppendLine("<font color=red><font size=5>Listing Directories<br>");
for (int i = 0; i < folderpaths.Length; i++)
{
string fpath = folderpaths[i];
string[] foldernames = fpath.Split('\\');
int j = foldernames.Length - 1;
string fname = foldernames[j];
string fullname;
if (sDirName != "/")
{
//fname= fname + "\\";
fullname = sDirName +"/"+ fname;
//fullname = fullname.Replace("\\", "/");
//fullname = Path.GetPathRoot("C:\\test");
Console.WriteLine("Get full path:" + fullname);
}
else
{
fullname = fname;
}
Console.WriteLine("Full Test:" + fullname);
//sb.AppendLine(string.Format("<img src=file.png height=20 width=20>{1}<br>",
sb.AppendLine(string.Format("<img src=file.png height=20 width=20>{1}<br>",
HttpUtility.HtmlEncode(HttpUtility.UrlEncode(fullname )),
HttpUtility.HtmlEncode(fname)));
}
string[] filePaths = Directory.GetFiles(#"C:\test");
sb.AppendLine("<font color=red><font size=5>Listing Files<br>");
for (int i = 0; i < filePaths.Length; ++i)
{
string name = Path.GetFileName(filePaths[i]);
sb.AppendLine(string.Format("<img src=file.png height=20 width=20>{1}<br>",
HttpUtility.HtmlEncode(HttpUtility.UrlEncode(name)),
HttpUtility.HtmlEncode(name)));
}
sb.AppendLine("</ul>");
sb.AppendLine("</body>");
sb.AppendLine("</html>");
sresult = sb.ToString();
return sresult;
//Console.WriteLine(sresult);
}
Any help would be highly appreciated.
Thank you
%2F is safe encoding for the / symbol. You are HTMLEncoding the / symbol in your code above.
Your approach can be much simpler see:
http://www.codeproject.com/KB/IP/mywebserver.aspx