Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 24.05.2009, 15:43   #1
Xardas
Сисадмин
Форумчанин
 
Аватар для Xardas
 
Регистрация: 28.12.2007
Сообщений: 320
По умолчанию Запись структуры TList в файл, проблема с длинными строками типа AnsiString

Всем доброго времени суток... Помогите, пожалуйста, решить проблему. В чем ее суть...

Есть 2 модуля. В одном объявлена структура

Код:
PRec=^TRec; 
  TRec=record 
    r1: String[255];  
    r2: Integer;
    ....
  end;
и в разделе public объявлено List:TList.

В программе после формирования каждую запись заношу в TList:

Код:
NewRec := New(PRec);

//...
// заполнение структуры
//...

List.Add(NewRec);
Во втором модуле, то что добавлено в List, надо записать в файл. Записываю так:

Код:
var
    fs: TFileStream;
    FileName: String;
// .....

begin
fs:=TFileStream.Create(FileName, fmCreate);

// запись других данных

for I := 0 to TForm1(ActiveMDIChild).List.Count - 1 do
    fs.Write(PRec(TForm1(ActiveMDIChild).List[i])^, sizeof(TRec))

// ...
end;
Появилась необходимость в поле записи r1 вмещать строку более 255 символов. Но появляется проблема с тем, что в файл, разумеется, записывается только адрес, который при чтении не имеет смысла. Как записать динамические строки из записи в файл, я представляю... Надо обрабатывать поле r1 отдельно... А как поступить, если использую я для хранения записей TList? Получается, что нужно "вытаскивать" оттуда каждую запись и обрабатывать поле r1 отдельно, но только как... Помогите, пожалуйста, разобраться.

Последний раз редактировалось Xardas; 24.05.2009 в 16:27.
Xardas вне форума Ответить с цитированием
Старый 24.05.2009, 18:20   #2
Ntlegend
Форумчанин
 
Аватар для Ntlegend
 
Регистрация: 12.05.2007
Сообщений: 373
По умолчанию

для хранения длинных строк советую исаользовать WideString

для сохранения в файл узнаешь длинну строки и пишешь ее в начале.. а затем пишешь саму строку.. приблизительно так:
Код:
tpe
  TMyRec = record
    Len:Word;
    Data:array of byte
***

var buf:TMyRec;
     ws:WideString;
     f, br:Cardinal;
begin
  ws:='очень длинная строка.. свыше 255 символов..';
  //определение параметров строки
  buf.Len:=Length(ws);
  SetLength(buf.Data, buf.Len);
  //загоняем ее в массив байт
  CopyMemory(@buf.Data[0], @ws[1], buf.Len);
  //открываем файл для записи, и пишем в него строку
  f:=CreateFile('MyFile.dat', $40000000, 2, nil, 2, 128, 0);
  WriteFile(f, buf, buf.Len+2, br, nil);
  CloseHandle(f);
end;
и потом чтобы прочитать эту строку тебе нада узнать ее длинну.. если нада прочитать следующюю строку - то смещение к ней (опять таки длинну этой строки)..

Код:
var buf:TMyRec;
     ws:WideString;
     f, br:Cardinal;
begin
//открываем файл для чтения
  f:=CreateFile(FileName,GENERIC_READ,FILE_SHARE_READ,nil,OPEN_EXISTING, 0,0);
//читаем первые 2 байта.. тоесть длинну строки..
  ReadFile(f, buf, 2, br, nil);
  SetLength(buf.Data, buf.Len);
//читаем строку в буфер
  ReadFile(f, buf.Data[0], buf.Len, br, nil);
//не забіваем закрывать обращение к файлу когда оно уже не нужно
  CloseHandle(f);
//и с буфера в строку..
  SetString(ws, PChar(@buf.Data[0]), buf.Len);
end;
ну вроде бы все так..

*********************************** ***

и еще.. если тебе нада хранить тока строки - так попробуй TStringList.. он тебе будет удобнее..
Перемен! - требуют наши сердца. Перемен! - требуют наши глаза.
В нашем смехе и в наших слезах, И в пульсации вен:
"Перемен!Мы ждем перемен!"

Последний раз редактировалось Ntlegend; 24.05.2009 в 23:16.
Ntlegend вне форума Ответить с цитированием
Старый 24.05.2009, 20:18   #3
Xardas
Сисадмин
Форумчанин
 
Аватар для Xardas
 
Регистрация: 28.12.2007
Сообщений: 320
По умолчанию

Ntlegend, спасибо... Хотя я представлял, что можно было очистить поле r1 :

Код:
//........
NewRec := New (PRec);

//.....

s := NewRec.r1;
NewRec.r1 := '';

//.....
Затем записать в поток запись с пустым полем r1, считать размер строки и писать ее и строку в поток:

Код:
Len := Length(s);
fs.Write(Len,SizeOf(Len));      
fs.Write(pChar(s)^,Length(s));
Должно работать... А вопрос все-таки теперь как "вынуть" эти записи из TList? Или вообще не использовать этот контейнер?
Xardas вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема с записью структуры в файл JamS007 Общие вопросы C/C++ 5 07.01.2009 23:13
Список структуры (типа база) почему неработает ??? Stark[SG!] Общие вопросы C/C++ 1 15.05.2008 15:25
Работа со строками типа Char Horror Общие вопросы C/C++ 4 02.02.2008 19:45
Как обьявить переменную типа AnsiString глобально Kocapb Общие вопросы C/C++ 6 19.12.2007 05:05