|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Calling FileStream.Create after File.Move gets old file handleHave a question regarding File.Move / FileStreams My steps, 1. Create file1 demo.log [FileMode.CreateNew] 2. Move file to demo1.log 3. Create file2 with same name as in #1: demo.log [FileMode.CreateNew] Now, problem is that the filehandle in #1 and #3 are the same. Are they expected to be? I suspect this is the reason why file2 inherits the CreateDate from file1 which is my main problem :-/ Can anyone please enlighten me what is going on? Cheers Sample code ================================== using System; using System.Collections.Generic; using System.Text; using System.IO; namespace FileMoveIssue { class Program { static void Main(string[] args) { RecycleLogFile(); } /// <summary> Illustreates how FileStream.Create after File.Move gets old file handle</summary> public static void RecycleLogFile() { string path = Path.GetTempPath(); string fileName = "demo"; string extension = ".log"; FileStream fs0 = null; if (File.Exists(path + fileName + extension)) File.Delete(path + fileName + extension); if (File.Exists(path + fileName + "1" + extension)) File.Delete(path + fileName + "1" + extension); fs0 = new FileStream(path + fileName + extension, FileMode.CreateNew, FileAccess.Write, FileShare.Read); DateTime file1CreationDate = DateTime.Now.AddDays(-2); int fileHandle1 = fs0.Handle.ToInt32(); fs0.Close(); File.SetCreationTime(fs0.Name, file1CreationDate); //creation time should be unique per file //move file demo.log -> demo1.log File.Move(fs0.Name, path + fileName + "1" + extension); if (File.Exists(fs0.Name)) { Console.WriteLine("File should Not exist it has been moved"); return; } FileStream fs1 = new FileStream(path + fileName + extension, FileMode.CreateNew, FileAccess.Write, FileShare.Read); int fileHandle2 = fs1.Handle.ToInt32(); Console.WriteLine("filehandle1==filehandle2 {0} filehandle1 {1} filehandle2 {2}", fileHandle1 == fileHandle2, fileHandle1, fileHandle2); DateTime file2CreationDate = File.GetCreationTime(fs1.Name); Console.WriteLine("file1.CreationDate== file1.CreationDate {0} ", file1CreationDate == file2CreationDate); if (fs0 != null) fs0.Close(); if (fs1 != null) fs1.Close(); Console.ReadLine(); } } } Anyone?
If this can be replicated it seems like a bug to me.. Show quote "C# Dev" wrote: > Greetings all, > > Have a question regarding File.Move / FileStreams > > My steps, > 1. Create file1 demo.log [FileMode.CreateNew] > 2. Move file to demo1.log > 3. Create file2 with same name as in #1: demo.log [FileMode.CreateNew] > > Now, problem is that the filehandle in #1 and #3 are the same. > Are they expected to be? > > I suspect this is the reason why file2 inherits the CreateDate from file1 > which is my main problem :-/ > > Can anyone please enlighten me what is going on? > > Cheers > > Sample code > ================================== > using System; > using System.Collections.Generic; > using System.Text; > using System.IO; > > namespace FileMoveIssue > { > class Program > { > static void Main(string[] args) > { > RecycleLogFile(); > } > > /// <summary> Illustreates how FileStream.Create after File.Move > gets old file handle</summary> > public static void RecycleLogFile() > { > > string path = Path.GetTempPath(); > string fileName = "demo"; > string extension = ".log"; > FileStream fs0 = null; > > if (File.Exists(path + fileName + extension)) > File.Delete(path + fileName + extension); > > if (File.Exists(path + fileName + "1" + extension)) > File.Delete(path + fileName + "1" + extension); > > fs0 = new FileStream(path + fileName + extension, > FileMode.CreateNew, FileAccess.Write, FileShare.Read); > DateTime file1CreationDate = DateTime.Now.AddDays(-2); > int fileHandle1 = fs0.Handle.ToInt32(); > fs0.Close(); > > File.SetCreationTime(fs0.Name, file1CreationDate); //creation > time should be unique per file > > //move file demo.log -> demo1.log > File.Move(fs0.Name, path + fileName + "1" + extension); > > if (File.Exists(fs0.Name)) > { > Console.WriteLine("File should Not exist it has been moved"); > return; > } > > FileStream fs1 = new FileStream(path + fileName + extension, > FileMode.CreateNew, FileAccess.Write, FileShare.Read); > int fileHandle2 = fs1.Handle.ToInt32(); > > Console.WriteLine("filehandle1==filehandle2 {0} filehandle1 {1} > filehandle2 {2}", fileHandle1 == fileHandle2, fileHandle1, fileHandle2); > DateTime file2CreationDate = File.GetCreationTime(fs1.Name); > > Console.WriteLine("file1.CreationDate== file1.CreationDate {0} > ", file1CreationDate == file2CreationDate); > > if (fs0 != null) > fs0.Close(); > > if (fs1 != null) > fs1.Close(); > > Console.ReadLine(); > } > } > } > > > C# Dev wrote:
Show quote > "C# Dev" wrote: I've managed to repeat this, using VB.Net. I believe it may be a> > > Greetings all, > > > > Have a question regarding File.Move / FileStreams > > > > My steps, > > 1. Create file1 demo.log [FileMode.CreateNew] > > 2. Move file to demo1.log > > 3. Create file2 with same name as in #1: demo.log [FileMode.CreateNew] > > > > Now, problem is that the filehandle in #1 and #3 are the same. > > Are they expected to be? > > > > I suspect this is the reason why file2 inherits the CreateDate from file1 > > which is my main problem :-/ > > > > Can anyone please enlighten me what is going on? > > > > Cheers > > > Anyone? > > If this can be replicated it seems like a bug to me.. > windows filesystem "feature". I cannot find a reference for it, but I believe it's been done like this to support scenarios where an application is about to write out an updated copy of a file, but wants to support being able to retrieve the "old" version, if there's a problem during the write. Obviously, you cannot overwrite the existing file, so you have to rename it first, and then write out the new version using the old filename. And then windows (I believe. Might be .Net, but I suspect windows) steps in and says "Aha! This is obviously just an updated copy of the file that's just been moved, it should inherit some meta-data, such as the creation date (and permissions)". I think it's done on a per-process basis (so if one process renames a file, and another writes the new one, it will not inherit the meta data). Now, final two bits. First, they have the same handle because the first free handle is obtained when you open the file, and then is freed by the Close() call, so that when you come to open the second file, it finds the first free handle (which happens to be the same handle previously used). Had you reopened the moved file (for reading say), before you had created the second file, you'd have probably had different handle values. Secondly, if you need the new file to have the correct creation datetime, I think you'll need to open it twice. Create it, Close it, Call SetCreationTime, then open it for writing. Damien Damien wrote:
Show quote > C# Dev wrote: Found it in MSDN, under CreateFile in Platform SDK, Storage. CreateFile> > "C# Dev" wrote: > > > > > Greetings all, > > > > > > Have a question regarding File.Move / FileStreams > > > > > > My steps, > > > 1. Create file1 demo.log [FileMode.CreateNew] > > > 2. Move file to demo1.log > > > 3. Create file2 with same name as in #1: demo.log [FileMode.CreateNew] > > > > > > Now, problem is that the filehandle in #1 and #3 are the same. > > > Are they expected to be? > > > > > > I suspect this is the reason why file2 inherits the CreateDate from file1 > > > which is my main problem :-/ > > > > > > Can anyone please enlighten me what is going on? > > > > > > Cheers > > > > > Anyone? > > > > If this can be replicated it seems like a bug to me.. > > > I've managed to repeat this, using VB.Net. I believe it may be a > windows filesystem "feature". I cannot find a reference for it, but I > believe it's been done like this to support scenarios where an > application is about to write out an updated copy of a file, but wants > to support being able to retrieve the "old" version, if there's a > problem during the write. > > Obviously, you cannot overwrite the existing file, so you have to > rename it first, and then write out the new version using the old > filename. And then windows (I believe. Might be .Net, but I suspect > windows) steps in and says "Aha! This is obviously just an updated copy > of the file that's just been moved, it should inherit some meta-data, > such as the creation date (and permissions)". I think it's done on a > per-process basis (so if one process renames a file, and another writes > the new one, it will not inherit the meta data). > is the Win32 call underneath the framework functionality. On the 2003 version, the link is ms-help://MS.MSDNQTR.2003FEB.1033/fileio/base/createfile.htm If you look down below the Remarks section, there is a section for each type of item that can be accessed using CreateFile. In the Files section, the fourth paragraph has: --Start quote If you rename or delete a file, then restore it shortly thereafter, the system searches the cache for file information to restore. Cached information includes its short/long name pair and creation time. --End Quote So, that's what you're getting. Damien Ok.
Although I don't agree with this as a preferred behaviour it certainly sheds some light of what is going on. And that is what I need to proceed :-) Thank you. Show quote "Damien" wrote: > Damien wrote: > > C# Dev wrote: > > > "C# Dev" wrote: > > > > > > > Greetings all, > > > > > > > > Have a question regarding File.Move / FileStreams > > > > > > > > My steps, > > > > 1. Create file1 demo.log [FileMode.CreateNew] > > > > 2. Move file to demo1.log > > > > 3. Create file2 with same name as in #1: demo.log [FileMode.CreateNew] > > > > > > > > Now, problem is that the filehandle in #1 and #3 are the same. > > > > Are they expected to be? > > > > > > > > I suspect this is the reason why file2 inherits the CreateDate from file1 > > > > which is my main problem :-/ > > > > > > > > Can anyone please enlighten me what is going on? > > > > > > > > Cheers > > > > > > > Anyone? > > > > > > If this can be replicated it seems like a bug to me.. > > > > > I've managed to repeat this, using VB.Net. I believe it may be a > > windows filesystem "feature". I cannot find a reference for it, but I > > believe it's been done like this to support scenarios where an > > application is about to write out an updated copy of a file, but wants > > to support being able to retrieve the "old" version, if there's a > > problem during the write. > > > > Obviously, you cannot overwrite the existing file, so you have to > > rename it first, and then write out the new version using the old > > filename. And then windows (I believe. Might be .Net, but I suspect > > windows) steps in and says "Aha! This is obviously just an updated copy > > of the file that's just been moved, it should inherit some meta-data, > > such as the creation date (and permissions)". I think it's done on a > > per-process basis (so if one process renames a file, and another writes > > the new one, it will not inherit the meta data). > > > Found it in MSDN, under CreateFile in Platform SDK, Storage. CreateFile > is the Win32 call underneath the framework functionality. > > On the 2003 version, the link is > ms-help://MS.MSDNQTR.2003FEB.1033/fileio/base/createfile.htm > > If you look down below the Remarks section, there is a section for each > type of item that can be accessed using CreateFile. In the Files > section, the fourth paragraph has: > > --Start quote > If you rename or delete a file, then restore it shortly thereafter, the > system searches the cache for file information to restore. Cached > information includes its short/long name pair and creation time. > --End Quote > > So, that's what you're getting. > > Damien > > |
|||||||||||||||||||||||