Есть скаченный csv файл объемом 1,5 гигабайта. В нем содержится примерно 120 000 000 строк в формате xxxx,yyyyyy. Из них 100 000 это кривые строки с артефактами, эти строки всегда меньше 11 символов.
Задача состоит следующая: обработать файл, и записать правильные строки в новый csv файл. Код, который я написал, отрабатывает эту операцию примерно за 10 часов.
Можно ли эту процедуру по времени сократить?
string line;
using (var file = new StreamReader(File.OpenRead(@"D:\bzip2\decompressed.csv")))
{
while ((line = file.ReadLine()) != null)
{
if( line.Length == 11 )
{
File.AppendAllText(@"D:\bzip2\new.csv", line + Environment.NewLine);
}
}
}
Читайте с буфером, пишите с буфером, и всё будет хорошо
string line;
using (var file = new StreamReader(new BufferedStream(File.OpenRead(@"D:\bzip2\decompressed.csv"), 10*1024*1024)))
using(var writer = new StreamWriter(new BufferedStream(File.OpenWrite(@"D:\bzip2\new.csv"), 10*1024*1024)))
{
while ((line = file.ReadLine()) != null)
{
if (line.Length == 11)
writer.WriteLine(line);
}
}
Скорее всего низкая скорость связана с вызовом File.AppendAllText
. Этот метод каждый раз будет открывать файл, перемещать указатель в его конец, дописывать текст и закрывать файл.
Все операции, кроме дописывания можно выполнить один раз, а не для каждой строки.
const string infile = @"D:\bzip2\decompressed.csv";
const string outfile = @"D:\bzip2\new.csv";
using (var in = new StreamReader(File.OpenRead(infile))
using (var out = new StreamWriter(File.OpenWrite(outfile))
{
string line;
while ((line = in.ReadLine()) != null)
{
if(line.Length >= 11)
out.WriteLine(line);
}
}
цсв упрощенной формы, или же имеет "сложные ячейки" (которые имеют внутри ячейки делимитер/ переход на следующую строку)?
Если таковые имеются, то твое решение НЕРАБОЧЕЕ.
Как и советы даные мной ниже. Как и все другие ответы на даный момент.
Мой ответ базируется на отсутствии сложных ячеек:Тебе нужно сделать буфер чтения в виде нескольких мегабайт текста и обрабатывать именно этот текст.
Если ты делаешь построчно у тебя выходит слишком много операций чтения/записи совсем маленькими кусками. Из-за этого и медленная обработка.
Вот пример кода для чтения файла с буфером через стрим:
using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (BufferedStream bs = new BufferedStream(fs))
using (StreamReader sr = new StreamReader(bs))
{
string line;
while ((line = sr.ReadLine()) != null)
{
}
}
код взят отсюда
Так же оптимизируй операцию записи. Запись для такого размера файла можно делать всего 1-2 раза за все время. Не обязательно аппендить все по каждому чиху.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Как сделать, чтобы если один чекбокс активен, при нажатии на другой выбирался этот чекбокс, а с прежнего галочка удалялась?
Нужно создать нумерованный список в Word, например:
Столкнулся с проблемой, что Тип DataRepeater существует в двух библиотеках, но по сути это одна
Пишу программу, которая переводит число из одной системы счисления в другую, в самом конце программы, когда нужно выводить результат, вылетает...