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

Вниз

Как мне перевести свой тип в поток?   Найти похожие ветки 

 
Dmitry_04   (2005-01-14 14:04) [0]

Как мне перевести свой тип в поток? Т.е. я создал свой тип:

type
 ...=record
   ...
 end;


Как мне его перевести в TMemoryStream и обратно?


 
begin...end ©   (2005-01-14 14:07) [1]

> Dmitry_04   (14.01.05 14:04)

TMemoryStream хранит данные, а не типы.

Если Вы имели в виду запись переменной указанного типа в TmemoryStream, то так:

type
 TMyType = record
   ...
 end;

var
 MyVar: TMyType;

begin
 ...
 MemoryStream.Write(MyVar, SizeOf(MyVar))
 ...
end.


 
Kerk ©   (2005-01-14 14:08) [2]

Наследуйся от TComponent для начала


 
Dmitry_04   (2005-01-14 14:11) [3]

Да... begin...end вы меня правильно поправили... т.е. переменную моего типа...


 
Kerk ©   (2005-01-14 14:13) [4]

Dmitry_04   (14.01.05 14:11) [3]
сорри думал отвечал про классы.. :)
[1] прав


 
Dmitry_04   (2005-01-14 14:13) [5]

а как обратно перевести из TMemoryStream в переменную моего типа?


 
Семен Сорокин ©   (2005-01-14 14:13) [6]


> Dmitry_04   (14.01.05 14:11) [3]
> Да... begin...end вы меня правильно поправили... т.е. переменную
> моего типа...

надеюсь про strings, dynamic arrays and pointers помним?


 
Семен Сорокин ©   (2005-01-14 14:14) [7]


> Dmitry_04   (14.01.05 14:13) [5]
> а как обратно перевести из TMemoryStream в переменную моего
> типа?

если записать -  write
то по логике, прочитать - ... (догадайтесь сами) :)


 
begin...end ©   (2005-01-14 14:15) [8]

> [5] Dmitry_04   (14.01.05 14:13)

У TStream и у его наследника TMemoryStream есть метод Read. Прочитать с его помощью можно в любую переменную (этот параметр там нетипизированный). Главное - следить за размером.


 
Dmitry_04   (2005-01-14 14:16) [9]

Семен Сорокин хорошая идея... :) Попробую "read"


 
Dmitry_04   (2005-01-14 14:17) [10]

begin...end извени за глупый вопрос, но зачем следить за размером?


 
begin...end ©   (2005-01-14 14:18) [11]

> [10] Dmitry_04   (14.01.05 14:17)

Чтобы при чтении заполнить ВСЮ переменную. Не больше, но и не меньше.


 
Dmitry_04   (2005-01-14 14:51) [12]

что-то у меня не получается прочитать всю переменную из потока...:( Что делать?


type
 TMyVar = record
   i: integer;
   s: string;
   b: boolean;
 end;

var
mstrm: TMemoryStream;
fmv: TMyVar;

...

mstrm.Read(fmv, SizeOf(mstrm));


 
Александр Иванов ©   (2005-01-14 14:53) [13]

>mstrm.Read(fmv, SizeOf(mstrm));

>mstrm.Read(fmv, SizeOf(fmv));


 
begin...end ©   (2005-01-14 14:53) [14]

> [12] Dmitry_04   (14.01.05 14:51)

> mstrm.Read(fmv, SizeOf(mstrm))

Вы читаете из потока переменную типа TMyVar. Вам надо указать, сколько байт нужно в эту переменную прочитать. Так почему же Вы указываете вторым параметром в Read размер переменной-потока, а не размер переменной fmv?


 
Александр Иванов ©   (2005-01-14 14:54) [15]

Нужен размер считываемого блока данных, а не указателя :).


 
Digitman ©   (2005-01-14 14:56) [16]


> Dmitry_04   (14.01.05 14:51) [12]


> s: string; !!!!!!!!!



> что-то у меня не получается прочитать всю переменную из
> потока...:( Что делать?


читать в справке все про длинные строки до полного просветления


 
Dmitry_04   (2005-01-14 14:57) [17]

я думал надо так... потому что переменная fmv пустая, в ней ничего нет... вот меня и смутил ее размер...
Но теперь все работает... только почему-то при закрытии программы ошибка какая-то выпадает...:(


 
begin...end ©   (2005-01-14 14:58) [18]

> [16] Digitman ©   (14.01.05 14:56)

О-о-о... Ещё и это...


 
Dmitry_04   (2005-01-14 15:03) [19]

и почему она выскакивает не понимаю...

mstrm.Free; написал...


 
Digitman ©   (2005-01-14 15:06) [20]


> begin...end ©   (14.01.05 14:58) [18]
> О-о-о... Ещё и это...


ладно бы только это ..


> Dmitry_04   (14.01.05 14:57) [17]



> при закрытии программы ошибка какая-то выпадает


и буквы в сообщении об ошибке, конечно же, не знакомые ?


> почему она выскакивает не понимаю


потому что ошибка)


 
Kerk ©   (2005-01-14 15:07) [21]

Dmitry_04   (14.01.05 15:03) [19]
см [16]


 
Семен Сорокин ©   (2005-01-14 15:08) [22]


> Dmitry_04   (14.01.05 15:03) [19]
> и почему она выскакивает не понимаю...

[6] & [16]
PS. Прям как предвидел продолжение :)


 
Dmitry_04   (2005-01-14 15:09) [23]

выскакивает окно ошибки:
"Exception EAccessViolation in module Project1.exe at 00003E1C. Access violation at address 00403E1C in module Project1.exe. Read of address 00956394."

Что это такое вообще не понимаю...


 
Digitman ©   (2005-01-14 15:09) [24]


> Как мне перевести


слово "перевести", миль пардон, ассоциируется с "бабушку через дорогу"...

а для потока (Делфи-объекта, наследника TStream) существуют термины "записать в поток", "прочитать из потока"


 
Dmitry_04   (2005-01-14 15:14) [25]

Digitman Точно! Тему говоришь! :)


 
Digitman ©   (2005-01-14 15:16) [26]


> Dmitry_04   (14.01.05 15:09) [23]
> Что это такое вообще не понимаю...


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

если же сообщение переводить дословно, то оно звучит так :

Возникло исключение класса EAccessViolation в модуле таком-то при выполнении маш.инструкции, находящейся по адресу такому-то.
Исключение возникло из-за нарушения прав доступа к данным по адресу такому-то в модуле таком-то.
Нарушение прав произошло при попытке чтения данных по такому-то адресу.


 
Dmitry_04   (2005-01-14 15:20) [27]

да, но почему она не возникает при чтении? А когда программу закрываешь? Так все записывается и читается отлично...


 
Kerk ©   (2005-01-14 15:23) [28]

Dmitry_04   (14.01.05 15:20) [27]
тебе уже раз пять ответили. ты читать умеешь?


 
Dmitry_04   (2005-01-14 15:25) [29]

все... я все понял! Спасибо всем! :))) Мне не надо было string использовать, я переделал на shortstring и все нормуль! :) У меня всеравно там одно слово хранится...:)


 
Семен Сорокин ©   (2005-01-14 15:30) [30]


> Dmitry_04   (14.01.05 15:25) [29]
> все... я все понял! Спасибо всем! :))) Мне не надо было
> string использовать, я переделал на shortstring и все нормуль!
> :) У меня всеравно там одно слово хранится...:)

может стоит тогда в string[20] переделать?


 
Dmitry_04   (2005-01-14 15:47) [31]

наверно :) так наверно еще лучше будет :)


 
Digitman ©   (2005-01-14 16:22) [32]


> Dmitry_04   (14.01.05 15:47) [31]
> наверно :) так наверно еще лучше будет :)


может и лучше .. но понимания происходящего это не добавит
таки все же вникни в спр.материалы по длинным строкам - оно хуже не будет и рано или поздно пригодится.


 
Dmitry_04   (2005-01-14 16:34) [33]

У меня тут еще один простенький вопросик возник... Вот если я в поток уже записывал переменную, а теперь надо другую переменную этого-же типа записать... мне перед тем как записывать писать mstrm.Clear? Т.е.


mstrm.Read(fmv, SizeOf(mstrm));
...
mstrm.Clear;
mstrm.Read(tmv, SizeOf(mstrm));


или тут без разницы? можно и не писать?


 
begin...end ©   (2005-01-14 16:36) [34]

> Dmitry_04   (14.01.05 16:34) [33]

> mstrm.Read(fmv, SizeOf(mstrm));

Вы что - издеваетесь, что ли?


 
Dmitry_04   (2005-01-14 16:39) [35]

begin...end Ой... сорри! Я эти строчки сверху скопировал и не увидел... Сорри!

mstrm.Read(fmv, SizeOf(fmv));
...
mstrm.Clear;
mstrm.Read(tmv, SizeOf(tmv));


 
begin...end ©   (2005-01-14 16:44) [36]

> Dmitry_04   (14.01.05 16:39) [35]

> Вот если я в поток уже записывал переменную, а теперь надо
> другую переменную этого-же типа записать... мне перед тем
> как записывать писать mstrm.Clear?

Если Вам надо, чтобы в потоке была всегда записана ОДНА переменная - естественно, поток надо перед каждой записью очищать. Если Вы хотите туда записать НЕСКОЛЬКО переменных, то записывайте их с помощью Write последовательно.

Правда, из кода [35] я не вижу, что там что-то записывается. Там из потока читается переменная, затем он очищается, а затем Вы пытаетесь из ПУСТОГО ПОТОКА прочитать что-то ещё.


 
Dmitry_04   (2005-01-14 16:46) [37]

ой... что-то я вообще сегодня торможу..... там Write надо... ну я вообще...:)


 
Digitman ©   (2005-01-14 16:51) [38]


> мне перед тем как записывать писать mstrm.Clear?


а ты сам себе задайся вопросом - а зачем собственно ? и что произойдет при вызове Clear() ?

вот река - это поток ... сомнений не вызывает этот факт, надеюсь ?

вот ты пустил по реке бумажный кораблик .. через минуту - еще один ..

тот кто ловит ниже по реке твои кораблики, поймает сначала первый пущенный тобой. затем через минуту - второй ... сомнений это не вызывает ?

теперь представь что ты пустил кораблик и тут же "очистил" реку, вместе со всем дерьмом что она несет, включая твой кораблик, и затем пустил следующий ... ЧТО увидит тот кто ожидает твои кораблики ниже по течению ?


 
Dmitry_04   (2005-01-14 16:57) [39]

он увидит второй кораблик :)


 
begin...end ©   (2005-01-14 16:58) [40]

> [39] Dmitry_04   (14.01.05 16:57)

Понимание Вами этого факта меня радует.


 
Digitman ©   (2005-01-14 17:04) [41]

надо же ! и меня, кстать, тоже)
пора делать выводы ?


 
Dmitry_04   (2005-01-14 17:25) [42]

а если я сделаю так:

mstrm.Write(fmv, SizeOf(fmv));
mstrm.Write(tmv, SizeOf(tmv));
...
mstrm.Read(fmv, SizeOf(fmv));
mstrm.Read(tmv, SizeOf(tmv));


я правильно получу обратно из потока переменные fmv и tmv?


 
Александр Иванов ©   (2005-01-14 17:27) [43]

Dmitry_04   (14.01.05 17:25) [42]
А проверить слабо?


 
Dmitry_04   (2005-01-14 17:27) [44]

сейчас проверю :)


 
begin...end ©   (2005-01-14 17:42) [45]

> [42] Dmitry_04   (14.01.05 17:25)

После выполнения этого кода значения переменных fmv и tmv, действительно, не изменятся. Но только лишь потому, что из потока фактически ничего не прочитается.


 
GrayFace ©   (2005-01-14 17:51) [46]

> Dmitry_04
Почитай статью "Динамические структуры данных".


 
begin...end ©   (2005-01-14 18:22) [47]

> [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.



Страницы: 1 2 вся ветка

Форум: "Основная";
Текущий архив: 2005.01.30;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.58 MB
Время: 0.039 c
3-1104065212
swinole
2004-12-26 15:46
2005.01.30
Инсталяция BDE


1-1106046599
Ser_max
2005-01-18 14:09
2005.01.30
свойстваTchart


14-1105498891
Ozone
2005-01-12 06:01
2005.01.30
Не могу найти прогу...


1-1106205535
snake_r
2005-01-20 10:18
2005.01.30
TEdit и свойство Text


14-1105523396
Кладовщик
2005-01-12 12:49
2005.01.30
Случайно попал в кладовку :)





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский