I want to do something like this:
(1) Check for existence of file with certain extension ".txt" in a directory D:\test
(2) If a file does not exist, create a initial one, write something to it, and name it test_1.txt
(2) If a file exists, write and append something to it, and renamed it to the next incremental number.
For example, if test_1.txt exists, renamed it to test_2.txt, after write and append.
if test_21.txt exists, renamed it to test_22.txt, after write and append.
(3) The maximum it can go is 65535.
(4) If test_65535.txt exists, create another new file and named it test_65535_1.txt, and write something to it.
If test_65535_20.txt exists, renamed it to test_65535_21.txt, after write and append.
(4) If test_65535_65535.txt exists, create another new file and named it test_65535_65535_1.txt, and write something to it.
If test_65535_65535_38.txt exists, renamed it to test_65535_65535_39.txt, after write and append.
And the loops goes on and on...
I would appreciate if some test codes are given.
thanks.

8 answers
Provided that there will never be more than one file in the directory whose name satisfies the pattern, this code should work:
answered 2 years ago by:
17279
494
hi Vulpes, thank very much for your code. Could you explain those numbers 4 and 5: int last = currentName.Length - 4; is the number 4 due to the text 'test'? how about first+5 ? Could we code the number 4 and 5 to be more generic? as I would need to replace "test_123.txt" with other like "payload_123.setl"
also, when I tested with a file with payload_65535.setl existing in the directory, when the above code is executed, that existing file is appended and renamed to payload_65535_1.setl. That is not what I want.
I want to keep the existing payload_65535.setl file as it is, and create a brand new file with filename payload_65535_1.setl
thanks in advance, vulpes
answered 2 years ago by:
494
Sorry, I didn't read the instructions properly :(
I'll try again and also make it more generic:
answered 2 years ago by:
17279
494
thank you very much Vulpes for your wonderful and neat codes... could I confirm with you that first + 5 is due to the length of the extension ".setl" ?
17279
That's strange - I thought I'd commented on that point but the comment seems to have disappeared! Anyway, when first + 5 is used, we know that the number preceding the extension is 65535 and 'first' corresponds to the index of its first digit. As we're now going to add '_1' to that we need to jump over the 65535 and so we add 5 to 'first'.
494
I understood now. thanks once again.
hi Vulpes, for your existing code, it works well. Now, I want to save the same set of data in both the local drive, as well as the network drive in the server. How do I do it? I could not get it saved to my server drive directory created. thanks.
DateTime dt = DateTime.Now;
string yyyyMMdd = String.Format("{0:yyyyMMdd}", dt);
// to save the same set of data on the server
DirectoryInfo dir = new DirectoryInfo(@"\\192.168.1.101\\D$\\SharedFolder");
try
{
dir.CreateSubdirectory("test");
dir.CreateSubdirectory(@String.Concat(@"test\payload_", yyyyMMdd));
}
catch (IOException e)
{
Console.WriteLine(e.Message);
}
answered one year ago by:
494
I think the problem lies with this line:
When you use a backslash in a C# string, you either need to double it or precede the string with an @ sign but not both. Now, you're doing both, so if you make all backslashes after the first (as it's followed by an IP address) single backslashes then it should work:
answered one year ago by:
17279
hi Vulpes,
The below code is able to write to both local drive, as well as the remote drive. I want to include the yyyyMMdd string to the directory for the remote drive, but it does not seem to work. Why?
// string dirName_Server = @String.Concat("\\192.168.1.101\\D$\\SharedFolder\\test\\payload_", yyyyMMdd); // not ok
using System;
using System.IO;
class Program
{
static void Main()
{
// set these variables first
DateTime dt = DateTime.Now;
string yyyyMMdd = String.Format("{0:yyyyMMdd}", dt);
string dirName = @String.Concat("D:\\test\\payload_", yyyyMMdd);
string dirName_Server = @"\\192.168.1.101\D$\SharedFolder\test\payload"; // ok
// string dirName_Server = @String.Concat("\\192.168.1.101\\D$\\SharedFolder\\test\\payload_", yyyyMMdd); // not ok
string firstName = "payload_1.setl";
string filter = "payload_*.setl";
string extension = ".setl"; // including the dot
DirectoryInfo di = Directory.CreateDirectory(dirName); // create the directory.
DirectoryInfo di_Server = Directory.CreateDirectory(dirName_Server); // create the directory.
string[] fileNames = Directory.GetFiles(dirName, filter);
string[] fileNames_Server = Directory.GetFiles(dirName_Server, filter);
StreamWriter sw = null;
StreamWriter sw1 = null;
if (fileNames.Length == 0 | fileNames_Server.Length==0)
{
sw = new StreamWriter(dirName + "\\" + firstName);
sw.WriteLine("Something"); // or whatever
sw.Close();
sw1 = new StreamWriter(dirName_Server + "\\" + firstName);
sw1.WriteLine("Something"); // or whatever
sw1.Close();
}
else
{
string currentName = null;
string currentName_Server = null;
if (fileNames.Length == 1 | fileNames_Server.Length==1)
{
currentName = fileNames[0];
currentName_Server = fileNames_Server[0];
}
else
{
// get longest file name which will be current one
int maxLen = fileNames[0].Length;
int maxLen_Server = fileNames_Server[0].Length;
int maxIndex = 0;
int maxIndex_Server = 0;
for (int i = 1; i < fileNames.Length; i++)
{
if (maxLen < fileNames[i].Length)
{
maxLen = fileNames[i].Length;
maxIndex = i;
}
}
for (int i = 1; i < fileNames_Server.Length; i++)
{
if (maxLen_Server < fileNames_Server[i].Length)
{
maxLen_Server = fileNames_Server[i].Length;
maxIndex_Server = i;
}
}
currentName = fileNames[maxIndex];
currentName_Server = fileNames_Server[maxIndex_Server];
}
int first = currentName.LastIndexOf("_") + 1;
int last = currentName.Length - extension.Length;
int number = int.Parse(currentName.Substring(first, last - first));
string newName;
int first_Server = currentName_Server.LastIndexOf("_") + 1;
int last_Server = currentName_Server.Length - extension.Length;
int number_Server = int.Parse(currentName_Server.Substring(first_Server, last_Server - first_Server));
string newName_Server;
if (number < 65535 | number_Server < 65535)
{
++number; ++number_Server;
newName = currentName.Substring(0, first) + number.ToString() + extension;
newName_Server = currentName_Server.Substring(0, first_Server) + number_Server.ToString() + extension;
sw = new StreamWriter(currentName, true); // append mode
sw.WriteLine("Something else"); // or whatever
sw.Close();
sw1 = new StreamWriter(currentName_Server, true); // append mode
sw1.WriteLine("Something else"); // or whatever
sw1.Close();
File.Move(currentName, newName); // rename
File.Move(currentName_Server, newName_Server); // rename
}
else
{
newName = currentName.Substring(0, first + 5) + "_1" + extension;
// create new file
sw = new StreamWriter(newName);
sw.WriteLine("Something new"); // or whatever
sw.Close();
newName_Server = currentName_Server.Substring(0, first_Server + 5) + "_1" + extension;
sw1 = new StreamWriter(newName_Server);
sw1.WriteLine("Something new"); // or whatever
sw1.Close();
}
}
}
}
answered one year ago by:
494
The first few lines of code should be:
A couple of further points:
1. There's no need to precede String.Concat with an @ sign, even if it's concatenating verbatim strings. The compiler just ignores it and it looks strange to anyone reading the code.
2. Unless you're doing bit arithmetic, you should normally use the conditional operators (&&, ||) rather than their logical equivalents (&, |). This is because the former don't bother evaluating the second operand unless it might make a difference to the value of the whole expression, which saves clock cycles.
The only case where you wouldn't do this is if the evaluation of the second operand has side effects (say, it's the result of a method call) which you're relying on though, IMO, this is seldom good practice.
answered one year ago by:
17279
thank you Vulpes for your help and comments, it is useful. :)
answered one year ago by:
494