0

私が使用している外部Windowsサービスは、継続的に追加される単一のテキストベースのログファイルを維持します。このログファイルは、時間の経過とともに無制限に大きくなります。このログファイルを定期的に整理して、最新の5MBのログエントリを維持したいと思います。C#.NET4.0でファイルI/ Oコードを効率的に実装して、ファイルを5MBと言うように整理するにはどうすればよいですか?

更新:サービスの依存関係を設定する方法で、私のサービスは常に外部サービスの前に開始されます。これは、必要に応じて、ログファイルに排他的にアクセスして切り捨てることを意味します。外部サービスが起動すると、ログファイルにアクセスしなくなります。デスクトップの起動時にファイルへの排他的アクセスを取得できます。問題は、ログファイルのサイズが数ギガバイトになる可能性があるため、ログファイルを切り捨てる効率的な方法を探していることです。

4

3 に答える 3

1

「新しい」ログファイルを処理するために保存するメモリの量が必要になりますが、5Mbのみが必要な場合は、問題ないはずです。Gb +について話している場合は、おそらく他の問題があります。ただし、一時ファイルといくつかのロックを使用して実行することはできます。

前に述べたように、競合状態が発生する可能性がありますが、これがこのファイルに書き込む唯一のスレッドである場合はそうではありません。これにより、ファイルへの現在の書き込みが置き換えられます。

const int MAX_FILE_SIZE_IN_BYTES = 5 * 1024 * 1024; //5Mb;
const string LOG_FILE_PATH = @"ThisFolder\log.txt";
string newLogMessage = "Hey this happened";


#region Use one or the other, I mean you could use both below if you really want to.
//Use this one to save an extra character
if (!newLogMessage.StartsWith(Environment.NewLine))
    newLogMessage = Environment.NewLine + newLogMessage;

//Use this one to imitate a write line
if (!newLogMessage.EndsWith(Environment.NewLine))
    newLogMessage = newLogMessage + Environment.NewLine; 
#endregion

int newMessageSize = newLogMessage.Length*sizeof (char);
byte[] logMessage = new byte[MAX_FILE_SIZE_IN_BYTES];
//Append new log to end of "file"
System.Buffer.BlockCopy(newLogMessage.ToCharArray(), 0, logMessage, MAX_FILE_SIZE_IN_BYTES - newMessageSize, logMessage.Length);


FileStream logFile = File.Open(LOG_FILE_PATH, FileMode.Open, FileAccess.ReadWrite);

int sizeOfRetainedLog = (int)Math.Min(MAX_FILE_SIZE_IN_BYTES - newMessageSize, logFile.Length);
//Set start position/offset of the file
logFile.Position = logFile.Length - sizeOfRetainedLog;
//Read remaining portion of file to beginning of buffer
logFile.Read(logMessage, logMessage.Length, sizeOfRetainedLog);

//Clear the file
logFile.SetLength(0); 
logFile.Flush();

//Write the file
logFile.Write(logMessage, 0, logMessage.Length);

私はこれを本当に速く書きました、私がどこかで1つずれているならば、私は謝罪します。

于 2013-02-15T22:50:45.253 に答える
0

ファイルオブザーバーを使用してファイルを監視できます。

FileSystemWatcher logWatcher = new FileSystemWatcher();
        logWatcher.Path = @"c:\example.log"
        logWatcher.Changed += logWatcher_Changed;

次に、イベントが発生したときに、StreamReaderを使用してファイルを読み取ることができます

private void logWatcher_Changed(object sender, FileSystemEventArgs e)
    {
     using (StreamReader readFile = new StreamReader(path))
        {
            string line;
            string[] row;
            while ((line = readFile.ReadLine()) != null)
            {
               // Here you delete the lines you want or move it to another file, so that your log keeps small. Then save the file. 
            }
        }
    }

それはオプションです。

于 2013-02-15T22:25:09.783 に答える
0

書き込まれる頻度によっては、ログを損傷せずにファイルを変更する競合状態に直面している可能性があります。ファイルサイズを監視するサービスをいつでも作成してみてください。特定のポイントに達したら、ファイルをロックし、すべてを複製してクリアし、閉じます。次に、サービスがサイズを簡単に制御できる別のファイルにデータを保存します。または、外部サービスにデータベースにログを記録するオプションがあるかどうかを確認できます。これにより、最も古いデータを簡単にロールアウトできます。

于 2013-02-15T22:19:43.773 に答える