![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как дописать 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, закрываешь стрим.
Все !