我需要能够打开一个文件来读取它,维护一个锁定,拒绝同一个应用程序写入访问的其他实例,直到我将修改后的文件写回磁盘。该文件位于网络上的共享位置,应用程序实例可以位于网络上的任何计算机上。
我尝试使用FileStream
与FileAccess.ReadWrite
和FileShare.Read
,Streamreader
阅读,然后StreamWriter
(同一FileStream
写入,但这会破坏文件。 FileAccess
和FileShare
的其他排列似乎也无法解决我的基本问题。
所以我在打开StreamReader
之前尝试关闭StreamWriter
,但这会更改CanRead
的{{1}}和CanWrite
属性,所以我仍然可以不写。
显然我采取了错误的方法,所以有人能告诉我应该如何接近这个吗?这似乎是一件很常见的事情 - 编辑文件并阻止写入访问,直到保存编辑过的文件。
答案 0 :(得分:0)
如果要写入文件,则需要进行独占文件访问,否则其他程序可以读取部分写入的数据(您的写入不是原子的)。有解决方案,但它们非常复杂。
解决方案可能是这样的:
static bool Read(FileStream fs, byte[] data, long position)
{
fs.Seek(position, SeekOrigin.Begin);
if (fs.ReadByte() == 0)
{
// Block of data not finished writing
return false;
}
fs.Read(data, 0, data.Length);
return true;
}
static bool Write(FileStream fs, byte[] data, long position)
{
try
{
fs.Lock(position, data.Length + 1);
fs.Seek(position, SeekOrigin.Begin);
fs.WriteByte(0);
fs.Write(data, 0, data.Length);
fs.Seek(position, SeekOrigin.Begin);
fs.WriteByte(1);
fs.Unlock(position, data.Length + 1);
return true;
}
catch (IOException)
{
return false;
}
}
static bool Append(FileStream fs, byte[] data)
{
return Write(fs, data, fs.Length);
}
您始终将FileStream
打开为
FileStream fs1 = new FileStream("Test.txt", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
在data
之前有一个“保护字节”,告诉我们是否正在写入数据。如果它正在写入,则读取它将失败。使用FileStream.Lock
将文件锁定在“需要的位置”。
这对二进制固定长度数据显然更有效。如果您有可变长度的数据(或者您需要以原子方式更新文件的更多“区域”),那么它就会变得更加复杂。通常,您出于以下原因使用DB: - )
答案 1 :(得分:0)
使用写访问权限保持文件打开。这应该拒绝对文件的所有其他写入。
答案 2 :(得分:0)
由于您没有指定您正在使用的操作系统,也没有指定访问是时间关键或命令关键,因此我认为您最好的选择是使用目录来指示文件已被锁定。
在大多数操作系统上,创建目录几乎是即时的,而创建文件却不是。 因此,每次您的应用程序想要访问有问题的数据文件时,它必须尝试在与文件相同的位置创建一个子目录。如果该目录已存在,则创建将失败,您的应用程序必须等待,再次尝试直到成功。
当它成功创建目录时,它可以访问该文件并进行编写。一旦所有数据都被写入并且文件访问被关闭,那么在删除目录之前它应该等待一点(以允许实际写入完成)。
但是,您需要编写一些代码来处理应用程序崩溃的实例并保留锁定目录。