Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Работа с текстовыми файлами больших размеров.


Автор: -----DelphiMan 8.4.2004, 10:08
Меня интересует как имея текстовый фаил
найти внём нужную ЛИНИЮ по 10-ти начальным символам строки
и совершить над этой линией следующие действия:

1) Заменить
2) Переименовать
4) Сместить позицию (Вверх /Вниз)

Конечно это можно былобы сделать открыв фаил в Какомнить Memo или RichEdite
но поскольку размер файла очень большой то на его загрузку и сохранение
уйдёт куча времени.

Автор: x77 8.4.2004, 10:18
FileSeek, BlockRead, BlockWrite.

Автор: -----DelphiMan 8.4.2004, 11:12
Ну и как задать для FileSeek нужную строку ?

Автор: x77 8.4.2004, 11:21
а что, размер линий разный?

тогда

for i := 1 to 10 do
ReadLn (f, s);

после окончания цикла в s будет десятая строка. меняем её как нам надо. потом:

for i := 1 to 9 do
ReadLn (f, s);
WriteLn (f, s);

Автор: x77 8.4.2004, 11:46
а, торможу. тебе ж надо не десятую, а по первым символам.

читай строки, для каждой делай Pos.

Автор: -----DelphiMan 8.4.2004, 16:50
Ну и как используя WriteLn сделать запись скажем
в серидине файла?

Автор: x77 8.4.2004, 20:09
делаешь в цикле ReadLn (f, s), пока не выполнится какое-то условие (не наступит "середина файла", к примеру), а потом делаешь WriteLn.

Автор: Alex 8.4.2004, 20:47
А можно узнать, что вы называете большим файлом?

Автор: RA 8.4.2004, 21:00
Цитата(x77 @ 8.4.2004, 17:09)
делаешь в цикле ReadLn (f, s), пока не выполнится какое-то условие (не наступит "середина файла", к примеру), а потом делаешь WriteLn.

Ошибка будет.
Добавлено @ 21:02
Цитата(alex @ 8.4.2004, 17:47)
А можно узнать, что вы называете большим файлом?

Как я понял это когда размер файла больше Оперативной памяти

Автор: x77 9.4.2004, 15:41
RAdmin, ты имеешь в виду Reset/Rewrite? не будет ;)

Автор: maxim1000 9.4.2004, 15:47
открываем два файла (один из них исходный, другой - для результата)
читаем один по кусочкам
вносим изменения
пишем резуьтат во второй файл
Добавлено @ 15:48
кстати, в виду больших объемов информации не помешало бы пользоваться системными функциями работы с файлами (я тестов не проводил, но по идее они должны быть быстрее)

Автор: Alex 9.4.2004, 15:58
Нет ну всетаки какой файл по размеру?

Автор: x77 9.4.2004, 16:19
alex-co, действительно smile.gif вдруг там вообще без file-mapping'а не обойдёшься. кстати, для действительно больших файлов - на пару гигов - оптимальный вариант.

Автор: RA 9.4.2004, 19:57
Цитата(x77 @ 9.4.2004, 12:41)
RAdmin, ты имеешь в виду Reset/Rewrite? не будет ;)

Ага, ибо либо одно либо другое.


Если Rewrite то придётся весь фаил перезаписывать, а прикинь он весить будет около гига, ну а ресет сам знаешь что даёт smile.gif .


Как вот такой вариант ?
Код


procedure FileReplaceString(const FileName, searchstring, replacestring: string);
var
 fs: TFileStream;
 S: string;
begin
 fs := TFileStream.Create(FileName, fmOpenread or fmShareDenyNone);
 try
   SetLength(S, fs.Size);
   fs.ReadBuffer(S[1], fs.Size);
 finally
   fs.Free;
 end;
 S  := StringReplace(S, SearchString, replaceString, [rfReplaceAll, rfIgnoreCase]);
 fs := TFileStream.Create(FileName, fmCreate);
 try
   fs.WriteBuffer(S[1], Length(S));
 finally
   fs.Free;
 end;
end;






Автор: x77 9.4.2004, 21:21
RAdmin, ты считаешь, что твой вариант будет нормально себя чувствовать при весе файла около гига? smile.gif кстати, объявление string соответствует AnsiString, а у него 2 гига - вообще предел.

нет, народ, для действительно больших файлов надо либо делать файл-маппинг, либо вообще читать напрямую диск.

Автор: RA 10.4.2004, 13:14
x77 ТормоjЮ hehe.gif

Автор: Alex 10.4.2004, 13:50
У меня такое впечатление, что ответ на вопрос интересует всех кроме автора вопроса smile.gif

Автор: ------DelphiMan 10.4.2004, 18:09
Да нет я тут слежу за базаром но пока никто толком не ответил.

а насчёт большого размера то около гигабайта фаил.

Автор: Alex 10.4.2004, 20:02
Если файл у тебя не превышает 2 гигов, то любой из выше приведенных способов тебе подойдет

Автор: RA 11.4.2004, 03:47
Да ты что, переписывать гигабайт этож вообще П****

Автор: p0s0l 11.4.2004, 15:05
Что значит:
1) заменить
2) переименовать

Чем они отличаются ?

и куда делось 3) ?

Если имеется в виду, что нужно заменить строку типа:
"abcdefg" на "klmnopqwertyiotiw", т.е. длина найденной строки может измениться, то это значит, что всю оставшуюся часть файла надо перемещать. Для больших файлов это будет убийство. Единственный приемлимый вариант в этом случае - создавать второй файл и в него писать новую инфу, а потом первый удалить...

Автор: ------DelphiMan 12.4.2004, 11:32
Посол, фаил текстовый так что ущерба не будет.

Автор: x77 12.4.2004, 19:11
да какая нахрен разница, текстовый он или нет. ты что, думаешь, что текстовый файл храниться также, как и выводится - по строчкам? это та же последовательность байтов, в которой периодически встречаются символы возврата картеки и сдвига строки - #13#10. то, что ты видишь по строчно, на самом деле представляет собой непрерывную последовательность символов. в твоём случае, скорее всего, фрагментированную. и эта последовательность будет увеличиваться/уменьшаться.

я бы делал файл-маппинг. по крайней мере, работать будет относительно быстро. но поскольку этот "базар" ты "толковым" не считаешь, сделай, как советует p0s0l - пиши в новый файл. других вариантов я не вижу. работать стандартно, через те же stream'ы, - самоубийство.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)