我正在使用此代码从文件中提取块
// info is FileInfo object pointing to file
var percentSplit = info.Length * 50 / 100; // extract 50% of file
var bytes = new byte[percentSplit];
var fileStream = File.OpenRead(fileName);
fileStream.Read(bytes, 0, bytes.Length);
fileStream.Dispose();
File.WriteAllBytes(splitName, bytes);
有没有办法加快这个过程?
目前,对于530 MB的文件,大约需要4到5秒。这次可以改善吗?
答案 0 :(得分:8)
您有几个问题,但没有一个与语言相关。
以下是值得关注的事情
在c#中,你几乎没有一个方法可能比File.Copy
内部调用CopyFile
的{{1}}更快。但是,由于百分比为50,因此代码可能不会更快。它复制整个文件,然后设置目标文件的长度
WINAPI
此外,如果
然后,您可以做的最好的事情是根本不复制文件。
例如,如果您的源文件位于var info=new FileInfo(fileName);
var percentSplit=info.Length*50/100; // extract 50% of file
File.Copy(info.FullName, splitName);
using(var outStream=File.OpenWrite(splitName))
outStream.SetLength(percentSplit);
或FAT
文件系统上,您可以做的是
如果您的文件系统是FAT32
,则可能需要花费很长时间来研究规范。
答案 1 :(得分:2)
var percentSplit = (int)(info.Length * 50 / 100); // extract 50% of file
var buffer = new byte[8192];
using (Stream input = File.OpenRead(info.FullName))
using (Stream output = File.OpenWrite(splitName))
{
int bytesRead = 1;
while (percentSplit > 0 && bytesRead > 0)
{
bytesRead = input.Read(buffer, 0, Math.Min(percentSplit, buffer.Length));
output.Write(buffer, 0, bytesRead);
percentSplit -= bytesRead;
}
output.Flush();
}
可能不需要刷新,但它没有受到伤害,这非常有趣,将循环更改为 do-while 而不是,而有一个很大的打击表现。我想IL不是那么快。我的电脑在4-6秒内运行原始代码,附加的代码似乎在大约1秒内运行。
答案 2 :(得分:0)
当用几兆字节的块读/写时,我得到更好的结果。表演的变化也取决于大块的大小。
FileInfo info = new FileInfo(@"C:\source.bin");
FileStream f = File.OpenRead(info.FullName);
BinaryReader br = new BinaryReader(f);
FileStream t = File.OpenWrite(@"C:\split.bin");
BinaryWriter bw = new BinaryWriter(t);
long count = 0;
long split = info.Length * 50 / 100;
long chunk = 8000000;
DateTime start = DateTime.Now;
while (count < split)
{
if (count + chunk > split)
{
chunk = split - count;
}
bw.Write(br.ReadBytes((int)chunk));
count += chunk;
}
Console.WriteLine(DateTime.Now - start);
答案 3 :(得分:-1)
我认为解决此问题的最快方法是通过二进制缓冲文件输入。
我对C#不是很熟悉,但你可以研究一些缓冲技术,以便进入文件的特定部分,并从该部分进行缓冲输入。
您也可以使用C ++和Windows API进行本机缓冲技术,或者找到具有快速缓冲方法的库。
我不能提出太多建议,希望这会有所帮助。