9

会社のデバイス予約用のある種のグローバルストレージとしてファイルを使用するアプリケーションの場合、ファイルの読み取りと書き込み(またはファイルのロック、読み取り、書き込み、ロック解除)の方法が必要です。小さなコードスニペットは、私が言っていることを示しています。

FileStream in = new FileStream("storage.bin", FileMode.Open);
//read the file
in.Close();

//!!!!!
//here is the critical section since between reading and writing, there shouldnt
//be a way for another process to access and lock the file, but there is the chance
//because the in stream is closed
//!!!!!
FileStream out = new FileStream("storage.bin", FileMode.Create);
//write data to file
out.Close();

これはこのようなものになるはずです

LockFile("storage.bin");
//read from it...
//OVERwrite it....
UnlockFile("storage.bin");

プログラムは2000台のデバイスで同時に実行する必要があるため、この方法は絶対に安全である必要があります

4

5 に答える 5

13

FileStream排他的(共有されていない)アクセスでオープンを保持するだけで、他のプロセスがファイルにアクセスできなくなります。これは、読み取り/書き込みアクセス用にファイルを開くときのデフォルトです。

現在開いているファイルを切り捨てることで「上書き」できます。

それで:

using (var file = File.Open("storage.bin", FileMode.Open))
{
    // read from the file

    file.SetLength(0); // truncate the file

    // write to the file
}

プログラムは2000台のデバイスで同時に実行する必要があるため、この方法は絶対に安全である必要があります

ファイルに書き込む頻度によっては、これがチョークポイントになる可能性があります。これをテストして、拡張性を確認することをお勧めします。

さらに、プロセスの1つが別のプロセスと同時にファイルを操作しようとすると、IOExceptionがスローされます。ファイルを「待機」する方法は実際にはないため、ファイルへのアクセスをより整然と調整する必要があります。

于 2012-07-24T08:52:59.987 に答える
3

読み取りと書き込みの両方のために開かれた単一のストリームが必要です。

FileStream fileStream = new FileStream(
      @"c:\words.txt", FileMode.OpenOrCreate, 
      FileAccess.ReadWrite, FileShare.None);

または、試すこともできます

static void Main(string[] args)
    {
        var text = File.ReadAllText(@"C:\words.txt");
        File.WriteAllText(@"C:\words.txt", text + "DERP");
    }

http://msdn.microsoft.com/en-us/library/system.io.fileshare(v=vs.71).aspxによる

FileStream s2 = new FileStream(name, FileMode.Open, FileAccess.Read, FileShare.None);

FileStreamコンストラクターのオーバーロードで開くには、FileShare列挙値Noneを渡す必要があります。

fs = new FileStream(@"C:\Users\Juan Luis\Desktop\corte.txt", FileMode.Open, 
    FileAccess.ReadWrite, FileShare.None);
于 2012-07-24T08:59:08.550 に答える
2

私はこれを行うためにこのヘルパークラスを書くことになりました:

public static class FileHelper
{
    public static void ReplaceFileContents(string fileName, Func<String, string> replacementFunction)
    {
        using (FileStream fileStream = new FileStream(
                fileName, FileMode.OpenOrCreate,
                FileAccess.ReadWrite, FileShare.None))
        {
            StreamReader streamReader = new StreamReader(fileStream);
            string currentContents = streamReader.ReadToEnd();
            var newContents = replacementFunction(currentContents);
            fileStream.SetLength(0);
            StreamWriter writer = new StreamWriter(fileStream);
            writer.Write(newContents);
            writer.Close();
        }
    }
}

これにより、既存のコンテンツを取得して新しいコンテンツを生成し、この変更が行われている間、ファイルが他のユーザーによって読み取られたり変更されたりしないようにする関数を渡すことができます。

于 2016-03-24T17:21:11.403 に答える
1

FileStream.LockFileStream.Unlockを探している可能性があります

于 2012-07-24T08:52:21.487 に答える
1

オーバーロードされたOpenメソッドでFileShare.Noneフラグを使用する必要があると思います。

file = File.Open("storage.bin", FileMode.Open, FileShare.None);
于 2012-07-24T09:03:12.727 に答える