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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 31.08.2011, 23:31   #1
Crystallon
Форумчанин
 
Регистрация: 05.04.2010
Сообщений: 273
Вопрос TMemoryStream и TFileStream есть ли различия?

TMemoryStream и TFileStream вроде бы одинаковые по функциям типы(ну или компоненты, не знаю как в данном случае правильней) и работать они по идее должны одинаково(разница только в том что первая пишет в память процесса в вторая в файл, так ведь?), но при создании дампа памяти вторая пишет его в файл без проблем, а первая как я понимаю затыкается когда видит "нестандартный" символ(которых при дампе памяти разумеется выводится дофига), туже особенность я заметил у TStringList и string, если записывать в них текст с "нестандартными" символами в 1 заход то все нормально, но если после записи такого текста попробовать добавить в этот TStringList или string еще какой угодно текст он просто не добавляется и текст в обоих остается таким как был до добавления(как я понимаю эта проблема в самой реализации этих типов и они просто "не понимают" как прибавить новый текст к тому что уже есть если какие-то символы в уже имеющемся тексте им непонятны/незнакомы). В итоге я сделал вывод что записать текст с этими самыми нестандартными символами можно только в один заход, что для меня проблематично.
Собственно мой вопрос заключается в следующем - есть ли какие-то альтернативы этим типам которые не имели бы такой проблемы?
Заранее спасибо за информацию по данному вопросу(даже если вопрос не решаем все равно не помешали бы ссылки где написано почему это происходит т.к. вопрос мне непонятен и интересен).
Crystallon вне форума Ответить с цитированием
Старый 01.09.2011, 00:03   #2
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Эта штука называется иерархией(Вы вообще delphi хелп открываете когда-нибудь)?

TStream имеет наследника TMemoruStream которые также делится на наследников TStringStream,TFileStream и т.д. по сути каждый наследник упрощается работу со своим предком. Получается что код в 5 строк с использованием TFileStream насммного лучше кода в 50 строк при работе с TStream.

При этом каждый наследник наследует все свойства и методы своего предка.

это называется иерархией.

А записывать байты как текст нужно ещё уметь! Вот в этом ваша проблема. Открыв справку, и почитав её, вы бы поняли причину проблемы, не создали бы такую глупую тему:
"Я записываю байты на прямую как текст, но они не записываются". Очень подходит выражение: "Или лыжи не едут, или я Еб****".
Человек_Борща вне форума Ответить с цитированием
Старый 01.09.2011, 00:16   #3
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

TMemoryStream - обёртка вокруг блока памяти.
TFileStream - обёртка вокруг файла.

Вот и вся разница.

Цитата:
есть ли какие-то альтернативы этим типам которые не имели бы такой проблемы?
Проблема не в них, а в коде, который их использует. Оба потока работают в двоичном режиме и не имеют никаких ограничений.

Альтернативы - полно. Вместо TMemoryStream - любые другие средства по работе с памятью. Указатели. Вместо TFileStream - любые другие средства по работе с файлами.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 01.09.2011, 00:31   #4
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Вариант решения проблемы это - это доступ 2 потоков к одному обьекту.
1 поток пишет 1 байт, записав отправляет, сообщение 2 потоку(В сообщение позиция нового байта в файле), 2 поток считывает появившийся байт и перезданной позиции, и отправляет сообщение об этом 1 потоку и так далее...

По моему это семафор.

Последний раз редактировалось Человек_Борща; 01.09.2011 в 00:33.
Человек_Борща вне форума Ответить с цитированием
Старый 01.09.2011, 01:17   #5
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

Никаких проблем у TMemoryStream (равно как и у string) с "нестандартными" символами нет, ищите проблемы в своём коде.

> По моему это семафор.

а по-моему это бред )
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 01.09.2011, 01:25   #6
Crystallon
Форумчанин
 
Регистрация: 05.04.2010
Сообщений: 273
По умолчанию

Да и правда нестандартными символами я назвал байты...и да это наверно выглядит очень глупо и наверно таковым и является :D
---
veniside
По поводу отсутствия проблем - ну если я вам скину файл дампа памяти процесса и вы загрузите его в TMemoryStream простой функцией LoadFromFile и скажите мне в чем секрет "уличной магии" я буду только за =)
---

И все же мне интересно почему при первой записи в пустой TMemoryStream/TStringStream/TStringList итд итп с помощью функции Write все эти байты итп спокойно в него влезают а добавить к уже имеющемуся содержимому он после этого ничего не может(тоже касается и обычного string)? Вернее даже перефразирую - почему возможна первая запись если невозможна вторая? Я не думаю что мне поможет ответ, мне просто интересно т.к. это по моему как минимум странно. И таже фигня происходит если попробовать вывести это содержимое в обычный memo, выводится все до первого непонятного memo символу включая этот самый символ, все что после тупо игнорируется(я так понимаю это по той причине что мемо читает по 1 байту а не все целиком...).

Последний раз редактировалось Crystallon; 01.09.2011 в 01:30.
Crystallon вне форума Ответить с цитированием
Старый 01.09.2011, 01:42   #7
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

> почему возможна первая запись если невозможна вторая?

ответ не меняется: из-за кривизны вашего кода.

Код:
procedure TForm1.Button1Click(Sender: TObject);
var
  D1, D2: Byte;
begin
  D1 := 200;
  D2 := 202;
  //
  with TMemoryStream.Create() do try
    //
    Write(D1, 1); // "первая" запись
    Write(D2, 1); // "вторая" запись (третья и последующие тоже сработают, проверьте у себя)
    //
    Seek(0, soFromBeginning);
    D1 := 0; // для пущей наглядности
    D2 := 0;
    //
    Read(D1, 1);
    Read(D2, 1);
  finally
    Free();
  end;
  //
  if (D1 <> 200) or (D2 <> 202) then
    ShowMessage('Кажется, мир сошёл с ума?')
  else
    ShowMessage('Crystallon, учи матчасть!');
end;
> если я вам скину файл дампа памяти процесса и вы загрузите его в TMemoryStream простой функцией LoadFromFile и скажите мне в чем секрет "уличной магии" я буду только за =)

хм.. а что именно не так с LoadFromFile()? Размер загруженных данных не совпадает с размером файла? Или какие-то байты искажаются?

> если попробовать вывести это содержимое в обычный memo

мемо может обрезать неугодные данные, никакой магии тут нет. Оно расчитано на текст, всё-таки, а не бинарные данные.
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 01.09.2011, 02:18   #8
Crystallon
Форумчанин
 
Регистрация: 05.04.2010
Сообщений: 273
По умолчанию

http://rghost.ru/20069321
Вот файл дампа памяти процесса, если бы LoadFromFile из него хоть что-то загрузило то SizeOf(TMemoryStream) нам показало бы не 4 байта, ведь так? Или я не правильно понимаю как и когда работает функция SizeOf?
Crystallon вне форума Ответить с цитированием
Старый 01.09.2011, 02:24   #9
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

> SizeOf(TMemoryStream) нам показало бы не 4 байта, ведь так?

SizeOf() возвращает размер переменной. В данном случае переменная у нас — это экземпляр класса TMemoryStream, то бишь пресловутый указатель. Учитывая, что свежая Дельфи доступна далеко не всем, можно утверждать, что размер указателя у вас будет 4 байта с большой степенью вероятности.

А если мы хотим узнать, сколько байт загрузилось в поток, так для этого у него есть свойсво Size.

> Или я не правильно понимаю как и когда работает функция SizeOf?

Код:
ShowMessage('Crystallon, учи матчасть!');
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Сходства и различия Linux и Windows. Ibanez Wizard Операционные системы общие вопросы 4 15.07.2011 22:08
Различия impulsgraw Общие вопросы Delphi 2 04.06.2011 18:49
Различия Dev++ и C++& Демик Помощь студентам 8 01.02.2011 23:48
Существеют ли принципиальные различия в синтаксесе С и С++ покаЧайник Общие вопросы C/C++ 2 04.10.2009 19:25