3

I have read many other posts about this topic, but none appear to solve my problem directly (which surprises me).

Regardless...I wrote a log parser and very simply I am looking to copy a file from a remote machine locally, prior to parsing it. The file I am trying to copy is being written to constantly and I have ‘random’ success in copying it. Sometimes it will work and other times I will get an ‘access is denied’ or FileAccess error. A few other points:

  • Whenever I use windows explorer to copy the file locally, I never
    have a problem copying it (which leads me to believe it’s perfectly
    possible to copy the file 100% of the time).
  • I can always open the file using a text editor in its remove location.
  • I do not own the file being written to and do not wish to ‘lock’ it in anyway such that the application that is actually writing to this file fails.

Does anyone have any suggestions for how to copy this file?

The current command I am using is:

File.Copy(this.txt_log_file_to_analyze.Text, sLogFileToAnalyze,true);
user2786756
  • 51
  • 1
  • 6
  • Debug examples of the value of this.txt_log_file_to_analyze.Text would help us figure out how exactly you're accessing this machine remotely (OS mapped drive, FTP, etc.) – Adam Kewley Sep 26 '13 at 08:51
  • 3
    Have you tried `new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.Read)` this way you make sure to open it only in "read" mode? The you could write it into a memory stream or save it into a file etc. – DerApe Sep 26 '13 at 08:55
  • 1
    what about the file size is it very large one ?? – Thilina H Sep 26 '13 at 08:55
  • 1
    Actually I don't think you have to copy the file, if owner of the file opened it with enough share options to read it while the owner is writing to it(in your case it is since you say it is possible), then you can open the file only with read mode and process what you read. – Tolga Evcimen Sep 26 '13 at 08:55
  • I am using a UNC \\\. – user2786756 Sep 26 '13 at 08:57
  • The file is can be anywhere from 20MB - 100 MB (Depending on the time of day grabbing it) – user2786756 Sep 26 '13 at 08:58
  • Open the file and save it where you want to copy it .. I guess this might work .. – Rafay Sep 26 '13 at 08:58
  • *Whenever I use windows explorer to copy the file locally, I never have a problem copying it (which leads me to believe it’s perfectly possible to copy the file 100% of the time).* You know that you can't be sure, aren't you? Fact is `File.Copy` locks the file exclusively, so no matter what you do, another person won't be able to open it while you copy it. use `Stream.CopyTo` as suggested in one of the answers. – Thorsten Dittmar Sep 26 '13 at 08:58

1 Answers1

8

I guess you'll have to open the file using:

File.Open(this.txt_log_file_to_analyze.Text,FileMode.Open,FileAccess.Read,FileShare.ReadWrite)

and then copy the contents of the file 'manually' i.e.

using (var from = File.Open("path", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (var to = File.OpenWrite("to_path"))
{
    from.CopyTo(to);
}

or if .NET 4.5 see How do I copy the contents of one stream to another?

Using the above api, you can specify that you do not want exclusive access to the file.

Community
  • 1
  • 1
Rudi
  • 3,124
  • 26
  • 35
  • This is exactly what I am saying – Tolga Evcimen Sep 26 '13 at 08:58
  • GREAT!!!. Two questions. What happens if the remote file continues to get written to while I run these statements? Will the commands ever finish? If the file exists locally, can I overwrite? – user2786756 Sep 26 '13 at 09:09
  • Will the command finish? I have no idea - never tried this before. Overwrite the to file? With the current File.OpenWrite, it will open an existing file, not sure if it will append or overwrite, but using File.Open for the 'to' you again have much more control. – Rudi Sep 26 '13 at 09:13
  • I tried this and here is what happens:When the file is being edited File.Open stops the copying process. I can't use Stream.CopyTo because my users are not on .NET 4.5. Any other suggestions? – user2786756 Sep 27 '13 at 07:54
  • So here is what I did to test this (didn't want to touch my production file just yet). I opened a file using notepad++ (75MB) During the 'File.Open' part, I edited the file and saved. That is when the copy stopped. I switched FileShare.ReadWrite to FileShare.Read and while the copying was happening, I could not edit the file (I am assuming this means the application would not be able to write to it while I was copying it). – user2786756 Sep 27 '13 at 08:09
  • For the replacement of CopyTo, see the linked question http://stackoverflow.com/questions/230128/best-way-to-copy-between-two-stream-instances And perhaps you will need to become very clever and open the source file, seek to the pervious position, read a buffer, close the source file, remember the position and repeat. – Rudi Sep 27 '13 at 09:33
  • Perhaps you can take a look at how http://snakenest.com/snaketail/ does it. https://code.google.com/p/snaketail-net/ It is using the http://msdn.microsoft.com/en-us/library/System.IO.FileStream.aspx class. (Discovered an old class!) – Rudi Sep 27 '13 at 09:42