Will a using clause close this stream?

后端 未结 5 1253
难免孤独
难免孤独 2020-12-20 10:55

I\'ve apparently worked myself into a bad coding habit. Here is an example of the code I\'ve been writing:

using(StreamReader sr = new StreamReader(File.Open         


        
相关标签:
5条回答
  • 2020-12-20 11:18

    Yes, StreamReader.Dispose closes the underlying stream (for all public ways of creating one). However, there's a nicer alternative:

    using (TextReader reader = File.OpenText("file.txt"))
    {
    }
    

    This has the added benefit that it opens the underlying stream with a hint to Windows that you'll be accessing it sequentially.

    Here's a test app which shows the first version working for me. I'm not trying to say that's proof of anything in particular - but I'd love to know how well it works for you.

    using System;
    using System.IO;
    
    class Program
    {
        public static void Main(string[] args)
        {
            for (int i=0; i < 1000; i++)
            {
                using(StreamReader sr = new StreamReader
                      (File.Open("somefile.txt", FileMode.Open)))
                {
                    Console.WriteLine(sr.ReadLine());
                }
                File.Move("somefile.txt", "somefile.bak");
                File.Move("somefile.bak", "somefile.txt");
            }
        }
    }
    

    If that works, it suggests that it's something to do with what you do while reading...

    And now here's a shortened version of your edited question code - which again works fine for me, even on a network share. Note that I've changed FileMode.Create to FileMode.CreateNew - as otherwise there could still have been an app with a handle on the old file, potentially. Does this work for you?

    using System;
    using System.IO;
    
    public class Test
    {    
        static void Main()
        {
            StreamWriter creditsFile = new StreamWriter(File.Open("test.txt", 
                                              FileMode.CreateNew));
    
            creditsFile.WriteLine("code\\inc");
    
            creditsFile.Close();
            creditsFile.Dispose();
    
            File.Move("test.txt", "test2.txt");
        }
    }
    
    0 讨论(0)
  • 2020-12-20 11:30

    Note - your using blocks do not need to be nested in their own blocks - they can be sequential, as in:

    using(FileStream fs = File.Open("somefile.txt", FileMode.Open))
    using(StreamReader sr = new StreamReader(fs))
    {
        //read file
    }
    

    The order of disposal in this case is still the same as the nested blocks (ie, the StreamReader will still dispose before the FileStream in this case).

    0 讨论(0)
  • 2020-12-20 11:34

    Is there any possibility that something else has a lock to somefile.txt?

    A simple check from a local (to the file) cmd line

    net files
    

    may well give you some clues if anything else has a lock.

    Alternatively you can get something like FileMon to take even more details, and check that your app is releasing properly.

    0 讨论(0)
  • 2020-12-20 11:40

    Since this doesn't seem to be a coding issue, I'm going to put my syadmin hat on and offer a few suggestions.

    1. Virus scanner on either the client or server that's scanning the file as it's created.
    2. Windows opportunistic locking has a habit of screwing things up on network shares. I recall it being mostly an issue with multiple read/write clients with flat file databases, but caching could certainly explain your problem.
    3. Windows file open cache. I'm not sure if this is still a problem in Win2K or not, but FileMon would tell you.

    Edit: If you can catch it in the act from the server machine, then Sysinternal's Handle will tell you what has it open.

    0 讨论(0)
  • 2020-12-20 11:44

    I would try to use FileInfo.Open() and FileInfo.MoveTo() instead of File.Open() and File.Move(). You could also try to use FileInfo.OpenText(). But these are just suggestions.

    0 讨论(0)
提交回复
热议问题