Текущий архив: 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.47 MB
Время: 0.038 c