![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как мне перевести свой тип в поток? [D7, WinXP]
Dmitry_04 © (2005-01-14 14:04:00)Как мне перевести свой тип в поток? Т.е. я создал свой тип:
type
...=record
...
end;
Как мне его перевести в TMemoryStream и обратно?
begin...end (2005-01-14 18:22:00) [1]> [42] Dmitry_04 (14.01.05 17:25)
Существует ещё такое понятие, как текущая позицияпотока. После того, как Вы записываете в поток какую-то переменную с помощью метода Write, позиция (представьте, что это некий указатель внутри потока) смещается (увеличивается) на величину размера записанной переменной.
Например, сразу после создания потока эта позиция равна 0. После записи переменной fmv значение этой позиции увеличится на величину количества записанных байт, т.е. на SizeOf(fmv). Если теперь снова вызвать метод Write и записать в поток переменную tmv, то она запишется, начиная с текущей позиции, а сама позиция после этого увеличится на величину SizeOf(tmv). Узнать значение этой позиции мы можем в любой момент, прочитав свойство потока Position.
Итак, после записи двух переменных в поток (после выполнения первой части кода [42]) указатель внутри потока будет указывать на, извините за выражение, конец потока.
Далее Вы хотите прочитать эти переменные. Но после вызова метода Read чтение всегда начинается не с начала потока, а именно с текущей позиции. А поскольку текущая позиция в данный момент - это конец потока, то ничего и не прочитается.
Чтобы всё же прочитать эти переменные, перед чтением нужно сместиться в начало потока. Сделать это можно, например, присвоивсвойству Position значение 0. Если теперь вызвать метод Read, то чтение начнётся именно с начала потока, и можно будет прочитать сначала переменную fmv, а потом - tmv, т.е. в том порядке, в котором Вы их и записывали.
Таким образом, всё, что нужно сделать - это просто добавить строку mstrm.Position := 0;вместо многоточия в [42]. Ну и читать-то уж желательно для проверки уже в другие переменные, а не в те же самые (а иначе как Вы узнаете, что содержимое переменных после чтения - это результат именно чтения, а не то же самое, что было там и до чтения?), или как-то обнулять их перед чтением.
Т.е. код будет такой:
type
TMyVar = record
...
end;
var
mstrm: TMemoryStream;
fmv1, tmv1, fmv2, tmv2: TMyVar;
begin
mstrm := TMemoryStream.Create;
try
// Записываем что-нибудь в fmv1 и tmv1
...
// Записываем fmv1 и tmv1 в поток
mstrm.Write(fmv1, SizeOf(TMyVar));
mstrm.Write(tmv1, SizeOf(TMyVar));
// Сброс указателя
mstrm.Position := 0;
// Читаем содержимое потока в fmv2 и tmv2
mstrm.Read(fmv2, SizeOf(TMyVar));
mstrm.Read(tmv2, SizeOf(TMyVar));
// Теперь нужно сравнить то, что записывали, с тем, что прочиталось,
// т.е. fmv1 c fmv2, а tmv1 с tmv2. Т.к. в Вашем случае эти переменные
// представляют собой записи, то оператор "=" не подойдёт. В таких
// случаях для сравнения используют функцию CompareMem
if CompareMem(@fmv1, @fmv2, SizeOf(TMyVar)) and CompareMem(@tmv1, @tmv2, SizeOf(TMyVar)) then
ShowMessage('Всё записалось и прочиталось удачно!')
finally
mstrm.Free
end
end.
GrayFace (2005-01-14 17:51:00) [2]> Dmitry_04
Почитай статью "Динамические структуры данных".
begin...end (2005-01-14 17:42:00) [3]> [42] Dmitry_04 (14.01.05 17:25)
После выполнения этого кода значения переменных fmv и tmv, действительно, не изменятся. Но только лишь потому, что из потока фактически ничего не прочитается .
Dmitry_04 (2005-01-14 17:27:00) [4]сейчас проверю :)
Александр Иванов (2005-01-14 17:27:00) [5]Dmitry_04 (14.01.05 17:25) [42]
А проверить слабо?
Dmitry_04 (2005-01-14 17:25:00) [6]а если я сделаю так:
mstrm.Write(fmv, SizeOf(fmv));
mstrm.Write(tmv, SizeOf(tmv));
...
mstrm.Read(fmv, SizeOf(fmv));
mstrm.Read(tmv, SizeOf(tmv));
я правильно получу обратно из потока переменные fmv и tmv?
Digitman (2005-01-14 17:04:00) [7]надо же ! и меня, кстать, тоже)
пора делать выводы ?
begin...end (2005-01-14 16:58:00) [8]> [39] Dmitry_04 (14.01.05 16:57)
Понимание Вами этого факта меня радует.
Dmitry_04 (2005-01-14 16:57:00) [9]он увидит второй кораблик :)
Digitman (2005-01-14 16:51:00) [10]
> мне перед тем как записывать писать mstrm.Clear?
а ты сам себе задайся вопросом - а зачем собственно ? и что произойдет при вызове Clear() ?
вот река - это поток ... сомнений не вызывает этот факт, надеюсь ?
вот ты пустил по реке бумажный кораблик .. через минуту - еще один ..
тот кто ловит ниже по реке твои кораблики, поймает сначала первый пущенный тобой. затем через минуту - второй ... сомнений это не вызывает ?
теперь представь что ты пустил кораблик и тут же "очистил" реку, вместе со всем дерьмом что она несет, включая твой кораблик, и затем пустил следующий ... ЧТО увидит тот кто ожидает твои кораблики ниже по течению ?
Dmitry_04 (2005-01-14 16:46:00) [11]ой... что-то я вообще сегодня торможу..... там Write надо... ну я вообще...:)
begin...end (2005-01-14 16:44:00) [12]> Dmitry_04 (14.01.05 16:39) [35]
> Вот если я в поток уже записывал переменную, а теперь надо
> другую переменную этого-же типа записать... мне перед тем
> как записывать писать mstrm.Clear?
Если Вам надо, чтобы в потоке была всегда записана ОДНА переменная - естественно, поток надо перед каждой записью очищать. Если Вы хотите туда записать НЕСКОЛЬКО переменных, то записывайте их с помощью Write последовательно.
Правда, из кода [35] я не вижу, что там что-то записывается. Там из потока читается переменная, затем он очищается, а затем Вы пытаетесь из ПУСТОГО ПОТОКА прочитать что-то ещё.
Dmitry_04 (2005-01-14 16:39:00) [13]begin...endОй... сорри! Я эти строчки сверху скопировал и не увидел... Сорри!
mstrm.Read(fmv, SizeOf(fmv));
...
mstrm.Clear;
mstrm.Read(tmv, SizeOf(tmv));
begin...end (2005-01-14 16:36:00) [14]> Dmitry_04 (14.01.05 16:34) [33]
> mstrm.Read(fmv, SizeOf(mstrm));
Вы что - издеваетесь, что ли?
Dmitry_04 (2005-01-14 16:34:00) [15]У меня тут еще один простенький вопросик возник... Вот если я в поток уже записывал переменную, а теперь надо другую переменную этого-же типа записать... мне перед тем как записывать писать mstrm.Clear? Т.е.
mstrm.Read(fmv, SizeOf(mstrm));
...
mstrm.Clear;
mstrm.Read(tmv, SizeOf(mstrm));
или тут без разницы? можно и не писать?
Digitman (2005-01-14 16:22:00) [16]
> Dmitry_04 (14.01.05 15:47) [31]
> наверно :) так наверно еще лучше будет :)
может и лучше .. но понимания происходящего это не добавит
таки все же вникни в спр.материалы по длинным строкам - оно хуже не будет и рано или поздно пригодится.
Dmitry_04 (2005-01-14 15:47:00) [17]наверно :) так наверно еще лучше будет :)
Семен Сорокин (2005-01-14 15:30:00) [18]
> Dmitry_04 (14.01.05 15:25) [29]
> все... я все понял! Спасибо всем! :))) Мне не надо было
> string использовать, я переделал на shortstring и все нормуль!
> :) У меня всеравно там одно слово хранится...:)
может стоит тогда в string[20] переделать?
Dmitry_04 (2005-01-14 15:25:00) [19]все... я все понял! Спасибо всем! :))) Мне не надо было string использовать, я переделал на shortstring и все нормуль! :) У меня всеравно там одно слово хранится...:)
Kerk (2005-01-14 15:23:00) [20]Dmitry_04 (14.01.05 15:20) [27]
тебе уже раз пять ответили. ты читать умеешь?