C# 更快地处理大型文件
处理大文件需要很长时间,了解到有一种方法可以处理大文件,请告诉我如何在上面的代码中使用它???除非您需要立即在内存中使用,否则MemoryMappedFile对您没有多大帮助 您的瓶颈可能是IO而不是CPU,因此我希望在C# 更快地处理大型文件,c#,encryption,aes,data-processing,C#,Encryption,Aes,Data Processing,处理大文件需要很长时间,了解到有一种方法可以处理大文件,请告诉我如何在上面的代码中使用它???除非您需要立即在内存中使用,否则MemoryMappedFile对您没有多大帮助 您的瓶颈可能是IO而不是CPU,因此我希望在FileStreams上使用BufferSize和设置SequentialScan,这可能有助于将较大的块读写到内部缓冲区(尤其是现代SSD),并更好地优化操作系统文件缓存(分别) 缓冲区大小 大于0的Int32正值,表示缓冲区大小。这个 默认缓冲区大小为4096 顺序扫描
FileStream
s上使用BufferSize
和设置SequentialScan
,这可能有助于将较大的块读写到内部缓冲区(尤其是现代SSD),并更好地优化操作系统文件缓存(分别)
缓冲区大小
大于0的Int32正值,表示缓冲区大小。这个
默认缓冲区大小为4096
顺序扫描
指示从开始按顺序访问文件
结束。系统可以将此作为优化文件缓存的提示。如果
应用程序移动文件指针以进行随机访问,最佳
缓存可能不会发生;但是,仍然可以保证正确的操作。
在某些情况下,指定此标志可以提高性能
还要注意的是,读写文件并并行处理它们可能在一定程度上起作用(尽管如果您正在等待IO,通常不会有太多),这实际上取决于您的设备控制器处理队列深度的能力,以及CPU造成的瓶颈有多大。但是,您需要再次使用它,并根据您的情况使用它的并行度。您可以尝试获取“System.Reactive”吗?添加对
System.Reactive.linq
的引用,然后尝试以下操作:
//string filename = "123.txt";
foreach (var files in Directory.GetFiles(pathToDir, "*.*", SearchOption.TopDirectoryOnly))
using (var fsIn = new FileStream(files, FileMode.Open, FileAccess.Read))
using (var fsOut = new FileStream($"{files}.crypt", FileMode.CreateNew, FileAccess.Write))
using (var aes = Aes.Create())
using (var enc = aes.CreateEncryptor(new byte[16] /* key */, new byte[16] /* vector */))
using (var cs = new CryptoStream(fsIn, enc, CryptoStreamMode.Write))
cs.CopyTo(fsOut);
如果运行得更快,那么并行处理会带来一些好处。如果不是,那么你是IO绑定的,并行运行也不会有帮助
在任何情况下,我看不出内存映射文件在哪里会有帮助。需要多长时间?代码的哪一部分需要时间?并行处理文件是否有帮助?
枚举文件
有帮助吗?干得好。如果您设置了测试,只想知道如果您将较大的缓冲区大小(如果是ssd、10k或其他)和FileModeOptions设置为sequential(与并行测试一起),会发生什么情况@MichaelRandall-我尝试更改设置,但除了16和16之外,无法运行任何其他设置-还可以找到将模式设置为sequential的位置?sequential可以在这个构造函数中设置,但最终选项都很好,只是好奇而已
var query =
Directory
.EnumerateFiles(pathToDir, "*.*", SearchOption.TopDirectoryOnly)
.ToObservable()
.SelectMany(files =>
Observable.Using(() => new FileStream(files, FileMode.Open, FileAccess.Read), fsIn =>
Observable.Using(() => new FileStream($"{files}.crypt", FileMode.CreateNew, FileAccess.Write), fsOut =>
Observable.Using(() => Aes.Create(), aes =>
Observable.Using(() => aes.CreateEncryptor(rgbKey: new byte[16], rgbIV: new byte[16]), enc =>
Observable.Using(() => new CryptoStream(fsIn, enc, CryptoStreamMode.Read), cs => Observable.FromAsync(() => cs.CopyToAsync(fsOut))))))));
query.ToArray().Wait();