简体   繁体   English

重命名文件和文件共享(文件流)

[英]Renaming files and filesharing (filestream)

I'm using a filestream to access a file (making an md5 ComputeHash). 我正在使用文件流来访问文件(创建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. 就像我说的,如果在计算MD5的过程中尝试重命名文件,我会得到该文件仍处于锁定状态的信息。

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 . 其中之一在此处进行了说明: 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! 希望能帮助到你! :) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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