Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.02.12;
Скачать: CL | DM;

Вниз

Как дописать StringList в текстовый файл?   Найти похожие ветки 

 
zorik ©   (2006-01-26 12:13) [0]

Есть текстовий файл. В конец файла нужно дописать все строчки StringList. Есть ли варианты, кроме перебора всех строчек списка?


 
Digitman ©   (2006-01-26 12:17) [1]

Есть.

Открываешь файл в TFileStream, позиционируешь курсор в конец стрима, читаешь содержимое StringList.Text во врем.буфер, записываешь этот буфер в TFileStream, закрываешь стрим.

Все !


 
zorik ©   (2006-01-26 12:19) [2]


> Digitman ©   (26.01.06 12:17) [1]


Спасибо. Этот вариант будет быстрее, я так понимаю


 
Digitman ©   (2006-01-26 12:20) [3]

Единственное, что может еще понадобиться :
1. перед записью буфера убедиться в том что конец файла не содержит символ EOF. Если содержит, сместить стоящий в конце курсор стрима на один символ назад

2. Перед записью буфера записать в стрим CRLF


 
PZ   (2006-01-26 12:44) [4]

Можно предложить такой вариант:

Var
 List1 : tStringList;   // Список, который надо добавить
 List2 : tStringList;

{
 ......................
 ......................
}

begin
 List2 := tStringList.Create;
 List2.LoadFromFile("Text.txt");
 List2.Add(List1.Text);
 List2.SaveToFile("Text.txt");
 List2.Free;
end;


 
Dmitrij_K   (2006-01-26 12:49) [5]

[4] если только файлы маленькие )


 
Gero ©   (2006-01-26 12:52) [6]

> если только файлы маленькие )

Да, если не больше 2 Гб.


 
zorik ©   (2006-01-26 14:42) [7]


> [4] если только файлы маленькие )


Файлы "большие". Log расчетов


> Да, если не больше 2 Гб.


Больше 2 Гб не будет.

В клиента Win98 128Mb RAM + расчет забирает память в динамические массивы. Поэтому идея была писать по процедурах. Первая создает файл, остальные ее дописывают. Каждая пишет примерно от 1000 до 3000 строк. Процедур 10-20. Точно не знаю сколько, так как еще не дописал, и возможно надо будет некоторые из промежуточных "Log-инить"


> Digitman ©   (26.01.06 12:17) [1]


А со Stream я немного запутался. Не работал раньше. Пока вот что накопал:

var
 f: TFileStream;
 m: TMemoryStream;
begin
 f:=TFileStreamCreate(Filename, fmOpenReadWrite {<- не знаю правильно ли});
 m:=TMemoryStream.Create;
 StringList.SaveToStream(m);
 m.Position := 0;
 {как их объеденить и записать поверх файла?}


 
Digitman ©   (2006-01-26 15:04) [8]

const
 CRLF: String = #13#10;
 EOF: Char = #0;
var
f: TFileStream;
CharBuf: Char;

begin
f:=TFileStream.Create(Filename, fmOpenReadWrite);
try
  if f.Size > 0 then //файл не пуст ?
    begin
      f.Position := f.Size - 1; //позиционируем курсор на последнем символе
      f.ReadBuffer(CharBuf, 1); //читаем символ в буфер
      if CharBuf = EOF then //символ = EOF ?
        f.Position := f.Size - 1; //да, вновь позиционируем курсор на нем - отныне конец файла не здесь, а далее      
      f.WriteBuffer(PChar(CRLF)^, 2); //пишем разделитель строк (в предположении что его нет в конце перезаписываемого ориг.файла)
      StringList.SaveToStream(f); //и наконец пишем собственно блок новых строк с разделителями  
finally
 f.Free;
end;


 
zorik ©   (2006-01-26 16:06) [9]

Спасибо! Все получилось.
Еще 2 маленьких вопросика для образования

1) #13 - это перевод каретки (ентер), а #13#10 что?

2) Когда именно происходить запись в файл. Открыт файл для чтения и для записи. Это происходит при манипуляциях с TFileStream или при его освобождении


 
Zeqfreed ©   (2006-01-26 16:35) [10]

zorik ©   (26.01.06 16:06) [9]

> #13 - это перевод каретки (ентер), а #13#10 что?

http://en.wikipedia.org/wiki/CRLF

> Когда именно происходить запись в файл.

TFileStream = class(THandleStream)

function THandleStream.Write(const Buffer; Count: Longint): Longint;
begin
 Result := FileWrite(FHandle, Buffer, Count);
 if Result = -1 then Result := 0;
end;


function FileWrite(Handle: Integer; const Buffer; Count: LongWord): Integer;
begin
{$IFDEF MSWINDOWS}
 if not WriteFile(THandle(Handle), Buffer, Count, LongWord(Result), nil) then
   Result := -1;
{$ENDIF}
{$IFDEF LINUX}
 Result := __write(Handle, Buffer, Count);
{$ENDIF}
end;


© Borland

С уважением,


 
zorik ©   (2006-01-26 16:45) [11]


> Zeqfreed ©   (26.01.06 16:35) [10]


в Digitman ©   (26.01.06 15:04) [8] нету процедуры Write. После StringList.SaveToStream(f) следует f.Free


 
Zeqfreed ©   (2006-01-26 17:37) [12]

zorik ©   (26.01.06 16:45) [11]
TStringList = class(TStrings)

procedure TStrings.SaveToStream(Stream: TStream);
var
 S: string;
begin
 S := GetTextStr;
 Stream.WriteBuffer(Pointer(S)^, Length(S));
end;


procedure TStream.WriteBuffer(const Buffer; Count: Longint);
begin
 if (Count <> 0) and (Write(Buffer, Count) <> Count) then
   raise EWriteError.CreateRes(@SWriteError);
end;


© Borland

Может и остальной код VCL сюда переписать?



Страницы: 1 вся ветка

Текущий архив: 2006.02.12;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.033 c
1-1136819117
em
2006-01-09 18:05
2006.02.12
является ли listview потокозащищенным


2-1138210666
Proxytel
2006-01-25 20:37
2006.02.12
Обработка события клавиатуры при неактивном окне программы


11-1117993714
Vanek_TV
2005-06-05 21:48
2006.02.12
TKOLToolbar


15-1138119168
Pazitron_Brain
2006-01-24 19:12
2006.02.12
Помогите зарегистрировать домен


2-1138305469
Vetalich
2006-01-26 22:57
2006.02.12
Edit