Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2006.02.12;
Скачать: [xml.tar.bz2];

Вниз

Как дописать 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.039 c
15-1137880245
lookin
2006-01-22 00:50
2006.02.12
Как по вашему, Кайли Миноуг хорошая певица?


8-1125577299
Sanctus
2005-09-01 16:21
2006.02.12
Webcam


6-1130580983
vishnia
2005-10-29 14:16
2006.02.12
Связь с БД MySQL из Интернет-приложения


2-1138017553
МегаПупс
2006-01-23 14:59
2006.02.12
Directory


6-1131019600
nikk
2005-11-03 15:06
2006.02.12
Получение папок локального компа





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский