ソケットストリームを介してファイルを受信しているとしましょう。一度に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;
}