pradeep kumar Ответов: 5

Чтение 14 ГБ файла на языке C#


Всем привет,

Я пытаюсь прочитать файл размером 14 ГБ, если какая-либо из этих строк файла содержит слово "NULL", я бы написал эту конкретную строку в отдельном текстовом файле, ниже приведен код, который я пробовал.

мой файл выглядит так

ID|F_NAME|MIDDLE_NAME|L_NAME
1 / ПРАДИП / НУЛЬ / КУМАР

Здесь я хочу найти нуль. Фактическая проблема заключается в том, что размер файла составляет около 14 Гб,я попробовал использовать ReadAllText (), Streamreader.ReadLine() и то, и другое выбрасывает мне исключение памяти. Есть ли способ, которым я могу это сделать?

Немедленная помощь приветствуется!

Спасибо

Что я уже пробовал:

using (FileStream fs = File.Open(Sources_path + "\\" + Filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                    using (BufferedStream bs = new BufferedStream(fs))

using (StreamReader sr = new StreamReader(bs))
                    {
                        
                        sr.ReadToEnd();

}

PIEBALDconsult

Без лишних подробностей я рекомендую просто использовать команду DOS FIND, а не писать что-то.

pradeep kumar

Я попробовал использовать ReadAllText (), readline () его исключение выбрасывания памяти. Проще говоря ниже будет выглядеть содержание

ID|FIRST_NAME|MIDDLE_NAME|LAST_NAME
1 / ПРАДИП / НУЛЬ / КУМАР

Я хочу прочитать строку за строкой или весь контент, найти NULL и записать эту конкретную строку в textpad.

Maciej Los

Вы пробовали использовать ADO.NET (OleDb)?

5 Ответов

Рейтинг:
36

Dave Kreskowiak

У вас нет другого выбора, кроме как читать файл по одной строке за раз. Вы не можете использовать ReadAllLines или что-то подобное, потому что он попытается прочитать весь файл в память в массиве строк. Если у вас нет около 30 ГБ оперативной памяти в машине, вы не сможете прочитать файл.

Кроме того, массив ограничен 2,47-м миллиардом записей. Если у вас больше этого количества строк в файле, вы все равно не сможете прочитать его целиком сразу.

Вы должны читать файл, по одной строке за раз, и обрабатывать каждую строку по мере чтения. Тогда вам не нужно иметь тонны памяти в машине. Вам просто нужно достаточно памяти, чтобы прочитать одну строку файла.

using (StreamReader sw = new StreamReader("filepath")
{
    string line = sw.ReadLine();
    ... process your line data ...
}


Рейтинг:
31

Patrice T

Первое решение: добавить безумное количество памяти. Помните, что файл, скорее всего, будет расти, и Вам также понадобится место для результирующего файла.

Второе решение: прочитайте файл строка за строкой.

Цитата:
Streamreader.ReadLine () выбрасывает мне исключение из памяти.
Невозможно, если вы также не попытаетесь сохранить файл в памяти. Подумайте об этом: нужно ли хранить весь файл в памяти ?
1 строка содержит достаточно информации, чтобы сказать, что с ней делать.

Третье решение: этот файл, скорее всего, взят из базы данных. Более эффективным было бы прямое обращение к базе данных за нулями.


Рейтинг:
2

Matt T Heffron

Это очень просто!

File.WriteAllLines("path to output file", 
                   File.ReadLines(Path.Combine(Sources_path, Filename))
                   .Where(l => l.Contains("NULL")));

Это будет обрабатывать строки по одной за раз, пока они читаются. Он не пытается иметь в памяти все сразу.

Если вы хотите, чтобы сравнение было нечувствительным к регистру, то измените последнюю строку выше на:
.Where(l => l.IndexOf("NULL", StringComparison.OrdinalIgnoreCase) >= 0));


pradeep kumar

Это выглядит довольно интересно, я проверю.! Спасибо

Рейтинг:
2

YrthWyndAndFyre

Вы хотите прочитать его строчку за строчкой. Кроме того, я думаю, что вы, возможно, немного переоцениваете это. Забудьте о буферизации. К тому времени, когда вы видите данные, они уже буферизованы контроллером жесткого диска на диске, драйвером ОС и средой выполнения, так что ваши заботы о буферизации закончены. Используйте StreamReader. ReadLine (), как предлагали другие. Вы обнаружите, что для очень больших объемов таких данных файловая система работает намного быстрее. Оперативная память работает быстрее в принципе, но на практике, если вы заставите ОС перейти в файл подкачки, то вы не закончите свою жизнь. Это версия, где Черепаха бьет зайца.


Рейтинг:
1

pradeep kumar

да ppolymorphe правильно этот файл приходит непосредственно из базы данных, его очевидный вопрос, почему я хочу читать вместо удаления null из базы данных только причины

1. я динамически выбираю столбцы для каждой таблицы ниже приведен мой код для лучшего понимания

DECLARE @colnm VARCHAR(MAX)
SET @colnm=''

SELECT @colnm = @colnm + CASE WHEN DATA_TYPE in ('numeric','decimal') 
	THEN + 'ISNULL(' + 'CONVERT(VARCHAR(50),'+'['+ColumnName +']' + ')' +','+' '''''''' '+')' +'as' +'[' + ColumnName + ']' 
	
	ELSE + 'ISNULL(' +'['+ColumnName+']'+ ','+' '''''''' '+')' +'as'+ '[' + ColumnName + ']'  end +','

FROM   #TMP_FINALCOLUMN COMMA
where Comma.TableName = @TBL_NM


SET @CLM_NM =(SELECT  LEFT(@colnm,LEN(@colnm)-1))


SELECT 'xp_cmdshell '''+'sqlcmd -S SERVER -d DB_NM' 
+ ' -E -Q '+'"'+
+'SET NOCOUNT ON; select ' + @CLM_NM + ' from ' 
+QUOTENAME(View_name)+'"'+
+ ' '+'-o'+' '
+ '"A:\DUMMY\'+view_name+'.txt" -W -w 1024 -s"|"'+'''' as Query
FROM TABLE_NAME where STAT=1 AND VIEW_NAME = @TBL_NM


2. Тем не менее я нашел несколько нулей, когда случайно проверил эти файлы.

В любом случае, спасибо за ваши ответы, я отказался от плана чтения файлов строка за строкой в этом случае :)