我们有一个项目,需要迁移多达10GB的二进制文件。步骤是 1)按邮件大小读取文件 2)做一些处理 3)将原始消息或已处理的消息写回到新的二进制文件中。
对于10GB的文件,处理后变为14GB。目前大约需要2个小时。
我想知道我是否可以做一些IO技巧来减少时间。
using (FileStream fsInput =new FileStream(inputfilename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (FileStream fsOutput = File.Create(outputfilename))
{
long total = fsInput.Length;
long progress = 0;
unsafe
{
int hdrSize = sizeof(FullMessageHeader);
byte[] headerBuffer = new byte[hdrSize];
while (fsInput.Position < fsInput.Length)
{
progress += fsInput.Read(headerBuffer, 0, hdrSize);
int msgSize = 0;
fixed (byte* hdr = headerBuffer)
{
msgSize = *(int*)(hdr + MessageHeaderOffsets.Size);
}
byte[] msg = new byte[msgSize];
Buffer.BlockCopy(headerBuffer, 0, msg, 0, headerBuffer.Length);
fsInput.Position -= hdrSize;
progress += fsInput.Read(msg, 0, msgSize);
fixed (byte* ptr = msg)
{
byte[] ba = ProcessMessage(ptr);
if (ba.Length == 0)
{
fsOutput.Write(msg, 0, msg.Length);
}
else
{
fsOutput.Write(ba, 0, ba.Length);
}
}
}
}
}
}
答案 0 :(得分:0)
最后,正如Georg所建议的,并清理了上面的代码,我能够将时间从2小时减少到10分钟,这不是最佳选择,但是可以接受。
Dictionary<int, byte[]> byteDictionary = new Dictionary<int, byte[]>();
using (FileStream fsInput =new FileStream(inputfilename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (FileStream fsOutput = File.Create(outputfilename))
{
long total = fsInput.Length;
long progress = 0;
unsafe
{
int hdrSize = sizeof(FullMessageHeader);
byte[] headerBuffer = new byte[hdrSize];
while (fsInput.Position < fsInput.Length)
{
progress += fsInput.Read(headerBuffer, 0, hdrSize);
int msgSize = 0;
fixed (byte* hdr = headerBuffer)
{
msgSize = *(int*)(hdr + MessageHeaderOffsets.Size);
}
byte[] msg = byteDictionary.ContainsKey(msgSize)
? byteDictionary[msgSize]
: new byte[msgSize];
if (!byteDictionary.ContainsKey(msgSize))
{
byteDictionary[msgSize] = msg;
}
//byte[] msg = new byte[msgSize];
//Buffer.BlockCopy(headerBuffer, 0, msg, 0, headerBuffer.Length);
fsInput.Position -= hdrSize;
progress += fsInput.Read(msg, 0, msgSize);
fixed (byte* ptr = msg)
{
//fsOutput.Write(msg,0,msg.Length);
byte[] ba = ProcessMessage(ptr);
if (ba.Length == 0)
{
fsOutput.Write(msg, 0, msg.Length);
}
else
{
fsOutput.Write(ba, 0, ba.Length);
}
}
}
}
}
}