简体   繁体   中英

Reading file after writing it

I have a strange problem. So my code follows as following.

  1. The exe takes some data from the user

  2. Call a web service to write(and create CSV for the data) the file at perticular network location(say \\some-server\\some-directory). Although this web service is hosted at the same location where this folder is (ie i can also change it to be c:\\some-directory). It then returns after writing the file

  3. the exe checks for the file to exists, if the file exists then further processing else quite with error.

The problem I am having is at step 3. When I try to read the file immediately after it has been written, I always get file not found exception(but the file there is present). I do not get this exception when I am debugging (because then I am putting a delay by debugging the code) or when Thread.Sleep(3000) before reading the file.

This is really strange because I close the StreamWriter before I return the call to exe. Now according to the documention, close should force the flush of the stream. This is also not related to the size of the file. Also I am not doing Async thread calls for writing and reading the file. They are running in same thread serially one after another(only writing is done by a web service and reading is done by exe. Still the call is serial)

I do not know, but it feels like there is some time difference between the file actually gets written on the disk and when you do Close() . However this baffling because this is not at all related to size. This happens for all file size. I have tried this with file with 10, 50, 100,200 lines of data.

Another thing which I suspected was since I was writing this file to a network location, it could be windows is optimizing the call by writing first to cache and then to network location. So I went ahead and changed the code to write it on drive(ie use c:\\some-directory), rather than network location. But it also resulted in same error.

There is no error in code(for reading and writing). As explained earlier, by putting a delay, it starts working fine. Some other useful information

  1. The exe is .Net Framework 3.5
  2. Windows Server 2008(64 bit, 4 GB Ram)

Edit 1 File.AppendAllText() is not correct solution, as it creates a new file, if it does not exits

Edit 2 code for writing

using (FileStream fs = new FileStream(outFileName, FileMode.Create))
        {
            using (StreamWriter writer = new StreamWriter(fs, Encoding.Unicode))
            {
                writer.WriteLine(someString)
            }
        }

code for reading

  StreamReader rdr = new StreamReader(File.OpenRead(CsvFilePath));
  string header = rdr.ReadLine();
  rdr.Close();

Edit 3 used textwriter, same error

  using (TextWriter writer = File.CreateText(outFileName))
    {
    }

Edit 3 Finally as suggested by some users, I am doing a check for the file in while loop for certain number of times before I throw the exception of file not found.

int i = 1;
while (i++ < 10)
{
   bool fileExists = File.Exists(CsvFilePath);
   if (!fileExists)
     System.Threading.Thread.Sleep(500);
   else
     break;
}

So you are writing a stream to a file, then reading the file back to a stream? Do you need to write the file then post process it, or can you not just use the source stream directly?

If you need the file, I would use a loop that keeps checking if the file exists every second until it appears (or a silly amount of time has passed) - the writer would give you an error if you couldn't write the file, so you know it will turn up eventually.

Since you're writing over a network, most optimal solution would be to save your file in the local system first, then copy it to network location. This way you can avoid network connection problems. And as well have a backup in case of network failure.

Based on your update, Try this instead:

File.WriteAllText(outFileName, someString);
header = null;
using(StreamReader reader = new StreamReader(CsvFilePath)) {
    header = reader.ReadLine();
}

Have you tried to read after disposing the writer FileStream?

Like this:

using (FileStream fs = new FileStream(outFileName, FileMode.Create))
{
    using (StreamWriter writer = new StreamWriter(fs, Encoding.Unicode))
    {
        writer.WriteLine(someString)
    }
}

using (StreamReader rdr = new StreamReader(File.OpenRead(CsvFilePath)))
{
    string header = rdr.ReadLine();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM