2

ソケットストリームを介してファイルを受信して​​いるとしましょう。一度に1024バイトを受信して​​います。ハードディスクに書き込むたびに、アンチウイルスがファイル全体をスキャンします。ファイルが大きくなるほど、次の1024バイトの書き込みに時間がかかります。「ファイルは別のプロセスで使用されています」というエラーは言うまでもありません。

現時点での私の回避策は、バイトをメモリ内のバイト配列に最大Xメガバイト(ユーザー定義)で格納することです。バイト配列は、いっぱいになるたびにハードディスク上のファイルに追加されます。

byte[] filebytearray = new byte[filesize]; //Store entire file in this byte array.

do
{
    serverStream = clientSocket.GetStream();
    bytesRead = serverStream.Read(inStream, 0, buffSize); //How many bytes did we just read from the stream?
    recstrbytes = new byte[bytesRead]; //Final byte array this loop
    Array.Copy(inStream, recstrbytes, bytesRead); //Copy from inStream to the final byte array this loop
    Array.Copy(recstrbytes, 0, filebytearray, received, bytesRead); //Copy the data from the final byte array this loop to filebytearray

    received += recstrbytes.Length; //Increment bytes received

}while (received < filesize);

addToBinary(filebytearray, @"C:\test\test.exe"); //Append filebytearray to binary

(この簡略化された例では、ファイル全体をメモリに保存してから、hddにアンロードします)

しかし、プログラムが使用するメモリが大幅に増えるため、この方法は絶対に嫌いです。

他のプログラマーはこの問題にどのように取り組んでいますか?たとえば、Firefoxでダウンロードすると、フルスピードでダウンロードされるだけで、AVはそれが完了するまでそれを取得しないようで、プロセスのメモリ使用量はほとんど増加しません。ここでの大きな秘密は何ですか?

私が使用しているバイナリ関数に追加する(WIP):

private bool addToBinary(byte[] msg, string filepath)
{
    Console.WriteLine("Appending "+msg.Length+" bytes of data.");

    bool succ = false;

    do
    {
        try
        {
            using (Stream fileStream = new FileStream(filepath, FileMode.Append, FileAccess.Write, FileShare.None))
            {
                fileStream.Write(msg, 0, msg.Length);
                fileStream.Flush();
                fileStream.Close();
            }
            succ = true;
        }
        catch (IOException ex) { /*Console.WriteLine("Write Exception (addToBinary) : " + ex.Message);*/ }
        catch (Exception ex) { Console.WriteLine("Some Exception occured (addToBinary) : " + ex.Message); return false; }
    } while (!succ);
    return true;
}
4

3 に答える 3

3

データを書き込むたびにファイルを再度開くようです。ファイルストリームを開いたままにしてみませんか?変更されているため、閉じるたびにアンチウイルスがスキャンします。

そして、1つの提案として、WriteLine関数はC ++のprintfのように機能するため、次のようにする代わりに次のことを行います。

Console.WriteLine("Appending "+msg.Length+" bytes of data.");

あなたができること:

Console.WriteLine("Appending {0} bytes of data.", msg.Length);

これは本当に時々あなたの時間を節約することができます。

于 2012-06-28T17:03:08.037 に答える
0

まず、メモリストリームを使用できます。次に、ディスクへの書き込みを何度か行う必要があります。ユーザーが気付かないように、バックグラウンドで書き込むだけです。

メモリストリームの同時キューを作成し、キューを空にしようとするハンドラーを作成します。

于 2012-06-28T16:27:05.077 に答える
0

アンチウイルスに除外を追加して、干渉を防ぐことができます。データをスキャンする場合は、除外されたフォルダーにデータをダウンロードし、ファイルが完成したら(スキャンされる)フォルダーに移動します。

他のアプローチは、データをバッファリングして、1k単位で書き込みを行わないようにし、書き込みが完了するまでファイルを開いたままにすることです。

于 2012-06-28T17:24:52.963 に答える