Задача
У меня есть огромный файл (& approx; 20 ГБ), содержащий целые числа, и вы хотите прочитать их на C#.Чтение гигантского массива из двоичного файла
Простой подход
Чтение файла в память (в байт-массив) довольно быстро (с использованием SSD, весь файл помещается в памяти). Но когда я читаю эти байты с двоичным считывателем (через поток памяти), а метод ReadInt32 занимает значительно больше времени, чем чтение файла в память. Я ожидал, что диск-IO станет узким местом, но это конверсия!
Идея и вопрос
Есть ли способ, чтобы непосредственно бросить весь байт-массив в Инт-массив не конвертируя его один-на-один с ReadInt32-метода?
class Program
{
static int size = 256 * 1024 * 1024;
static string filename = @"E:\testfile";
static void Main(string[] args)
{
Write(filename, size);
int[] result = Read(filename, size);
Console.WriteLine(result.Length);
}
static void Write(string filename, int size)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
BinaryWriter bw = new BinaryWriter(new FileStream(filename, FileMode.Create), Encoding.UTF8);
for (int i = 0; i < size; i++)
{
bw.Write(i);
}
bw.Close();
stopwatch.Stop();
Console.WriteLine(String.Format("File written in {0}ms", stopwatch.ElapsedMilliseconds));
}
static int[] Read(string filename, int size)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
byte[] buffer = File.ReadAllBytes(filename);
BinaryReader br = new BinaryReader(new MemoryStream(buffer), Encoding.UTF8);
stopwatch.Stop();
Console.WriteLine(String.Format("File read into memory in {0}ms", stopwatch.ElapsedMilliseconds));
stopwatch.Reset();
stopwatch.Start();
int[] result = new int[size];
for (int i = 0; i < size; i++)
{
result[i] = br.ReadInt32();
}
br.Close();
stopwatch.Stop();
Console.WriteLine(String.Format("Byte-array casted to int-array in {0}ms", stopwatch.ElapsedMilliseconds));
return result;
}
}
- Файл написан в 5499ms
- Файл считывается в память в 455ms
- байт массива отлитого в Инт-массив в 3382ms
Вам придется выполнить преобразование в конце концов. Можете ли вы просто прочитать массив в памяти и использовать BitConverter для получения значений из массива по мере необходимости? –
Возможный дубликат http://stackoverflow.com/questions/3206391/directly-reading-large-binary-file-in-c-sharp-w-out-copying. –
@PatrickHofman: Кажется, он уже знает, как читать файл в памяти. –