【发布时间】:2016-01-17 18:07:28
【问题描述】:
我正在使用以下代码从一个大文件 (> 10 GB) 中读取值:
FileStream fs = new FileStream(fileName, FileMode.Open);
BinaryReader br = new BinaryReader(fs);
int count = br.ReadInt32();
List<long> numbers = new List<long>(count);
for (int i = count; i > 0; i--)
{
numbers.Add(br.ReadInt64());
}
不幸的是,我的 SSD 的读取速度卡在了几 MB/s。我猜这个限制是 SSD 的 IOPS,所以从文件中分块读取可能会更好。
问题
每次 BinaryReader 调用 ReadInt64() 时,我的代码中的 FileStream 是否真的只从文件中读取 8 个字节?
如果是这样,BinaryReader 是否有一种透明的方式来提供从文件中读取更大块的流以加快过程?
测试代码
这是一个创建测试文件并测量读取性能的最小示例。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
namespace TestWriteRead
{
class Program
{
static void Main(string[] args)
{
System.IO.File.Delete("test");
CreateTestFile("test", 1000000000);
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
IEnumerable<long> test = Read("test");
stopwatch.Stop();
Console.WriteLine("File loaded within " + stopwatch.ElapsedMilliseconds + "ms");
}
private static void CreateTestFile(string filename, int count)
{
FileStream fs = new FileStream(filename, FileMode.CreateNew);
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(count);
for (int i = 0; i < count; i++)
{
long value = i;
bw.Write(value);
}
fs.Close();
}
private static IEnumerable<long> Read(string filename)
{
FileStream fs = new FileStream(filename, FileMode.Open);
BinaryReader br = new BinaryReader(fs);
int count = br.ReadInt32();
List<long> values = new List<long>(count);
for (int i = 0; i < count; i++)
{
long value = br.ReadInt64();
values.Add(value);
}
fs.Close();
return values;
}
}
}
【问题讨论】:
-
刚刚看到我最初的评论有缺陷。读取命令的数量可能确实是那里的原因(否则通常我会认为缓存或内存大小是主要原因)。 Veras 链接问题应该为您的问题提供一个很好的观点。如果读取这些块没有帮助,那么瓶颈在其他地方,您还应该检查内存使用情况和 cpu 使用情况并将其放入您的问题中。
-
你可以使用 File.ReadAllBytes 吗?然后从字节中制作内存流,然后使用 BitConverter 读取数据?它比寻找更快,
-
很遗憾我不能,因为 File:ReadAllBytes 只支持 2 GB 文件。
-
@user2033412:您在
count变量中读取的值是多少?
标签: c# performance io filestream binaryreader