简体   繁体   中英

Renaming files and filesharing (filestream)

I'm using a filestream to access a file (making an md5 ComputeHash). If I attempt to rename the file during this time (which fails as the file is being accessed). So far so good, but when I then try to open the file anew after the original filestream is closed I get the info that the file is open in another process.

Code:

using (Stream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
    MD5 md5 = MD5.Create();
    byte[] mymd5computed = md5.ComputeHash(fileStream);
    ......
}
Thread.Sleep(50);

Thread a = new Thread (()=>{(FileStream sourceStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)){....} });

Like I said if while during the computation of the MD5 I try to rename the file I get the info that the file is still locked.

The lock on a file sometimes isn't released right away when you close your stream, so there are some other solutions you can use to wait until you can access the file again. One of them is explained here: http://www.codeproject.com/Tips/164428/C-FileStream-Lock-How-to-wait-for-a-file-to-get-re .

Recap:

public static void Lock(string path, Action<FileStream> action) {
    var autoResetEvent = new AutoResetEvent(false);

    while(true)
    {
        try
        {
            using (var file = File.Open(path,
                                        FileMode.OpenOrCreate,
                                        FileAccess.ReadWrite,
                                        FileShare.Write))
            {
                action(file);
                break;
            }
        }
        catch (IOException)
        {
            var fileSystemWatcher =
                new FileSystemWatcher(Path.GetDirectoryName(path))
                        {
                            EnableRaisingEvents = true
                        };

            fileSystemWatcher.Changed +=
                (o, e) =>
                    {
                        if(Path.GetFullPath(e.FullPath) == Path.GetFullPath(path))
                        {
                            autoResetEvent.Set();
                        }
                    };

            autoResetEvent.WaitOne();
        }
    } 
}

Sample use:

Lock(@"c:\file",
        (f) =>
            {
                try
                {
                    f.Write(buf, 0, buf.Length);
                }
                catch(IOException ioe)
                {
// handle IOException
                }
            });

Hope it helps! :)

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