文件锁定 - 读取,然后锁定写入 [英] File locking - read then write whilst locked

查看:130
本文介绍了文件锁定 - 读取,然后锁定写入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要能够打开一个文件来读取它,维护一个锁,它拒绝同一个应用程序的其他实例写入权限,直到我将修改后的文件写回到磁盘。该文件是在网络上的共享位置,应用程序实例可以在网络上的任何机器。



我已经尝试使用 FileStream FileAccess.ReadWrite FileShare.Read ,用 Streamreader 来读取,然后一个 StreamWriter (在同一个 FileStream 但是这会破坏文件。其他排列的 FileAccess FileShare 似乎也不能解决我的基本问题。



所以我试着在打开 StreamWriter 之前关闭 StreamReader ,但是这改变了 CanRead CanWrite 属性 FileStream ,所以我仍然不能写。



显然我采取了错误的方法,那么有人可以告诉我应该如何处理这个问题吗?这似乎是一个足够普遍的事情要做 - 编辑一个文件,并阻止写入权限,直到编辑的文件被保存。

如果你想写一个文件,你需要独占文件访问,否则其他程序可以读取部分写入的数据(你的写入不是原子的)。有解决方案,但它们相当复杂。

一个解决方案可能是这样的:

<$ p

fsSeek(position,SeekOrigin.Begin);

$

if(fs.ReadByte()== 0)
{
//数据块没有写完
return false;
}

fs.Read(data,0,data.Length);
返回true;


静态bool写入(FileStream fs,byte [] data,long position)
{
尝试
{
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);
返回true;
}
catch(IOException)
{
return false;



$附加(FileStream fs,byte [] data)
{
return Write(fs,data,fs.Length) ;

$ / code>

其中您始终保持打开 FileStream as

  FileStream fs1 = new FileStream(Test.txt,FileMode.Open,FileAccess.ReadWrite,FileShare .ReadWrite); 

data 之前有一个守卫字节,告诉数据是否被写入。如果正在写入,则读取将失败。使用 FileStream.Lock



这个文件被锁定在需要的地方长度数据。如果你有可变长度的数据(或者你需要自动更新一个文件的区域),那么它变得更加复杂。通常你使用数据库出于这个原因: - )


I need to be able to open a file to read it, maintaining a lock that denies other instances of the same application write access until I have written the amended file back to disk. The file is in a shared location on a network, and the app instances can be on any machine on the network.

I have tried using a FileStream with FileAccess.ReadWrite and FileShare.Read, with a Streamreader to read and then a StreamWriter (on the same FileStream) to write, but this corrupts the file. Other permutations of the FileAccess and FileShare don't seem to solve my basic problem either.

So I tried closing the StreamReader before opening the StreamWriter, but that changes the CanRead and CanWrite properties of the FileStream, so I still can't write.

Clearly I am taking the wrong approach, so can someone tell me how I should be approaching this? It seems a common enough thing to want to do - edit a file and block write access until the edited file is saved.

解决方案

If you want to write to a file, you need to take exclusive file access, otherwise other programs can read partially written data (your writes aren't atomic). There are solutions to this, but they are quite complex.

A solution could be something like this:

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);
}

where you always keep open the FileStream as

FileStream fs1 = new FileStream("Test.txt", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);

Before the data there is a "guard byte" that tells if the data is being written. If it's being written then reads on it will fail. The file is locked "where it's needed" using FileStream.Lock.

This clearly works better with binary fixed-length data. If you have variable length data (or you need to atomically update more "regions" of a file) then it becomes more complex. Normally you use DBs for this reason :-)

这篇关于文件锁定 - 读取,然后锁定写入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆