提高拆分文件的速度
本文关键字:文件 速度 拆分 高拆分 | 更新日期: 2023-09-27 17:58:43
我正在使用此代码从文件中提取块
// 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 秒。这个时间可以改进吗?
有几种情况是你质疑的,但没有一个与语言相关。
以下是值得关注的问题
- 源/目标文件的文件系统是什么?
- 是否要保留原始源文件?
- 他们躺在同一个驱动器上吗?
在 c# 中,您几乎没有一个方法可以比 File.Copy
在内部调用WINAPI
CopyFile
更快。但是,由于百分比为 50,因此以下代码可能不会更快。它复制整个文件,然后设置目标文件的长度
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
文件系统上,您可以做的是
- 为文件的新拆分部分创建新的目录条目(条目(
- 让条目指向目标部件的集群
- 为每个条目设置正确的文件大小
- 检查交叉链接并避免这种情况
如果您的文件系统是NTFS
的,您可能需要花费很长时间来研究规范。
祝你好运!
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 秒内运行。
当读取/写入几兆字节的块时,我会得到更好的结果。性能也会根据块的大小而变化。
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);