Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/302.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将文件锁定在C#中,而不使其在首次读取后无法写入?_C#_Json_Multithreading_Locking_Filestream - Fatal编程技术网

如何将文件锁定在C#中,而不使其在首次读取后无法写入?

如何将文件锁定在C#中,而不使其在首次读取后无法写入?,c#,json,multithreading,locking,filestream,C#,Json,Multithreading,Locking,Filestream,这个问题来自另一个线索: 基本上,假设您想要锁定一个JSON文件,读取它,然后写入它,最后解锁它。您可以使用其他问题的答案锁定该文件 但是,我遇到了一些问题,这使得我能够读取文件,但在没有首先解锁文件的情况下不能写入文件。也就是说,推荐的方法(似乎得到了很好的尊重)是将相同的线程锁定在自己的资源之外 例如: using (var fs = new FileStream(GetJsonPath(), FileMode.Open, FileAccess.ReadWrite, File

这个问题来自另一个线索:

基本上,假设您想要锁定一个JSON文件,读取它,然后写入它,最后解锁它。您可以使用其他问题的答案锁定该文件

但是,我遇到了一些问题,这使得我能够读取文件,但在没有首先解锁文件的情况下不能写入文件。也就是说,推荐的方法(似乎得到了很好的尊重)是将相同的线程锁定在自己的资源之外

例如:

using (var fs = new FileStream(GetJsonPath(), FileMode.Open, FileAccess.ReadWrite,
        FileShare.None))
{
    SomeDtoType dto;
    using (StreamReader reader = new StreamReader(fs))
    {
        dto = ((SomeDtoType)(new JsonSerializer()).Deserialize(reader,
                typeof(SomeDtoType)));
    }

    // Make changes to the DTO.....

    using (StreamWriter writer = new StreamWriter(fs))
    {
        new JsonSerializer().Serialize(writer, dto);
    }
}
创建
StreamWriter
using
行引发以下异常:

流不可写

现在想到的一件事是
FileShare.None
的价值。这里的问题是,这个特定的枚举显然不仅仅是为外部进程设置锁定权限

如何锁定外部线程/进程以避免更改/删除文件,同时允许自己的线程/进程进行这两次后续读/写访问

编辑:


显然,使用
StreamReader
块将所有内容移动到
中,然后在读写类型之间将
fs.Position
设置为
0
,可以解决问题。
fs.Position
部分很好,但是必须将写入逻辑移动到
StreamReader
using
块中,这样他们就可以使用相同的
文件流
锁,这似乎有点奇怪…

StreamReader
关闭流,如果您不使用ctor重载并指示它不要这样做:

using (StreamReader reader = new StreamReader(fs, Encoding.UTF8, true, 4096, leaveOpen:true))
在中没有终结器,您可以使用
块将其移出
,并保持为未被终结,但是我建议显式控制其生存期和行为

另一个问题是,您将附加到文件中。如果要覆盖内容,则需要在写入内容之前重置内容:

fs.SetLength(0);

当您通过处理读卡器停止关闭流时,应该可以正常工作。。。(你显然需要寻找流回)@Panzercrisis如果你移动一个
位置
并且新内容小于现有内容,那么你可能会得到一个格式错误的内容,因为移动一个位置不会重置内容。有一个特殊的构造器不会关闭流-