safely copy files

  • Thread starter Thread starter MarkusR
  • Start date Start date
M

MarkusR

Good day,

I need to safely copy files from one directory to another. I need to
make sure that I do not lock the file making it unreadable by others.

I am not sure if this is the default behavior if I just used
File.Copy...

The files are relatively small.

For example, i can open up a file in notepad and someone else can edit
to it, rename it, delete it. Those operations are not affected by me
having it open in notepad.

Thanks for any advice.

-Markus_R
 
Markus,

If you are copying the file over, then you absolutely need to have the
file locked. If someone deletes the file in the middle of you copying it,
then you are going to corrupt the file when it is moved over (since you
won't be able to read it while copying).
 
I disagree and wouldn't say "absolutely". I can see scenarios where copying
should fall back if the file changes or is removed, such that copying is
cancelled and the half-copied file is removed if the file changed (was
locked for modification) or if the file was removed, and I could be mistaken
but I believe the Windows user shell is among such scenarios, both File
Explorer and XCopy.

Jon

Nicholas Paldino said:
Markus,

If you are copying the file over, then you absolutely need to have the
file locked. If someone deletes the file in the middle of you copying it,
then you are going to corrupt the file when it is moved over (since you
won't be able to read it while copying).


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

MarkusR said:
Good day,

I need to safely copy files from one directory to another. I need to
make sure that I do not lock the file making it unreadable by others.

I am not sure if this is the default behavior if I just used
File.Copy...

The files are relatively small.

For example, i can open up a file in notepad and someone else can edit
to it, rename it, delete it. Those operations are not affected by me
having it open in notepad.

Thanks for any advice.

-Markus_R
 
| Good day,
|
| I need to safely copy files from one directory to another. I need to
| make sure that I do not lock the file making it unreadable by others.
|
| I am not sure if this is the default behavior if I just used
| File.Copy...
|

File.Copy opens the file in ReadOnly mode, that means that another
application that has the file open, must have done this for shared read
access. If another application has opened the file in exclusive mode (no
shared read), File.Copy will fail.

| The files are relatively small.
|
| For example, i can open up a file in notepad and someone else can edit
| to it, rename it, delete it. Those operations are not affected by me
| having it open in notepad.
|

The reason for this is that notepad does NOT keep the file open, it opens
the file, reads it's contents into a buffer and closes the file. When you
save a file using notepad, all you do is save the modified buffer back to
the file, if the buffer did not change, the file won't even be written to.
That means that notepad doesn't even care about sharing, you can have
multiple users editing a file in notepad - the last writer "wins it all".

Willy.
 
More informationl: what I am trying to do is copy a log file to a
temporary directory so I can open it and parse it. I do not want to
prevent the program that is logging to it to get an access denied
error.

What is the fastest way to read the content of a file and close it?

Is this better/safer than File.copy?

Here are some methods I came up with:

//method 1
string str1 = "";
StreamReader s1 = File.OpenText(sFileName);
str1 = s1.ReadToEnd();
s1.Close();

FileInfo f1 = new FileInfo(sDestFilePath);
StreamWriter w1 = f1.CreateText();
w1.Write(s1);
w1.Close();

//method 2
string sFileText = File.ReadAllText(sFileName, Encoding.UTF8);
File.AppendAllText(sDestFilePath, sFileText, Encoding.UTF8);*/

-Markus
 
MarkusR said:
More informationl: what I am trying to do is copy a log file to a
temporary directory so I can open it and parse it. I do not want to
prevent the program that is logging to it to get an access denied
error.

What is the fastest way to read the content of a file and close it?

Is this better/safer than File.copy?

Here are some methods I came up with:

//method 1
string str1 = "";
StreamReader s1 = File.OpenText(sFileName);
str1 = s1.ReadToEnd();
s1.Close();

FileInfo f1 = new FileInfo(sDestFilePath);
StreamWriter w1 = f1.CreateText();
w1.Write(s1);
w1.Close();

//method 2
string sFileText = File.ReadAllText(sFileName, Encoding.UTF8);
File.AppendAllText(sDestFilePath, sFileText, Encoding.UTF8);*/

If you open it and specify Read/Write sharing, then you should not
cause the logging program any difficulty. If the logging program has
not shared the file for reading, then you won't be able to open it
anyway.

I notice that you are using ReadToEnd(). If the files are not too
large, this should be fine, but keep in mind that holding all the data
in a string will take up a lot of memory for very large files.

Chris
 
It is a 500k file so no problem.

The program that actually creates the log file will attempt to roll
(rename) the log file every 5 minutes so I don't want to step in its
way.

-Markus_R
 
| It is a 500k file so no problem.
|
| The program that actually creates the log file will attempt to roll
| (rename) the log file every 5 minutes so I don't want to step in its
| way.
|


If the logger program has opened the file for shared read access, you won't
have a problem to open the file in read mode with shared read/write access
and read from the file. The only problem I see in such scenario's is that
you'll never be sure you have read all the data from the file.
If the logger has opened the file for exclusive access, you won't be able to
open the file.

Willy.
 
The only problem I see in such scenario's is that you'll never be sure you
have read all the data from the file."

Actually, what I do (and I "think" works) is that I take the checksum
every time as well. If the checksum has changed then I know more data
was written to it. This works well with the rotated logs (data1.log,
data2.log). I store the checksums then ignore files that have a
checksum that I am tracking.

Anyone know the odds on 2 files having the same checksum?

-Markus_R
 
Ok,

I need to try this one more time since there are many, many ways to
read data from a file...

I need to open a file. While I have it open another program needs to be
able to rename it. I have no control over the other program. It is set
on an interval to roll the log files. There is nothing I can do.

What I am trying to do is copy the files to a temp directory so I can
parse them. I do not want to prevent the third party program from being
able to rename the file.

-Markus_R
 
MarkusR said:
Ok,

I need to try this one more time since there are many, many ways to
read data from a file...

I need to open a file. While I have it open another program needs to be
able to rename it. I have no control over the other program. It is set
on an interval to roll the log files. There is nothing I can do.

What I am trying to do is copy the files to a temp directory so I can
parse them. I do not want to prevent the third party program from being
able to rename the file.

-Markus_R
What sort of timeframe do you need?
Can you wait the 5 minutes and then copy the rolled file?
In terms of the checksum, you'd have to google(gonna get sued) to see if
they're guaranteed unique, otherwise you could use a hashing algorithm
(presume checksum is too) such as md5 or sha1.

JB
 
Waiting isn't going to solve it. They are not stopping me. They are
running into me.

I don't want to impede them. They roll (rename) the logs on a specified
interval. Once and awhile our intervals collide. They are unable to
rename a log file that I am reading and a log file is lost. It is a
pretty small file but I need to find a way to read it as fast as
possible and release it.

tried:

1) string str1 = "";
StreamReader s1 = File.OpenText(sFileName);
str1 = s1.ReadToEnd().ToString();
s1.Close();

FileInfo f1 = new FileInfo(sDestFilePath);
StreamWriter w1 = f1.CreateText();
w1.Write(str1);
w1.Close();

2) string sFileText = File.ReadAllText(sFileName, Encoding.UTF8);
File.AppendAllText(sDestFilePath, sFileText, Encoding.UTF8);

3) File.Copy(sFileName, sDestFilePath, true);

Is there a better way to open the file and still let someone else
access it (rename it)

John, thanks. I got the checksum figured out, using md5 and works
nicely.

-Markus
 

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

Back
Top