powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / TMemoryStream и string переменная
3 сообщений из 3, страница 1 из 1
TMemoryStream и string переменная
    #32358766
Просто гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в поток записываю информацию :
первые 8 байт - размер файла,
следующие 4 байта - имя файла
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
var OutputStream :TMemoryStream ;
     filesize:int64 ;
     filename :string ;
...

    OutputStream.Write( FileSize,  8 ) ;
    OutputStream.Write( FileName,  4 ) ;
{запись самого файла в конец потока}    
...


при обратном процессе (чтении потока) хочу узнать имя и размер файла, сам файл извлечь на диск
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
var OutputStream :TMemoryStream ;
     filesize:int64 ;
     filename :string ;
...

    OutputStream.Position :=  0  ;
    OutputStream.Read( FileSize,  8 ) ;
    OutputStream.Position :=  8  ;
    OutputStream.Read( FileName,  4 ) ;
...

переменная filesize считывается замечательно - все правильно
а вот FileName inaccessible value
как лечить?
...
Рейтинг: 0 / 0
TMemoryStream и string переменная
    #32358800
Дмитрий Мыльников
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В Delphi начиная со второй версии по умолчанию все переменные string на самом деле являются указателями, а не переменными. Borland разработала специальный механизм для работы с "длинными строками", которые могут иметь длинну до 2 Gb (если память повзолит). Этот механизм отличается от стандартного Pascal, где строка имеет длину всего 255 символов.
В Pascal срока всегда объявлялась с указанием максимального размера строки, например string[60]. При этом в памяти для такой переменной выделяется 61 байт, а сама строка рассматривается как массив типа char. При этом элемент 0 хранит реальную длину строки, которая в данном примере не может быть больше 60 символов.
В новом механизме работы с длинными строками переменная типа string по умоляанию будет считаться указателем на соответсвующую область памяти, где уже и хранятс сами символы строки. Строка завершается символом 0, точно так же, как в C.
Ошибка, которая возникает у вас, вызвана тем, что вы сохраняете не собственно строку символов, а указатель на эту строку. Но при разных запусках программы эти указатели будут разными. Да и что там в этой области памяти будет хранится тоже неизвестно.
То есть, нужно либо объявить вашу переменную по другому, например
filename :string[200];
тогда Delphi использует старый механизм работы со строками.
Тогда текст поменяется на
...
OutputStream.Write( FileName, 201);
...
OutputStream.Read( FileName, 201) ;
...

Да, строку OutputStream.Position := 8; можно убрать, поскольку после считывания 8 байт указатель и так будет там, где необходимо. :)

Если же хотите работать с длинными строками, то нужно делать так же, как бы вы делали в С.

Выглядеть будет примерно так:

var OutputStream :TMemoryStream ;
filesize:int64 ;
filename :string ;
StrSize:int;
...
OutputStream.Write( FileSize,SizeOf(FileSize)) ;
StrSize:=Length(FileName);
OutputStream.Write(StrSize,SizeOf(StrSize)) ; //сохраняем размер строки
OutputStream.Write( FileName^,StrSize) ; //сохраняем символы строки
{запись самого файла в конец потока}
...

считывание

var OutputStream :TMemoryStream ;
filesize:int64 ;
filename :string ;
StrSize:int;
...
OutputStream.Position := 0 ;
OutputStream.Read( FileSize,SizeOf(FileSize)) ;
OutputStream.Read( StrSize,SizeOf(StrSize)) ; //считываем длину строки
SetLength(FileName,StrSize); //данная функция выделяет под строку необходимое количество байт в памяти
OutputStream.Read( FileName^,StrSize) ; //считываем символы строки
...

Примерно так. :)
...
Рейтинг: 0 / 0
TMemoryStream и string переменная
    #32358813
Anferov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
все верно, только в строке
OutputStream.Write( FileName^,StrSize) ; //сохраняем символы строки
, впрочем как и чтенеие
OutputStream.Read( FileName^,StrSize)
надо вместо FileName^ использовать pointer(FileName)^
...
Рейтинг: 0 / 0
3 сообщений из 3, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / TMemoryStream и string переменная
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]