I am not sure if this is the reason why its throwing error. But for me the test where I perform the File.Replace with files residing in different directories failed. Just want to know if this is the case with others too.
[TestMethod]
public void TestFileReplaceDifferentDirectory()
{
string FileToReplace = #"c:\tools\file2.txt";
string FileToDelete = #"D:\DropFolder\file0.txt";
string strToWrite;
using (var wtr = File.CreateText(FileToDelete))
{
long ticks = DateTime.Now.Ticks;
strToWrite = string.Join(",", ticks, ticks, ticks);
wtr.WriteLine(strToWrite);
wtr.Flush();
wtr.Close();
}
string BackupFileName = Path.Combine(
Path.GetDirectoryName(FileToReplace),
string.Format("{0}_{1}{2}",
Path.GetFileNameWithoutExtension(FileToReplace),
DateTime.Now.Ticks,
Path.GetExtension(FileToReplace))
);
File.Replace(FileToDelete, FileToReplace, BackupFileName, false);
using (StreamReader rdr = new StreamReader(FileToReplace))
{
string line = rdr.ReadLine();
Assert.AreEqual(strToWrite, line);
}
}
[TestMethod]
public void TestFileReplaceSameDirectory()
{
string FileToReplace = #"c:\tools\file2.txt";
string FileToDelete = #"c:\tools\file0.txt";
string strToWrite;
using (var wtr = File.CreateText(FileToDelete))
{
long ticks = DateTime.Now.Ticks;
strToWrite = string.Join(",", ticks, ticks, ticks);
wtr.WriteLine(strToWrite);
wtr.Flush();
wtr.Close();
}
string BackupFileName = Path.Combine(
Path.GetDirectoryName(FileToReplace),
string.Format("{0}_{1}{2}",
Path.GetFileNameWithoutExtension(FileToReplace),
DateTime.Now.Ticks,
Path.GetExtension(FileToReplace))
);
File.Replace(FileToDelete, FileToReplace, BackupFileName, false);
using (StreamReader rdr = new StreamReader(FileToReplace))
{
string line = rdr.ReadLine();
Assert.AreEqual(strToWrite, line);
}
}
I was trying to write to a temporary file (using Path.GetTempFileName()) and replace a file in D:\DropFolder. It wasn't happening; it threw an System.IO.Exception
So does this mean my only option is to create a kind of temporary file in the same directory as that of FileToReplace and carry out this task?
This is by design. The point of using File.Replace() is to be able to replace a file that's locked by another process. Very important if you have just one shot at saving precious data, common at machine shutdown or unexpected program termination. Needless to say, that does takes a trick or two since Windows is adamant about stopping you from overwriting a locked file.
It is possible at all because the operating system only puts a lock on the file data but not on the directory entry for a file. In other words, it is valid to rename the file, even though it is locked. The underlying system call is the same as File.Move().
Which operates two distinct ways, depending on the destFileName. If the destination path is on the same drive, the file system merely has to move the directory entry. Very fast and trouble-free. But that cannot work if it is not on the same drive, that requires moving the file data as well. Which is of course slow and not possible at all in a scenario where the file data is locked.
It is therefore imperative that the destinationBackupFileName argument you pass to File.Replace() is a path that's on the same drive as sourceFileName. Not doing this causes the exception when the move fails. Not otherwise hard to do in general, boilerplate is to make the backup filename simply the same as the source filename with, say, ".bak" appended to the path.
Related
I need to create a file, write one line of text in the file and then delete the file and estimate how long it will take to do it.
Unfortunately, I am running in couple of problems, first I cannot write in the file, it succesfully creates it but nothing is written to it.
Secondly, I cannot delete the file because it has been used by another process.
Please help.
I have been trying to delete it for quite some time.
I have also tried wrapping it in usings, to no avail.
Writing to the file is the same situation. I even changed it so the file ends in .txt but that does not make any difference.
public static void ProcessFile(string path)
{
string fullpath = path;
int lastBracket = path.LastIndexOf("\\");
// the filename does not contain .html so it can be named to .txt
string newFileName = path.Substring(lastBracket + 1, path.Length - lastBracket - 6) + " hrefcount.txt";
string newPath = Path.Combine(fullpath.Substring(0, lastBracket), newFileName);
Console.WriteLine(newPath);
int counter = 0;
foreach (var line in File.ReadAllLines(path))
{
if (line.Contains("href="))
{
counter++;
}
}
var fileCreated = File.CreateText(newPath);
fileCreated.WriteLine("The number of times href appears is " + counter);
Console.WriteLine();
File.Delete(newPath);
}
File created, nothing written to it, unable to delete due to has been used by another process.
Instead of File.CreateText() use File.WriteAllText(path, content). It writes the text and then closes the file allowing you to delete it if necessary
Instead of the following
var fileCreated = File.CreateText(newPath);
fileCreated.WriteLine("The number of times href appears is " + counter);
You may write
File.WriteAllText(newPath, $"The number of times href appears is {counter}");
Refer documentation here
The issue with your approach is that CreateText() is used to write to a stream. But in your case, it is not necessary since you're writing all the text at once to the file and that text is small in size.
The cause of your error is the fact that you don't close and dispose the variable fileCreated. This, is a FileStream and until you close and dispose this variable the file is not available to anyone, even your own code that has opened the file.
So the first thing to do is
using (var fileCreated = File.CreateText(newPath))
{
fileCreated.WriteLine("The number of times href appears is " + counter);
}
The using block ensure the proper disposal of the variable.
However there are other parts of your code that you can simplify
public static void ProcessFile(string path)
{
string folder = Path.GetDirectoryName(path);
string file = Path.GetFileName(path);
// Keep the first 6 characters from the source file?
string newFile = file.Substring(0, 6) + " hrefcount.txt";
string newPath = Path.Combine(folder, newFile);
// A single line to retrieve your counter thanks to IEnumerables and Linq
int counter = File.ReadLines(path).Count(x => x.Contains("href="));
// Create, but dispose also the file
using (var fileCreated = File.CreateText(newPath))
{
fileCreated.WriteLine("The number of times href appears is " + counter);
}
// Now you should be free to delete the file
File.Delete(newPath);
}
I cannot delete the file because it has been used by another process.
Probably you're not disposed your files after creating. To do that, you should additionally use FileStream.Dispose method:
File.Create(path).Dispose();
estimate how long it will take to do it
You can use System.Diagnostics.Stopwatch class to do that:
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
/*
do the magic
*/
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedMilliseconds);
You can use File.WriteAllText method instead of File.CreateText to write your text to file:
File.WriteAllText(path, myText);
Remember that since the .NET 4 you can use this method with array or List<T> too instead of string.
File.Create() supports Dispose method which help you to release that file resource to perform further operations
To perform operations on file follow below steps:
Create file and free up the resource using Dispose().
File.Create(newPath).Dispose();
or Use StreamWriter to create file and write text to it.
using( StreamWriter sw = new StreamWriter(newPath, true)
{
sw.Write($"The number of times href appears is {counter}"); //Used string interpolation
}
StreamWriter calls Dispose() function to release file resource.
When Writer release control over file, then you will not face issue related to I cannot delete the file because it has been used by another process.
Now you can delete file using,
File.Delete(newPath);
MSDN : IDisposable.Dispose Method
Performs application-defined tasks associated with freeing, releasing,
or resetting unmanaged resources.
Using this article from MSDN, I'm trying to search through files in a directory. The problem is, every time I execute the program, I get:
"An unhandled exception of type 'System.OutOfMemoryException' occurred in mscorlib.dll".
I have tried to some other options like StreamReader, but I can't get it to work. These files are HUGE. Some of them range in upwards to 1.5-2GB each and there could be 5 or more files per day.
This code fails:
private static string GetFileText(string name)
{
var fileContents = string.Empty;
// If the file has been deleted since we took
// the snapshot, ignore it and return the empty string.
if (File.Exists(name))
{
fileContents = File.ReadAllText(name);
}
return fileContents;
}
Any ideas what could be happening or how to make it read without memory errors?
Entire code (in case you don't want to open the MSDN article)
class QueryContents {
public static void Main()
{
// Modify this path as necessary.
string startFolder = #"c:\program files\Microsoft Visual Studio 9.0\";
// Take a snapshot of the file system.
System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(startFolder);
// This method assumes that the application has discovery permissions
// for all folders under the specified path.
IEnumerable<System.IO.FileInfo> fileList = dir.GetFiles("*.*", System.IO.SearchOption.AllDirectories);
string searchTerm = #"Visual Studio";
// Search the contents of each file.
// A regular expression created with the RegEx class
// could be used instead of the Contains method.
// queryMatchingFiles is an IEnumerable<string>.
var queryMatchingFiles =
from file in fileList
where file.Extension == ".htm"
let fileText = GetFileText(file.FullName)
where fileText.Contains(searchTerm)
select file.FullName;
// Execute the query.
Console.WriteLine("The term \"{0}\" was found in:", searchTerm);
foreach (string filename in queryMatchingFiles)
{
Console.WriteLine(filename);
}
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
// Read the contents of the file.
static string GetFileText(string name)
{
string fileContents = String.Empty;
// If the file has been deleted since we took
// the snapshot, ignore it and return the empty string.
if (System.IO.File.Exists(name))
{
fileContents = System.IO.File.ReadAllText(name);
}
return fileContents;
}
}
The problem you're having is based on trying to load multiple gigabytes of text at the same time. If they're text files, you can stream them and just compare one line at a time.
var queryMatchingFiles =
from file in fileList
where file.Extension == ".htm"
let fileLines = File.ReadLines(file.FullName) // lazy IEnumerable<string>
where fileLines.Any(line => line.Contains(searchTerm))
select file.FullName;
I would suggest that you are getting an out of memory error because the way the query is written I believe that you will need to load the entire text of every file into memory and none of the objects can be released until the entire file set has been loaded. Could you not check for the search term in the GetFileText function and then just return a true or false?
If you did that the file text at least falls out of scope at the end of the function and the GC can recover the memory. It would actually be better to rewrite as a streaming function if you are dealing with large files/amounts then you could exit your reading early if you come across the search term and you wouldn't need the entire file in memory all the time.
Previous question on finding a term in an HTML file using a stream
I have a 'safe' config file saving routine that tries to be atomic when writing user config data to the disk, avoiding disk caching etc.
The code goes something like this:
public static void WriteAllTextSafe(string path, string contents)
{
// generate a temp filename
var tempPath = Path.GetTempFileName();
// create the backup name
var backup = path + ".backup";
// delete any existing backups
if (File.Exists(backup))
File.Delete(backup);
// get the bytes
var data = Encoding.UTF8.GetBytes(contents);
if (File.Exists(path))
{
// write the data to a temp file
using (var tempFile = File.Create(tempPath, 4096, FileOptions.WriteThrough))
tempFile.Write(data, 0, data.Length);
// replace the contents
File.Replace(tempPath, path, backup, );
}
else
{
// if the file doesn't exist we can't replace so just write it
using (var tempFile = File.Create(path, 4096, FileOptions.WriteThrough))
tempFile.Write(data, 0, data.Length);
}
}
On most systems this works perfectly and I have not had any reports of issues, but for some users each time my program calls this function they get the following error:
System.IO.IOException: 置換するファイルを置換されるファイルに移動できません。置換されるファイルの名前は、元のままです。
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.File.InternalReplace(String sourceFileName, String destinationFileName, String destinationBackupFileName, Boolean ignoreMetadataErrors)
at download.ninja.BO.FileExtensions.WriteAllTextSafe(String path, String contents)
at download.ninja.BO.FileExtensions.SaveConfig(String path, Object toSave)
After a bit of investigation and with the help of Google Translate I've found that the actual error is thrown from the wine32 ReplaceFile function:
ERROR_UNABLE_TO_MOVE_REPLACEMENT 1176 (0x498)
The replacement file could not be renamed. If lpBackupFileName was specified, the replaced and
replacement files retain their original file names. Otherwise, the replaced file no longer exists
and the replacement file exists under its original name.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365512(v=vs.85).aspx
The problem is that I have no idea why Windows is throwing this error.. I have tried setting the file to readonly locally but that throws an Unauthorized exception rather than a IOException so I don't believe that is causing the problem.
My second guess is that the the is somehow locked, but I only have one read function that is used for reading all config files and that should be closing off all file handles when it finsihes
public static T LoadJson<T>(string path)
{
try
{
// load the values from the file
using (var r = new StreamReader(path))
{
string json = r.ReadToEnd();
T result = JsonConvert.DeserializeObject<T>(json);
if (result == null)
return default(T);
return result;
}
}
catch (Exception)
{
}
return default(T);
}
I have also tried throwing fake exceptions in the LoadJson function to try and lock the file but I can't seem to do it.
Even then I have tried simulating a file lock by opening the file in a different process and running the save code while it is still open, and that generates a different (expected) error:
System.IO.IOException: The process cannot access the file because it is being used by another process.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.File.InternalReplace(String sourceFileName, String destinationFileName, String destinationBackupFileName, Boolean ignoreMetadataErrors)
at download.ninja.BO.FileExtensions.WriteAllTextSafe(String path, String contents)
So the question is.. what is causing Windows to throw this ERROR_UNABLE_TO_MOVE_REPLACEMENT error on some systems
NOTE: This error is thrown EVERY TIME my program attempt to replace the file on an affected machine.. not just occasionally.
OK, so found the problem. It seems that files passed into ReplaceFile must be on the SAME DRIVE
In this case the user had changed their temp folder to d:\tmp\
So File.Replace looked something like this:
File.Replace(#"D:\tmp\sometempfile", #"c:\AppData\DN\app-config", #"c:\AppData\DN\app-config.backup");
This difference in drives between the source file and the desitnation file in File.Replace seems to be what caused the problem.
I have modified my WriteAllTextSafe function as follows and my user reports the problem has been resolved!
public static void WriteAllTextSafe(string path, string contents)
{
// DISABLED: User temp folder might be on different drive
// var tempPath = Path.GetTempFileName();
// use the same folder so that they are always on the same drive!
var tempPath = Path.Combine(Path.GetDirectoryName(path), Guid.NewGuid().ToString());
....
}
As far as I can find there is no documentation stating that the two files need to be on the same drive but I can reproduce the problem by manually entering different drives (yet valid paths) into File.Replace
Are you by any chance, hardcoding drives in your file name, e.g. c:\ etc?
If you are, don't, they might not not work in runtimes where the locale is 1041 (japanese).
Instead use the framework to get the drive part and dynamically build your path.
string drivePath = System.IO.Path.GetPathRoot(System.Environment.SystemDirectory);
string somePath = string.Concat(drivePath, "someFolder\SomeFileName.Txt");
I've had the same problem working with source files on OneDrive copying to local files under %AppData%. A solution that worked well for me was to delete the destination file then perform a copy from the source.
Code that does not work:
file.replace(source,destination,backup,false)
Code that does work:
File.Delete(destination)
File.Copy(source, destination)
I am trying to create a torrent for the files in my desktop using monotorrent i have tried like the below code
i am able to get the byte code i am not able to save it as torrent it shows access denied
enter code here string path = "C:/Users/snovaspace12/Desktop/monotorrent-0.90/files";
string savepath = "D:/results";
TorrentCreator nnnn = new TorrentCreator();
nnnn.CreateTorrent(path, savepath);
public void CreateTorrent(string path, string savePath)
{
// The class used for creating the torrent
TorrentCreator c = new TorrentCreator();
// Add one tier which contains two trackers
//RawTrackerTier tier = new RawTrackerTier();
//tier.Add("http://localhost/announce");
//c.Announces.Add(tier);
c.Comment = "This is the comment";
c.CreatedBy = "Doug using " + VersionInfo.ClientVersion;
c.Publisher = "www.aaronsen.com";
// Set the torrent as private so it will not use DHT or peer exchange
// Generally you will not want to set this.
c.Private = true;
// Every time a piece has been hashed, this event will fire. It is an
// asynchronous event, so you have to handle threading yourself.
c.Hashed += delegate(object o, TorrentCreatorEventArgs e)
{
Console.WriteLine("Current File is {0}% hashed", e.FileCompletion);
Console.WriteLine("Overall {0}% hashed", e.OverallCompletion);
Console.WriteLine("Total data to hash: {0}", e.OverallSize);
};
// ITorrentFileSource can be implemented to provide the TorrentCreator
// with a list of files which will be added to the torrent metadata.
// The default implementation takes a path to a single file or a path
// to a directory. If the path is a directory, all files will be
// recursively added
ITorrentFileSource fileSource = new TorrentFileSource(path);
// Create the torrent file and save it directly to the specified path
// Different overloads of 'Create' can be used to save the data to a Stream
// or just return it as a BEncodedDictionary (its native format) so it can be
// processed in memory
c.Create(fileSource, savePath);
}
public void Create(ITorrentFileSource fileSource, string savePath)
{
Check.SavePath(savePath);
var file = Create(fileSource);//getting the fbyte code
File.WriteAllBytes( savePath, Create(fileSource).Encode()); //getting exception here
}
when i checked the byte code is returning properly to the file
it shows access is denied
You’ve probably solved this already but I just encountered the same issue. The solution, at least in my case, was pretty simple.
The problem originated with the savePath parameter in c.Create(fileSource, savePath);
I assumed savePath was a directory where the torrent would be saved. It should be a file path instead. For example savePath = “C:\pathtomytorrents\content.torrent”
Hopefully that works for you!
I need to generate a unique temporary file with a .csv extension.
What I do right now is
string filepath = System.IO.Path.GetTempFileName().Replace(".tmp", ".csv");
However, this doesn't guarantee that my .csv file will be unique.
I know the chances I ever got a collision are very low (especially if you consider that I don't delete the .tmp files), but this code doesn't looks good to me.
Of course I could manually generate random file names until I eventually find a unique one (which shouldn't be a problem), but I'm curious to know if others have found a nice way to deal with this problem.
Guaranteed to be (statistically) unique:
string fileName = System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".csv";
(To quote from the wiki article on the probabilty of a collision:
...one's annual risk of being hit by a
meteorite is estimated to be one
chance in 17 billion [19], that means
the probability is about 0.00000000006
(6 × 10−11), equivalent to the odds of
creating a few tens of trillions of
UUIDs in a year and having one
duplicate. In other words, only after
generating 1 billion UUIDs every
second for the next 100 years, the
probability of creating just one
duplicate would be about 50%. The
probability of one duplicate would be
about 50% if every person on earth
owns 600 million UUIDs
EDIT: Please also see JaredPar's comments.
Try this function ...
public static string GetTempFilePathWithExtension(string extension) {
var path = Path.GetTempPath();
var fileName = Path.ChangeExtension(Guid.NewGuid().ToString(), extension);
return Path.Combine(path, fileName);
}
It will return a full path with the extension of your choice.
Note, it's not guaranteed to produce a unique file name since someone else could have technically already created that file. However the chances of someone guessing the next guid produced by your app and creating it is very very low. It's pretty safe to assume this will be unique.
public static string GetTempFileName(string extension)
{
int attempt = 0;
while (true)
{
string fileName = Path.GetRandomFileName();
fileName = Path.ChangeExtension(fileName, extension);
fileName = Path.Combine(Path.GetTempPath(), fileName);
try
{
using (new FileStream(fileName, FileMode.CreateNew)) { }
return fileName;
}
catch (IOException ex)
{
if (++attempt == 10)
throw new IOException("No unique temporary file name is available.", ex);
}
}
}
Note: this works like Path.GetTempFileName. An empty file is created to reserve the file name. It makes 10 attempts, in case of collisions generated by Path.GetRandomFileName();
You can also alternatively use System.CodeDom.Compiler.TempFileCollection.
string tempDirectory = #"c:\\temp";
TempFileCollection coll = new TempFileCollection(tempDirectory, true);
string filename = coll.AddExtension("txt", true);
File.WriteAllText(Path.Combine(tempDirectory,filename),"Hello World");
Here I used a txt extension but you can specify whatever you want. I also set the keep flag to true so that the temp file is kept around after use. Unfortunately, TempFileCollection creates one random file per extension. If you need more temp files, you can create multiple instances of TempFileCollection.
The MSDN documentation for C++'s GetTempFileName discusses your concern and answers it:
GetTempFileName is not able to guarantee that the file name is unique.
Only the lower 16 bits of the uUnique parameter are used. This limits GetTempFileName to a maximum of 65,535 unique file names if the lpPathName and lpPrefixString parameters remain the same.
Due to the algorithm used to generate file names, GetTempFileName can perform poorly when creating a large number of files with the same prefix. In such cases, it is recommended that you construct unique file names based on GUIDs.
Why not checking if the file exists?
string fileName;
do
{
fileName = System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".csv";
} while (System.IO.File.Exists(fileName));
You can also do the following
string filepath = Path.ChangeExtension(Path.GetTempFileName(), ".csv");
and this also works as expected
string filepath = Path.ChangeExtension(Path.GetTempPath() + Guid.NewGuid().ToString(), ".csv");
How about:
Path.Combine(Path.GetTempPath(), DateTime.Now.Ticks.ToString() + "_" + Guid.NewGuid().ToString() + ".csv")
It is highly improbable that the computer will generate the same Guid at the same instant of time. The only weakness i see here is the performance impact DateTime.Now.Ticks will add.
In my opinion, most answers proposed here as sub-optimal. The one coming closest is the original one proposed initially by Brann.
A Temp Filename must be
Unique
Conflict-free (not already exist)
Atomic (Creation of Name & File in the same operation)
Hard to guess
Because of these requirements, it is not a godd idea to program such a beast on your own. Smart People writing IO Libraries worry about things like locking (if needed) etc.
Therefore, I see no need to rewrite System.IO.Path.GetTempFileName().
This, even if it looks clumsy, should do the job:
//Note that this already *creates* the file
string filename1 = System.IO.Path.GetTempFileName()
// Rename and move
filename = filename.Replace(".tmp", ".csv");
File.Move(filename1 , filename);
I mixed #Maxence and #Mitch Wheat answers keeping in mind I want the semantic of GetTempFileName method (the fileName is the name of a new file created) adding the extension preferred.
string GetNewTempFile(string extension)
{
if (!extension.StartWith(".")) extension="." + extension;
string fileName;
bool bCollisions = false;
do {
fileName = Path.Combine(System.IO.Path.GetTempPath(), Guid.NewGuid().ToString() + extension);
try
{
using (new FileStream(fileName, FileMode.CreateNew)) { }
bCollisions = false;
}
catch (IOException)
{
bCollisions = true;
}
}
while (bCollisions);
return fileName;
}
This could be handy for you... It's to create a temp. folder and return it as a string in VB.NET.
Easily convertible to C#:
Public Function GetTempDirectory() As String
Dim mpath As String
Do
mpath = System.IO.Path.Combine(System.IO.Path.GetTempPath, System.IO.Path.GetRandomFileName)
Loop While System.IO.Directory.Exists(mpath) Or System.IO.File.Exists(mpath)
System.IO.Directory.CreateDirectory(mpath)
Return mpath
End Function
This seems to work fine for me: it checks for file existance and creates the file to be sure it's a writable location.
Should work fine, you can change it to return directly the FileStream (which is normally what you need for a temp file):
private string GetTempFile(string fileExtension)
{
string temp = System.IO.Path.GetTempPath();
string res = string.Empty;
while (true) {
res = string.Format("{0}.{1}", Guid.NewGuid().ToString(), fileExtension);
res = System.IO.Path.Combine(temp, res);
if (!System.IO.File.Exists(res)) {
try {
System.IO.FileStream s = System.IO.File.Create(res);
s.Close();
break;
}
catch (Exception) {
}
}
}
return res;
} // GetTempFile
Based on answers I found from the internet, I come to my code as following:
public static string GetTemporaryFileName()
{
string tempFilePath = Path.Combine(Path.GetTempPath(), "SnapshotTemp");
Directory.Delete(tempFilePath, true);
Directory.CreateDirectory(tempFilePath);
return Path.Combine(tempFilePath, DateTime.Now.ToString("MMddHHmm") + "-" + Guid.NewGuid().ToString() + ".png");
}
And as C# Cookbook by Jay Hilyard, Stephen Teilhet pointed in Using a Temporary File in Your Application:
you should use a temporary file whenever you need to store
information temporarily for later retrieval.
The one thing you must remember is to delete this temporary file
before the application that created it is terminated.
If it is not deleted, it will remain in the user’s temporary
directory until the user manually deletes it.
This is what I am doing:
string tStamp = String.Format("{0:yyyyMMdd.HHmmss}", DateTime.Now);
string ProcID = Process.GetCurrentProcess().Id.ToString();
string tmpFolder = System.IO.Path.GetTempPath();
string outFile = tmpFolder + ProcID + "_" + tStamp + ".txt";
This is a simple but effective way to generate incremental filenames. It will look in the current directly (you can easily point that somewhere else) and search for files with the base YourApplicationName*.txt (again you can easily change that). It will start at 0000 so that the first file name will be YourApplicationName0000.txt. if for some reason there are file names with junk between (meaning not numbers) the left and right parts, those files will be ignored by virtue of the tryparse call.
public static string CreateNewOutPutFile()
{
const string RemoveLeft = "YourApplicationName";
const string RemoveRight = ".txt";
const string searchString = RemoveLeft + "*" + RemoveRight;
const string numberSpecifier = "0000";
int maxTempNdx = -1;
string fileName;
string [] Files = Directory.GetFiles(Directory.GetCurrentDirectory(), searchString);
foreach( string file in Files)
{
fileName = Path.GetFileName(file);
string stripped = fileName.Remove(fileName.Length - RemoveRight.Length, RemoveRight.Length).Remove(0, RemoveLeft.Length);
if( int.TryParse(stripped,out int current) )
{
if (current > maxTempNdx)
maxTempNdx = current;
}
}
maxTempNdx++;
fileName = RemoveLeft + maxTempNdx.ToString(numberSpecifier) + RemoveRight;
File.CreateText(fileName); // optional
return fileName;
}
Easy Function in C#:
public static string GetTempFileName(string extension = "csv")
{
return Path.ChangeExtension(Path.GetTempFileName(), extension);
}
In this what we can do we can first find the extension of file
which is coming from file and after finding its extension.Then we
can create the temprary name of file and after that we can change
extension by the previous one it will works.
var name = Path.GetTempFileName();
var changename = Path.GetFileName(name);
var fileName = Path.ChangeExtension(changename, fileExtension);
I think you should try this:
string path = Path.GetRandomFileName();
path = Path.Combine(#"c:\temp", path);
path = Path.ChangeExtension(path, ".tmp");
File.Create(path);
It generates a unique filename and creates a file with that file name at a specified location.