Calling FileStream.Create after File.Move gets old file handle

G

Guest

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();
}
}
}
 
D

Damien

C# Dev said:
C# Dev said:
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).

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
 
D

Damien

Damien said:
C# Dev said:
C# Dev said:
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
 
G

Guest

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.

Damien said:
Damien said:
C# Dev said:
:

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top