Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.10.31;
Скачать: CL | DM;

Вниз

Массив в файл   Найти похожие ветки 

 
Justas   (2004-10-08 01:17) [0]

Привет всем!
Есть массив a:array [1..31,1..12] of string . Как его сохранить в файл, а потом прочитать из файла?
Кажется, сохранять можно так

with TFileStream.Create("MyArray.dat", fmCreate or fmOpenWrite) do begin
WriteBuffer(a, SizeOf(a));
Free;

Но, я не знаю, как его потом из файла прочитать
Заранее спасибо


 
GuAV ©   (2004-10-08 01:35) [1]


> with TFileStream.Create("MyArray.dat", fmCreate or fmOpenWrite)
> do begin
> WriteBuffer(a, SizeOf(a));
> Free;
> Но, я не знаю, как его потом из файла прочитать

Из такого файла можно будет прочитать эту переменную, однако от этого много пользы не будет. Видите ли, string - это на самом деле указатель на содержимое строки. При чтении прочитается указатель, но не содержимое, которое не было записано. Указатели потом будут указывать на левые данные и манипуляции с ними опасны...

Самый простой выход shortstring заместо string.
Можно ещё писать сначала длинну строки
I:=Length(S);
WriteBuffer(I, SizeOf(I));
а потом саму
WriteBuffer(S[1], I);
Читать при этом так:
ReadBuffer(I, SizeOf(I));
SetLength(S, I)
ReadBuffer(S[1], I);


 
Defunct ©   (2004-10-08 01:47) [2]

GuAV ©   (08.10.04 01:35) [1]
> Читать при этом так:
> ReadBuffer(I, SizeOf(I));
> SetLength(S, I)


это, а к ShortString разве тоже можно применять SetLength? Помоему это статиский массив, не нужен там SetLength.


 
Defunct ©   (2004-10-08 01:48) [3]

[2]

Соответственно читать при этом так:
ReadBuffer(S[0], 1);
ReadBuffer(S[1], Byte(S[0]));


 
GuAV ©   (2004-10-08 01:55) [4]

Defunct ©   (08.10.04 01:47) [2]
Да я непонятно наверное написал.

или

> shortstring заместо string.


или
Можно ещё писать сначала длинну строки
I:=Length(S);
WriteBuffer(I, SizeOf(I));
а потом саму
WriteBuffer(S[1], I);
Читать при этом так:
ReadBuffer(I, SizeOf(I));
SetLength(S, I)

ReadBuffer(S[1], I);


SetLength для shortstring тоже работает (меняет byte(s[0])), но необходимость приведенного кода отпадает, проще записать все 256 (или меньше) байт строки - и там уже будет и длина.


 
GuAV ©   (2004-10-08 01:56) [5]

C Вами про строки - лучше в другой ветке :)


 
Defunct ©   (2004-10-08 02:11) [6]

Justas   (08.10.04 01:17)  
В общем так, поскольку GuruAV похоже не выспался, а я возможно не полностью понял его ответ, отвечу так:

Есть массив:

A : array [1..31,1..12] of string;

// Запись в файл:
Procedure Save(FileName:String);
Var I,J,L:Integer;
Begin
 With TMemoryStream.Create Do
 Try
   For I:=1 To 31 Do
   For J:=1 To 12 Do
   Begin
     { Для String }
     L := Length(A[i,j]);
     WriteBuffer(L, 4);
     WriteBuffer(A[i,j][1], L);
     { Для ShortString }
     {
     WriteBuffer(A[i,j][0],1);
     WriteBuffer(A[i,j][1], Length(A[i,j]));  
     }
   End;
   SaveToFile( FileName );
 Finally
   Free;
 End;
End;

// Чтение из файла:
Procedure Load(FileName:String);
Var I,J,L:Integer;
Begin
 With TMemoryStream.Create Do
 Try
   LoadFromFile(FileName);
   Position := 0;
   For I:=1 To 31 Do
   For J:=1 To 12 Do
   Begin
     { Для String }
     ReadBuffer(L, 4);
     ReadBuffer(A[i,j][1], L);
     { Для ShortString }
     {
       ReadBuffer(A[i,j][0],1);
       ReadBuffer(A[i,j][1], Byte(A[i,j]));  
     }
   End;
 Finally
   Free;
 End;
End;


1488 байт будут занимать одни только длины строк. А Если использовать ShortString потребуется в 4 раза меньше места на хранение длин строк.


 
Justas   (2004-10-08 02:12) [7]

Извиняюсь, это я сглупил. Должен быть array of integer.
это массив, в котором хранятся координаты компонентов, как их сохранять и читать по указанному вами методу?
Спасибо


 
Justas   (2004-10-08 02:14) [8]

Спасибо народ!!!
Извиняюсь за прошлый пост! Это у меня эксплорер висел долго открытый с написанным сообщением, пока я пытался что-то сделать. А когда не получилось - отослал, но уже куча ответов появилась :)
Спасибо за помощь!


 
Justas   (2004-10-08 02:15) [9]


> Defunct

А как поступать для integer?


 
Defunct ©   (2004-10-08 02:29) [10]

Можно аналогично, достаточно одной строчки при записи:

WriteBuffer(A[i], 4);

при чтении:

ReadBuffer(A[i], 4);


 
Германн ©   (2004-10-08 02:34) [11]

2 Justas   (08.10.04 02:15) [9]
Ну ты гад! Взял два кирпича. Одним ударил по GuAV, другим по Defunct. (И сделал вид, что это они друг друга!).

А они лезли вон из кожи, что бы помочь с проблемой сохранения/чтения строк в файл и из файла!

А какие проблемы волнуют тебя? Может объяснишь наконец!


 
Justas   (2004-10-08 02:37) [12]


> Defunct

при чтении получаю ошибку Invalid typecast
как бороться?


 
Justas   (2004-10-08 02:39) [13]


> Германн

ну вообще-то зря ты так..я ж не извращенец сетевой :(
просто раньше у меня данные в прогу грузились из ИНИ-файла..я решил переделать. Когда задавал первый вопрос - думал сделать так, но потом увидел. что сохранять чиста в сиде string тупо, и задал другой вопрос..
извиняюсь, если обидел кого-то


 
Defunct ©   (2004-10-08 02:46) [14]

> при чтении получаю ошибку Invalid typecast

Где именно? Приведите код чтения с указанием места ошибки.


 
Justas   (2004-10-08 02:46) [15]

Все работает!
Премного благодарен за помощь!


 
Justas   (2004-10-08 02:48) [16]


> ReadBuffer(A[i,j][1], Byte(A[i,j]));  

В этом месте выдавал ошибку Invalid typecast
Надо было написать ReadBuffer(A[i,j][1], Byte(A[i,j][0]));   и заработало
спасибо


 
Defunct ©   (2004-10-08 02:53) [17]

> что сохранять чиста в виде string тупо

Смотря что сохранять, файлы исходных данных и результатов должны быть повозможности доступными из других редакторов, пользователь должен иметь возможность изменять/просматривать исх. данные/результаты вручную в любом текстовом редакторе.


 
Justas   (2004-10-08 02:55) [18]


> Defunct

Тут просто координаты элементов управления. Так что вряд ли их понадобится редактировать вручную. Хотя маленький редактов я написал - но отдельный


 
Defunct ©   (2004-10-08 02:57) [19]

ic


 
Justas   (2004-10-08 03:11) [20]

для ини-файла написал в смысле


 
Zeon   (2004-10-08 03:12) [21]

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


 
Amoeba ©   (2004-10-08 11:08) [22]


> Zeon   (08.10.04 03:12) [21]

Ну, это уже называется делать через одно известное место. Использвание двоичного файла для данной задачи проще и эффективнее.


 
GuAV ©   (2004-10-08 12:59) [23]

Так. Определяемся:
с типом элемента массива.
с размерностью.
статический или динамический.

от этого зависит ответ. возможно его можно будет читать-записывать за одну или две ReadBuffer-WriteBuffer.


 
Justas   (2004-10-09 01:09) [24]


> Zeon

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


> GuAV

Массив статический.


> Defunct

Большое спасибо за код. Пользоваться прогой стало намного удобнее :)


 
GuAV ©   (2004-10-09 01:17) [25]


> Массив статический.

Статический, да ещё из Integer.
Тогда совсем просто
запись
WriteBuffer(a, SizeOf(a));
чтение
ReadBuffer(a, SizeOf(a));


 
Zeon ©   (2004-10-17 00:54) [26]

> Justas
Интересно, чем тут неудобно читать?
Про команду Seek сышал?

А кроме того еще и дебажить крайне удобно, так как такой файл всегда можно просмотрель любым текстовам редактором.



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

Текущий архив: 2004.10.31;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.027 c
3-1096441296
Maxim_____
2004-09-29 11:01
2004.10.31
string conversion error


1-1097870045
Мирон
2004-10-15 23:54
2004.10.31
TXPManifest уличен во вредительстве


1-1097951236
kmi
2004-10-16 22:27
2004.10.31
Как определить, запущено ли приложение из IDE


1-1098077604
вик
2004-10-18 09:33
2004.10.31
Как можно получить диапазон Excel


3-1096693515
DelphiN!
2004-10-02 09:05
2004.10.31
Перевод базы данных в HTML