Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

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


zorik ©   (2006-01-26 12:13:00) 

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


Zeqfreed   (2006-01-26 17:37:00) [1]

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 сюда переписать?


zorik   (2006-01-26 16:45:00) [2]


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


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


Zeqfreed   (2006-01-26 16:35:00) [3]

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:06:00) [4]

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

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

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


Digitman   (2006-01-26 15:04:00) [5]

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 14:42:00) [6]


> [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;
 {как их объеденить и записать поверх файла?}


Gero   (2006-01-26 12:52:00) [7]

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

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


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

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


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

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

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

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

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


Digitman   (2006-01-26 12:20:00) [10]

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

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


zorik   (2006-01-26 12:19:00) [11]


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


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


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

Есть.

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

Все !


Наверх

Титульная страница Поиск, карта сайта Написать письмо