Writing to file by creating further files (and not replacing/overwriting) - c#

Is there any way to modify the following simple code, so that once the file myBackup.csv is created and the code is run over and over again, it doesn't just re-write the same file and destroy the previous contents, but creates further files?
string localPath = somePath + Path.DirectorySeparatorChar + "myBackup.csv";
StreamWriter sw = new StreamWriter( localPath );
sw.WriteLine( "blah blah:" );
foreach ( var element in entryId )
sw.WriteLine( element );
localSaver.Close();

So you want to check if the file exists and choose another file name if the file exists?
string localPath = somePath + Path.DirectorySeparatorChar + "myBackup.csv";
int counter = 1;
while (File.Exists(localPath))
{
localPath = somePath + Path.DirectorySeparatorChar + "myBackup-" + counter + ".csv";
counter++;
}
Then use localPath in your StreamWriter constructor.

Related

Increment file name by 1 if the file exists in c#

I am trying to increment the filename (e.g., "file1.csv", "file2.csv", etc.), each time a new file is generated. I followed this thread Increment the file name if the file already exists in c# but the solution is not useful for my case. What I want to do is check if the file exists in the first place and if it does write in it. If it doesn't create one and write. The problem is that if the file exists but it's from another user, I want the system to increment the file number and not write to the same file just because it exists. What I have so far:
public void saveFile()
{
int count = 0;
string title = "TimeStamp,Name,Trial,Time_spent-dist,Time_spent_tar\n";
string output = System.DateTime.Now.ToString("mm_ss_ffff") + "," +
currentScene.name.ToString() + "," +
trialNum.ToString() + "," +
timerDistractor.ToString() + "," +
timerTarget.ToString();
string fname = "User_" + count + ".csv";
string path = Path.Combine(Application.persistentDataPath, fname);
if (File.Exists(path))
{
File.AppendAllText(path, "\n" + output);
}
else
{
StreamWriter writer = new StreamWriter(path);
writer.WriteLine(title + "\n" + output);
writer.Close();
}
}
Any pointers?

How to remove last characters from a string

So I am writing a C# program which combines several text files into one and saves them as a combined text file. One issue I am having, I have a textfield which selects the intended folder the save the compiled reciept, however when selecting the desired folder, it generates a file name to the text box, the filename follwing the final / must be erased every time for the save function to work properly. I am wondering, how to remove all text after the final letter before the last / in the file directory?
Here is the code:
private void RecieptDisplayed_TextChanged(object sender, EventArgs e)
{
try
{
string[] fileAry = Directory.GetFiles(RecieptSelect.Text);
string input = RecieptSelect.Text;
int index = input.LastIndexOf("/");
if (index >= 0)
input = input.Substring(0, index);
MessageBox.Show("Reciepts being processed : " + index);
using (TextWriter tw = new StreamWriter(savefileas.Text + "RecieptsCombined.txt", true))
{
foreach (string filePath in fileAry)
{
using (TextReader tr = new StreamReader(filePath))
{
tw.WriteLine("Reciept for: " + " " + filePath + tr.ReadToEnd()) ;
tr.Close();
tr.Dispose();
}
MessageBox.Show("File Processed : " + filePath);
}
tw.Close();
tw.Dispose();
}
}
You have a string like
var fullpath = #"C:\temp\myfile.txt";
You can use:
var dir = Path.GetDirectoryName(fullpath);
To get
c:\temp
Note that if the path ends with a slash it doesn't remove it before "going up a directory" so c:\temp\ becomes c:\temp. Try to keep your paths free of trailing slashes
Try to always use the Path class when manipulating string that are paths. It has a whole load of useful methods (this isn't an exhaustive list but the ones I use most) like:
GetFileName
GetFileNameWithoutExtension
GetExtension
ChangeExtension
Combine
This last one builds paths, eg:
Path.Combine("c:", "temp", "myfile.txt");
It knows the different operating systems it runs on and builds paths appropriately - if you're using net core on Linux it uses "/" instead of "\" for example. full docs here
Construct a FileInfo object from the string and then use DirectoryName or Directory.
Also, do not concatenate strings to get a file name, use Path.Combine instead.
You are looking for Directory name from given path, you can use existing function to get the directory name, Path.GetDirectoryName()
using System.IO;
...
//Get the directory name
var directoryName = Path.GetDirectoryName(savefileas.Text);
using (TextWriter tw = new StreamWriter(Path.Combine(directoryName, "RecieptsCombined.txt"), true))
{
foreach (string filePath in fileAry)
{
using (TextReader tr = new StreamReader(filePath))
{
tw.WriteLine("Reciept for: " + " " + filePath + tr.ReadToEnd()) ;
tr.Close();
tr.Dispose();
}
MessageBox.Show("File Processed : " + filePath);
}
tw.Close();
tw.Dispose();
}

Versioning file name and saving it to different location

After the else block Path.Combine method combines every part and gives the file name when Console.WriteLine(result); is used. But it doesn't actually create the file with that name.
I want to get the EmployeeDetails.txt file, make a version of it (i.e. renaming the filename) and saves it to C:\Hitory folder.
How to achieve that?
Using File.Move throws FileNotFoundexception
void ModRec()
{
string filename = #"C:\Current\EmployeeDetails.txt";
string current = #"C:\Current\";
string history = #"C:\History\";
FileInfo fileinfo = new FileInfo(filename);
if (fileinfo.Exists)
{
if (!Directory.Exists(history))
{
Directory.CreateDirectory(history);
}
}
else
{
Console.WriteLine("\t\t\tFile doesn't exist!");
Console.ReadLine();
Menu1();
}
var extension = Path.GetExtension(filename);
var fileNamePart = Path.GetFileNameWithoutExtension(filename);
var path = Path.GetDirectoryName(filename);
var version = 0;
string result;
do
{
version++;
result = Path.Combine(path, fileNamePart + "_" + version + extension);
}
while (File.Exists(result));
//File.Move(current, history);
}
Your loop at the end needs to change slightly, because
result = Path.Combine(path, fileNamePart + "_" + version + extension);
is looking in the directory where the file already is, rather than in the history directory where you want it to be, so you'll be scanning for duplicates in the wrong location. The Path.Combine therefore needs to reference the value of history:
result = Path.Combine(history, fileNamePart + "_" + version + extension);
Secondly, you cannot use Move to move a file to a directory in the same way that you can from the command line, you need to specify the two parameters as filenames, so
File.Move(current, history);
becomes
File.Move(filename, result);
The resulting code at the end of your method should therefore look like this:
do
{
version++;
result = Path.Combine(history, fileNamePart + "_" + version + extension);
}
while (File.Exists(result));
File.Move(filename, result);
Incidentally, where you test whether the file already exists, you simply call Menu1 and then carry on. Can you guarantee that that will ensure that the next thing that the user does will create a valid file? I'm guessing that it most likely cannot guarantee that, so you should exit your method at that point, or perhaps put the remainder of the body inside the fileinfo.Exists block.
That leaves the desirability of invoking a menu from inside this method, but that's a design question outside of the scope of what you've asked here.
Try this instead:
void ModRec()
{
string filename = #"C:\Current\EmployeeDetails.txt";
string current = #"C:\Current\";
string history = #"C:\History\";
FileInfo fileinfo = new FileInfo(filename);
if (fileinfo.Exists)
{
if (!Directory.Exists(history))
{
Directory.CreateDirectory(history);
}
}
else
{
Console.WriteLine("\t\t\tFile doesn't exist!");
Console.ReadLine();
Menu1();
}
var extension = Path.GetExtension(filename);
var fileNamePart = Path.GetFileNameWithoutExtension(filename);
var path = Path.GetDirectoryName(filename);
var version = 0;
string result;
do
{
version++;
result = Path.Combine(history, fileNamePart + "_" + version + extension);
}
while (File.Exists(result));
File.Move(filename, result);
}
Path.Combine() does not touch filesystem at all. No files/folders would be ever crated.
Try File.Move(filename, history);. That is, instead of current, which is a directory, move the file (assuming filename is a full path).

How to save data from form in a specific drive

I want to save my text file in a F drive but this file is written to a default folder of program . How to save it by guiding a path
string[] contents = new string[2];
contents[0] = "Name: " + textBox1.Text;
contents[1] = "age: " + textBox2.Text;
string path = #"F:\\"; // path to file
System.IO.File.WriteAllLines(textBox1.Text + ".txt", contents);
It would be a good idea to actually use your path variable:
string path = System.IO.Path.Combine(#"F:\", textBox1.Text + ".txt");
System.IO.File.WriteAllLines(path, contents);
Because you defining a path,but you don't use it.
string path = #"F:\" + textBox1.Text + ".txt";
File.WriteAllLines(path, contents);
As an alternative, you can use File.Move after you created it like;
File.WriteAllLines(textBox1.Text + ".txt", contents);
File.Move(Directory.GetCurrentDirectory() + textBox1.Text + ".txt",
path + textBox1.Text + ".txt");

Adding DateTime to filename during rename

I have found lots of examples of people creating new files and adding the current Datetime then the file extension but what I want to do is look to see if a file currently exists and if it does simply add the current DateTime to the file name but I can't figure out how to maintain the file extension. My current code so far:
public class FileUploadHelper
{
private CoreSiteContext db = new CoreSiteContext();
public Int64 UploadSiteImage(string ContainerName, string NewFileName, HttpPostedFile UploadedFile)
{
string SavePath = #"F:\FFInfoImages\" + ContainerName + #"\";
if (System.IO.File.Exists(SavePath + NewFileName))
{
System.IO.File.Move(SavePath + NewFileName, SavePath + NewFileName + DateTime.Now.ToString("MM_dd_yyyy_hh_mm_ss"));
UploadedFile.SaveAs(SavePath + NewFileName);
}
else
{
UploadedFile.SaveAs(SavePath + NewFileName);
}
using (db)
{
File NewFile = new File()
{
FileName = NewFileName,
ContentType = UploadedFile.ContentType
};
db.Files.Add(NewFile);
db.SaveChanges();
return NewFile.ID;
}
}
}
Appears as if the NewFileName string variable does not get passed in with the filename extension, otherwise most of this should work. Why not get the extension from UploadedFile?
string strNewPath = SavePath + NewFileName + Path.GetExtension(UploadedFile.FileName);
if (System.IO.File.Exists(strNewPath)) {
System.IO.File.Move(strNewPath, SavePath + NewFileName + DateTime.Now.ToString("MM_dd_yyyy_hh_mm_ss") + Path.GetExtension(UploadedFile.FileName));
UploadedFile.SaveAs(strNewPath);
}
else {
UploadedFile.SaveAs(strNewPath);
}
using (db) {
File NewFile = new File() {
FileName = NewFileName + Path.GetExtension(UploadedFile.FileName),
ContentType = UploadedFile.ContentType
};
db.Files.Add(NewFile);
db.SaveChanges();
return NewFile.ID;
}
.NET has built-in methods for safely extracting the different portions of a file name (the file's name and it's extension, respectively). Path exists in the System.IO namespace.
Path.GetExtension
Path.GetFileNameWithoutExtension
Assuming NewFileName is something like myfilename.txt, you could use it like this (untested):
if (File.Exists(SavePath + NewFileName))
{
var name = Path.GetFileNameWithoutExtension(NewFileName);
var ext = Path.GetExtension(NewFileName);
File.Move(SavePath + NewFileName,
SavePath + name + DateTime.Now.ToString("MM_dd_yyyy_hh_mm_ss") + ext);
}
UploadedFile.SaveAs(SavePath + NewFileName);
The following method totally solves your problem
System.IO.Path.GetExtension("Path");
You'd better get the current file name without extension first using System.IO.Path.GetFileNameWithoutExtension("Path") then add the Date Time and then add up the extension anyway.
you can use Path.GetExtension() method to identify the file extension.
Try This:
String strExtension=IO.Path.GetExtension(SavePath + NewFileName);
if (System.IO.File.Exists(SavePath + NewFileName))
{
System.IO.File.Move(SavePath + NewFileName, SavePath + NewFileName + DateTime.Now.ToString("MM_dd_yyyy_hh_mm_ss")+strExtension);
UploadedFile.SaveAs(SavePath + NewFileName);
}
else
{
UploadedFile.SaveAs(SavePath + NewFileName);
}

Categories