假设我通过套接字流接收文件,我一次收到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;
}
答案 0 :(得分:3)
我看到你每次写数据时都重新打开文件。为什么不保持文件流打开?每次关闭它时,防病毒软件都会对其进行扫描,因为它已被修改。
还有一个建议,WriteLine函数就像c ++中的printf一样工作,所以...而不是:
Console.WriteLine("Appending "+msg.Length+" bytes of data.");
你可以这样做:
Console.WriteLine("Appending {0} bytes of data.", msg.Length);
这有时可以节省您的时间。
答案 1 :(得分:0)
首先,您可以使用内存流。 其次,你必须有时写入磁盘,只需在后台进行,这样用户就不会注意到了。
创建一个并发的内存流队列,并创建一个尝试清空队列的处理程序。
答案 2 :(得分:0)
您可以向防病毒软件添加排除项,以阻止其干扰。如果要扫描数据,请将其下载到排除的文件夹,然后在文件完成时将其移动到文件夹(将被扫描)。
其他方法是缓冲数据,这样你就不会以微小的1k增量写入,并保持文件打开直到你完成写入。