2

我正在使用 C# 的十六进制编辑器控件,源代码和二进制文件可以在这里找到。

使用它时的一个问题是,如果在十六进制编辑器和另一个程序中加载了一个文件,则另一个程序无法保存该文件,因为它已被另一个进程使用。

所以我问了控件的作者,谁告诉我在FileByteProvider和DynamicFileByteProvider类中的File.Open方法中设置FileShare参数为ReadWrite(原来只有Read)会修复它。所以我这样做了,但它仍然没有工作(同样的错误)。将其设置为只写也不起作用,但将其设置为只读和无都可以。这些文件在任何程序中都有相同的问题,例如记事本。它们没有设置为 ReadOnly 或任何东西,所以我不知道为什么它不起作用。

我在这里有什么遗漏吗?

4

2 回答 2

9

问题可能出在其他程序上——如果它试图打开文件以进行独占访问(没有共享),那么无论你的程序如何打开文件——它都会失败。


每当程序尝试打开文件时,您都需要指定 FileAccess 和 FileShare 参数(如果未明确传递,则采用默认值)。

然后 Windows 要做的是检查所有现有的打开文件句柄,并确定它们是否兼容。因此,它会将您的 FileAccess 参数与其他所有人的 FileShare 参数进行比较——您是否可以做其他所有人都说他们很乐意为他人做的事情?然后它执行相反的检查 - 您的 FileShare 参数是否与它们的 FileAccess 参数匹配?-他们在做你为他们做的事情而高兴吗?只有当这两项检查都通过时,您的特定开放请求才能被批准。

您可以使用Process Monitor之类的工具来实际监视向CreateFile发出的 Win32 调用,以查看每个进程实际在做什么。


记事本可以打开为读/写共享的文件,但不能写回该文件。示例程序:

using System.IO;

namespace ConsoleApplication2
{
    class Program
    {

        static void Main(string[] args)
        {
            var fs = new FileStream(@"C:\Bar.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
            fs.Write(System.Text.Encoding.ASCII.GetBytes("abc"),0,3);
            fs.Flush();
            fs.Close(); //<-- Breakpoint here
        }
    }
}

设置给定的断点,运行程序。当它到达断点时,打开记事本,然后用它打开 C:\Bar.txt。一切都很好。在文件中添加更多文本并点击保存。您将收到一条错误消息。

于 2011-01-14T10:13:19.597 回答
0
  1. 改为读写。
  2. 重新编译。
  3. 尝试打开一个您尚未尝试打开的文件并检查问题是否出现。

可能是您没有正确关闭文件,因此即使在您关闭应用程序后它仍保持打开状态(之前的权限设置为读取)

于 2011-01-14T10:09:54.930 回答