Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Построчное считывание большого файла, Подскажите наиболее удобный способ 
:(
    Опции темы
Newo
Дата 13.1.2010, 17:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 24.12.2008

Репутация: нет
Всего: нет



Суть вот в чем: есть большой файл (может быть больше 10гб), состоит из небольших строчек (разделитель - #13#10), в среднем символов 50 каждая. В каждой строчке записана информация, которую нужно обрабатывать.
Подскажите, пожалуйста, наиболее разумный способ решения этой проблемы.

1. Обычное считывание текстового файла с помощью writeln невозможно, ибо такие большие файлы этим инструментом не поддерживаются.
2. Считать все в StringList нельзя, ибо нет так много памяти
3. Пробовал TJclAnsiMappedTextReader из Jedi Code Library, он тоже отказывается работать с такими большими файлами
4. Пока только мысль завести файловый поток, считывать string фиксированной длины, а из нее уже выделять строчки файла, ища #13#10. Но неудобно будет все это дело компоновать между собой

Заранее спасибо.
PM MAIL   Вверх
bems
Дата 13.1.2010, 17:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 31
Всего: 88



ну это смотря что нужно с ним потом делать. Если обработкуможно вести с более мелкими блоками, то можно читать string фиксированной длины, потом присваивать его TStringList.Text и работать с стринглистом.


--------------------
Обижено школьников: 8
PM MAIL   Вверх
Демо
Дата 13.1.2010, 18:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

Репутация: 30
Всего: 50



Мне кажется, что для обработки таких больших текстовых файлов возможны 2 варианта - маппировать файл в память, и обрабатывать строки вручную, либо то же самое, но с TFileStream.
Впринципе, не так много писанины для этого.


--------------------
    
PM MAIL ICQ Skype   Вверх
Newo
Дата 13.1.2010, 18:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 24.12.2008

Репутация: нет
Всего: нет



Цитата(bems @ 13.1.2010,  17:55)
ну это смотря что нужно с ним потом делать. Если обработкуможно вести с более мелкими блоками, то можно читать string фиксированной длины, потом присваивать его TStringList.Text и работать с стринглистом.

Да, обработка будет идти лишь по строчкам (которые между #13#10). Вашу мысль понял, спасибо

Просто думал, есть более цивильный способ это дело реализовать smile
PM MAIL   Вверх
Snowy
Дата 13.1.2010, 18:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



Код
  TTextFileStream = class(TFileStream)
  private
    buf: AnsiString;
    bp, bs:  Integer;
  public
    eof: Boolean;
    function ReadChar: AnsiChar;
    function ReadLn: AnsiString;
  end;

/////////

{ TTextFileStream }

function TTextFileStream.ReadChar: AnsiChar;
begin
  if (bs = 0) or (bp = bs) then
  begin
    bs := 65536; // размер буфера
    SetLength(buf, bs);
    bs := Read(buf[1], bs);
    if bs < Length(buf) then SetLength(buf, bs);
    if (bs = 0) then eof := True;
    bp := 0;
  end;
  Inc(bp);
  if bp <= bs then Result := buf[bp] else result := #0;
end;

function TTextFileStream.ReadLn: string;
var
  c: Char;
begin
  Result := '';
  while not eof do
  begin
    c := ReadChar;
    if c = #13 then Break;
    if c <> #10 then result := result + c;
  end;
end;


Sample:
Код
var
  fs: TTextFileStream;
  s:  string;
begin
  fs := TTextFileStream.Create('C:\1.txt', fmOpenRead);
  while not fs.eof do
  begin
    s := fs.ReadLn;
    Memo1.Lines.Add(s);
  end;
  fs.Free;
end;


Добавлено через 1 минуту и 49 секунд
Не перегружал Seek - подразумевается, что чтение идёт от начала файла непрерывно.
Если нужны пробросы по файлу, то нужно перегружать Seek - в нём сбросить буфер на 0
PM MAIL   Вверх
Newo
Дата 13.1.2010, 19:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 24.12.2008

Репутация: нет
Всего: нет



Snowy, больше спасибо! Я, конечно, в конечном счете сам что-то подобное бы написал, но куда более сложно и громоздко smile.
Спасибо! smile
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0712 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.