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

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

Вернуться   Форум программистов > Delphi программирование > Lazarus, Free Pascal, CodeTyphon
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 01.06.2011, 09:06   #11
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

видимо придется делать именно так как я сказал в 7 посте.
я пишу реализацию на месте обьяления, это перенесете как положено.
Код:
type
 WString=object
  private
   FText:WideString
   function GetLength:Integer;
    begin
     Result:=Length(FText);
    end;
   procedure SetLength(Value:Integer);
    begin
     SetLength(FText,Value);
    end;
  public 
   function SaveToStream(Stream:TStream):Integer;
    var i:Integer;
    begin
     Result:=0;
     i:=Length;//длину в переменную
     Inc(Result,Stream.Write(i,SizeOf(i));//сохраняем длину
     if(i<>0) then Inc(Result,Stream.Write(FText[1],SizeOf(WideChar)*i));//если длина не ноль, то сохраняем символы
    end;
   function LoadFromStream(Stream:TStream):Integer;
    var i:integer;
    begin
     Result:=0;
     Int(Result,Stream.Read(i,SizeOf(i));//загружаем длину в переменную
     Length:=i;//устанавливаем длину
     if(i<>0) then Inc(Result,Stream.Read(FText[1],SizeOf(WideChar)*i));//если длина была не нулевая, то читаем файл
    end;
   property Length:Integer read GetLength write SetLength;
   property Text:WideString read FText write FText;
  end;
соответственно придется и в классе который вы используете сделать подобное.

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

Код:
function SaveToStream(Stream:TStream):Integer;
begin
 Result:=0;
 //класс сохраняет свои данные
 Inc(Result,String.SaveToStream(Stream));
end;

function LoadFromStream(Stream:TStream):Integer;
begin
 Result:=0;
 //класс читает свои данные, в том же порядке и в том же формате что записывал
 Inc(Result,String.ReadFromStream(Stream));
end;
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 01.06.2011, 09:14   #12
Lex_Liven
Пользователь
 
Аватар для Lex_Liven
 
Регистрация: 21.04.2010
Сообщений: 15
По умолчанию

Вы опять меня не поняли... Я объявил объект и описал в нем методы GetText и SetText, которые заполняют объект символами из строки и наоборот, формируют из объекта строку.
Код:
  TWString=class
                Len:integer;
                Text:array of WideChar;
                function GetText:WideString;
                procedure SetText(S:WideString);
  end;
Если я объявляю File of WString, то с ним можно работать через write(File,MyWString);
Вопрос сейчас в том, чтобы задать размер для каждого конкретного объекта.
Код:
NameWString:WString30; {здесь все равно не больше 30 символов, мне не нужен массив из 500}
PathWString:WString500; {Путь может быть и больше 30}
Как сделать это? 4 похожих объект и 4 раза повторять описание методов?
Lex_Liven вне форума Ответить с цитированием
Старый 01.06.2011, 09:21   #13
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
Есть предложения по размеру массива внутри? Можно ли сделать его изменяющимся для каждого объекта? Чтобы можно было объявить объект типа WString[50], например?
нет, так как динамический массив в типизированный файл запишется не сам, а лишь указатель на него(то есть белиберда)
Цитата:
Как сделать это? 4 похожих объект и 4 раза повторять описание методов?
ну значит 4 похожих объекта, раз вам хочется через типизированные файлы работать.
Цитата:
Если я объявляю File of WString, то с ним можно работать через write(File,MyWString);
или я старею и в новых Делфи дин массив пишеться нормально?
попробуйте тогда. задать длину массива это SetLength(Array,<длина>);
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.

Последний раз редактировалось Пепел Феникса; 01.06.2011 в 09:25.
Пепел Феникса вне форума Ответить с цитированием
Старый 01.06.2011, 09:39   #14
Lex_Liven
Пользователь
 
Аватар для Lex_Liven
 
Регистрация: 21.04.2010
Сообщений: 15
По умолчанию

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
ну значит 4 похожих объекта, раз вам хочется через типизированные файлы работать.
Дело в том, что WString используется в качестве поля для других объектов
Код:
MoreObject1=object
Name:WString; {длина не более 30}
ID:integer;
{...}
end;
MoreObject2=object
Path:WString; {длина до 500}
ID:integer;
{...}
end;
А вот уже эти объекты и пишутся в типизированные файлы.

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
или я старею и в новых Делфи дин массив пишеться нормально?
Совсем честно - я работаю в Lazarus (Free Pascal). Дин массивы (как и WideString) в файл пишутся в виде указателя, потому и извращаюсь. Использовал бы ShortString и не парился, но нужен Юникод, туды его в качель...
Lex_Liven вне форума Ответить с цитированием
Старый 01.06.2011, 09:49   #15
mss
Заблокирован
 
Регистрация: 27.05.2010
Сообщений: 1,099
По умолчанию

Сам себе геморрой придумал и теперь героически его лечишь)
К чему этот object ? Нет у него в дан.случае никаких преимуществ перед class.

type
TWString=class(TComponent)
..
private
FText: WideString;
..
protected
..
procedure SetText(Value: WideString);
..
published
..
property Text: WideString read FText write SetText;
..
end;

implementation
..
var WString: TWString;
..
SomeStream.WriteComponent(WString); // запись объекта в стрим
..
SomeStream.ReadComponent(WString); // чтение объекта из стрима без регистрации класса, экз-р WString должен на этот момент существовать !
..
WString := SomeStream.ReadComponent(nil); // чтение объекта из стрима с предварительной регистрацией класса, экз-р WString будет создан автоматически, если где-то ПЕРЕД этим была выполнена регистрация класса RegisterClass(TWString)

И всё !) И вуаля !)
Всю заботу о чтении-записи опублик.св-в объекта берет на себя встроенная в RTL стриминг-система Delphi
mss вне форума Ответить с цитированием
Старый 01.06.2011, 13:13   #16
Lex_Liven
Пользователь
 
Аватар для Lex_Liven
 
Регистрация: 21.04.2010
Сообщений: 15
По умолчанию

Нет, не дошло... Я честно пытался понять, но никак.
1. Ладно, про private/protected/published я еще почитаю, чтобы понять, в чем отличия.
2. property Text: WideString read FText write SetText; что значит "read FText" и "write SetText"? SetText - это, надо полагать, моя процедура заполнения массива строкой? Но ведь массива в описанном вами классе уже нет.
3. Как превратить файл в Стрим и что значит регистрация класса?
Lex_Liven вне форума Ответить с цитированием
Старый 01.06.2011, 15:27   #17
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

есть такое слово, сериализация.

хотя, в твоём случае, это из пушки по воробьям. Храни 500 символов и не трать время, диски сейчас огромные, памяти завались, экономить 940 байт можно только в том случае, если планируется хранить миллиарды записей. Чтобы длина не терялась, её можно хранить в поле типа Integer перед массивом символов.

> Использовал бы ShortString и не парился, но нужен Юникод, туды его в качель..

путаем белое и горячее. Что мешает хранить UTF8 в ShortString?
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 01.06.2011, 15:55   #18
Lex_Liven
Пользователь
 
Аватар для Lex_Liven
 
Регистрация: 21.04.2010
Сообщений: 15
По умолчанию

Цитата:
Сообщение от veniside Посмотреть сообщение
Храни 500 символов и не трать время, диски сейчас огромные, памяти завались, экономить 940 байт можно только в том случае, если планируется хранить миллиарды записей. Чтобы длина не терялась, её можно хранить в поле типа Integer перед массивом символов.

> Использовал бы ShortString и не парился, но нужен Юникод, туды его в качель..

путаем белое и горячее. Что мешает хранить UTF8 в ShortString?
Я и храню, пусть не миллиарды, но миллионы есть. Длину пишу в интежер, если вы невнимательно смотрели описание объекта.

А насчет белого и горячего - ShortString - это ВСЕГДА 1 байт на символ. А кириллица в UTF8 пишется ДВУМЯ байтами.
Lex_Liven вне форума Ответить с цитированием
Старый 01.06.2011, 15:57   #19
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Цитата:
Я и храню, пусть не миллиарды, но миллионы есть
А зачем такое делать у себя в коде? Почему бы не использовать БД вроде какой-нибудь SQLite?
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 01.06.2011, 15:58   #20
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

> Длину пишу в интежер, если вы невнимательно смотрели описание объекта.

каюсь, невнимательно )

> ShortString - это ВСЕГДА 1 байт на символ. А кириллица в UTF8 пишется ДВУМЯ байтами.

да хоть десятью, какая разница?
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как записать файл UNICODE ? MakTpaxep Общие вопросы C/C++ 0 24.02.2011 17:05
как создать проект содержащий ОДИН файл в visual LOST94 Visual C++ 4 23.06.2010 16:17
Дан файл, содержащий текст на русском языке.Составить в алфавитном порядке список слов в файл. JiLiYa Паскаль, Turbo Pascal, PascalABC.NET 3 26.12.2008 12:05
Как записать файл в файл программы? Хамяг Общие вопросы Delphi 2 02.11.2008 16:01
как записать record в файл Kn793 Общие вопросы Delphi 5 01.08.2008 08:10