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

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

Запись в файл и чтение из файла записи: есть запись:


Страницы:   1 2

EgorovAlex ©   (2008-06-16 14:54:00) 

record
 s1,
 s2: PWideChar;
end;

Как мне её записать в файл и потом прочитать из файла?

пробовал так: MS: TMemoryStream;

MS.Write(Rec^, SizeOf(Rec));
MS.Position := 0;
MS.WriteToFile...

но потом при чтении из файла (тоже через мемористрим) не читаются s1 и s2.

Что я не так делаю?


EgorovAlex   (2008-06-19 16:14:00) [1]

Это здесь не нужно, просто по инерции на упрощённыи пример перекинул, а в D2007 WStrLen уже в WideStrUtils есть.
Да, с прибавлением единицы перед записью проблема решилась


Sapersky   (2008-06-19 15:51:00) [2]

Насколько я понял, WStrLen (из TntWideStrUtils), даёт длину без завершающего #0, а в WStrAlloc её нужно указывать с учётом нуля, во всяком случае, WStrNew берёт Size := WStrLen(Str) + 1.

И вот это зачем:
MS.WriteBuffer(Rec^, SizeOf(TMyRec));
MS.ReadBuffer(Rec^, SizeOf(TMyRec));


EgorovAlex   (2008-06-19 12:46:00) [3]

Опять вопрос:
Сейчас записываю в стрим так:

type
 PMyRec = ^TMyRec;
 TMyRec = record
   S: PWideChar;
 end;
var
 Size: Cardinal;
 MS: TMemoryStream;
 Rec: PMyRec;

MS.WriteBuffer(Rec^, SizeOf(TMyRec));
if Assigned(Rec.S) then
 Size := WStrLen(Rec.S)
else
 Size := 0;
MS.WriteBuffer(Size, SizeOf(Size));
MS.WriteBuffer(Rec.S^, Size*SizeOf(WideChar));


а читаю так:

var
 Buf: WideString;

MS.ReadBuffer(Rec^, SizeOf(TMyRec));
MS.ReadBuffer(Size, SizeOf(Size));
if (Size > 0) then
begin
 SetLength(Buf, Size);
 MS.ReadBuffer(PWideChar(Buf)^, Size*SizeOf(WideChar));
 Rec.S := WStrNew(PWideChar(Buf));
end;


и всё работает нормально, но если я пытаюсь избавиться от промежуточного буфера и читать так:

MS.ReadBuffer(Rec^, SizeOf(TMyRec));
MS.ReadBuffer(Size, SizeOf(Size));
if (Size > 0) then
begin
 Rec.S := WStrAlloc(Size);
 MS.ReadBuffer(Rec.S^, Size*SizeOf(WideChar));
end;


то в конце строки Rec.S появляется какой-то мусор. Почему?


Sapersky   (2008-06-17 13:55:00) [4]

На всякий случай повторю: запись должна быть с WideString, не WideChar. Собственно, с чем оно будет работать, с чем нет - расписано в комментарии в начале модуля TypInfoEx.
http://sapersky.narod.ru/files/TypInfoEx.rar


EgorovAlex   (2008-06-17 13:38:00) [5]

Все мы когда-то в чём-то начинающие, не томи, показывай :)


Sapersky   (2008-06-17 13:15:00) [6]

Для записи с WideString могу предложить хакерский метод, позволяющий писать/читать запись одной командой. Но вам, как начинающему, возможно, лучше о нём не знать :)


EgorovAlex   (2008-06-17 12:47:00) [7]

Для такой записи всё просто, она же фиксированной длины, да к тому же и не юникодная


Palladin   (2008-06-17 11:53:00) [8]


> Идея рассматривалась на http://forum.sources.ru

однако растут :) какие великие идеи рассматривать начали


Василий Жогарев   (2008-06-17 11:30:00) [9]


>  Запись в файл и чтение из файла записи: есть запись:
>
> EgorovAlex ©   (16.06.08 14:54)  


type
 TRow = packed record
   Value1: String[32];
   Value2: String[32];
   Value3: LongInt;
 end;

var
 Rows: array[1..16] of TRow;


var
 F: file of TRow;
 i: Integer;
begin
 // Вносим значения.
 {Rows[1].Value1 := 'Значение 1';
 Rows[1].Value2 := 'Значение 2';
 Rows[1].Value3 := 3;}

 AssignFile(F, './rows.my');
 Rewrite(F);

 try
   for i:= 1 to 16 do
   Write(F, Rows[i]);
 finally
   CloseFile(F);
 end;


var
 Row: TRow;
 F: file of TRow;
begin
 AssignFile(F, './rows.my');
 Reset(F);
 try
   while not Eof(F) do
     begin
       Read (F, Row);
       // Получаем значения.
       {Row.Value1...}
     end;
 finally
   CloseFile(F);
 end;
end;


Идея рассматривалась на http://forum.sources.ru


Поросенок Винни-Пух   (2008-06-17 11:05:00) [10]

тебе перепечатать сюда штатную справку?


EgorovAlex   (2008-06-17 10:57:00) [11]

Что за функции работы со строками? Какие преимущества они дадут?


Поросенок Винни-Пух   (2008-06-17 10:41:00) [12]

1. New(Rec2) красивше чем гетмем в этом случае.
2. Память под строки распределять надо и надо копировать сами строки если хочешь именно дубликат записи, а не две записи с указателями на один и тот же буфер.
3. Со строками тоже лучше работать через строковые функции а не через гетмем и копимемори


EgorovAlex   (2008-06-17 09:50:00) [13]

С этим разобрался, спасибо, теперь для уточнения моих познаний :)
(т.к. старался всегда использовать только записи с фиксированными полями, а не указателями)

Если у меня есть запись Rec1 и мне нужно сделать её дубликат, то достаточно ли этих двух строк:

type
 PMyRec = ^TMyRec;
 TMyRec = record
   S: PWideChar;
 end;

var
 Rec1, Rec2: PMyRec;

GetMem(Rec2, SizeOf(Rec2));
Rec2^ := Rec1^;

или нужны ещё и эти строки:

GetMem(Rec2.S, Length(Rec1.S)*SizeOf(WideChar));
CopyMemory(Rec2.S, Rec1.S, Length(Rec1.S)*SizeOf(WideChar));


Поросенок Винни-Пух   (2008-06-16 17:10:00) [14]

ридбуфер требует параметром адрес, а не указатель


Поросенок Винни-Пух   (2008-06-16 17:09:00) [15]

Эт я не в ту ветку запостил


EgorovAlex   (2008-06-16 17:05:00) [16]

так нет никаких исключений, но и не читается :(

to TForumHelp

а как читать-то :)


TForumHelp   (2008-06-16 17:02:00) [17]

ну еще бы читалось.


Поросенок Винни-Пух   (2008-06-16 17:01:00) [18]

try
ms := T....Stream.create(...);
except
on E:Exception do ShowMessage('Ой, мама!'#13#10 + E.Message)
end


EgorovAlex   (2008-06-16 16:54:00) [19]

Вроде всё так и написано в приведённом коде, но считать почему-то не получается, читаю так:

MS.ReadBuffer(Size, SizeOf(Size));
if (Size > 0) then
begin
 GetMem(Rec.s1, Size);
 MS.ReadBuffer(Rec.s1, Size);
end;
MS.ReadBuffer(Size, SizeOf(Size));
if (Size > 0) then
begin
 GetMem(Rec.s2, Size);
 MS.ReadBuffer(Rec.s2, Size);
end;


Поросенок Винни-Пух   (2008-06-16 16:50:00) [20]

записать длину первого поля.
записать само первое поле.
записать длину второго поля
записать само второе поле.


Страницы:   1 2

Наверх

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