Есть скаченный 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 раза за все время. Не обязательно аппендить все по каждому чиху.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Как сделать, чтобы если один чекбокс активен, при нажатии на другой выбирался этот чекбокс, а с прежнего галочка удалялась?
Нужно создать нумерованный список в Word, например:
Столкнулся с проблемой, что Тип DataRepeater существует в двух библиотеках, но по сути это одна
Пишу программу, которая переводит число из одной системы счисления в другую, в самом конце программы, когда нужно выводить результат, вылетает...