Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Ошибка чтения разнотипных данных из TFileStream


Страницы:   1 2

dm_member ©   (2012-09-28 18:00:00) 

Вопрос общий, может быть кто-то сталкивался с такой проблемой и может подсказать.

Используя TFileStream, сохраняю в файл данные в такой последовательности: integer, integer, string, integer, string, integer, string и т.д. В общем, инт и строки вперемешку.
При чтении в той же самой последовательности, сбивается где-то на середине, читает одну из строк как пустую, а последнее значение integer выдаёт равным чему-то типа 18834599..
Это я понял, расставив повсюду showmessage с выводом значений.
Причём, скорее всего, ошибка при чтении. Через блокнот видно, что записана в файл вся последовательность полностью, байты вроде правильно идут в нём.

Почему такое может происходить? Код я проверял построчно, последовательность при записи и чтении совпадает. Пустые строки не пишу в файл.


Inovet   (2012-09-28 22:42:00) [1]

Ты даже бне соизволил проверить

> [11] Inovet ©   (28.09.12 21:53)
> read что возвращает?


Inovet   (2012-09-28 22:40:00) [2]

> [19] dm_member ©   (28.09.12 22:36)
> Ты никогда по существу не пишешь, да?

Ты дай мне код,
мезмозглый мастер,
а дашь не тот,
сам копипасти.

Так понятнее? Негатив тут пока от одного человека, уж не знаю, на кого обиженного.:)


dm_member   (2012-09-28 22:36:00) [3]


> Inovet ©   (28.09.12 22:26) [17]

Ты никогда по существу не пишешь, да?
Глупо себя ведёшь, приводишь искажённые слова других людей без упоминания контекста обсуждения, агитируешь, создаёшь негативный настрой в обсуждении. Тем дамам, которые обиделись на "хамство", следовало бы самим поучиться вежливо относиться к людям. Ты, вроде, взрослый человек, а ведёшь себя как-то несерьёзно.


dm_member   (2012-09-28 22:31:00) [4]


> Dimka Maslov ©   (28.09.12 22:04) [13]

Код чтения/записи идентичен по логике моему. Но у меня не массив строк, а массив объектов с различными типами данных внутри.


Inovet   (2012-09-28 22:26:00) [5]

> [15] sniknik ©   (28.09.12 22:16)
> слабо как раз не дать код...

У автора противоположное мнение. В прошлой ветке он прямо сказал, что советы ему не нужны и даже просил модераторов удалить их. Следовательно ждал код, попутно хамя всем. Что делать, раз нет понимания, что советы намного полезнее.


dm_member   (2012-09-28 22:23:00) [6]


> Dimka Maslov ©   (28.09.12 22:04) [13]


Во-первых, с заменой pointer на pchar ничего не изменилось.
Во-вторых,

...
> Есть и при этом только одна - голова.

Не зазнавайся, мистер супер мозг.


sniknik   (2012-09-28 22:16:00) [7]

> а код дать слабо.:)
слабо как раз не дать код... а дать это развестись "на слабо".


Inovet   (2012-09-28 22:13:00) [8]

> [13] Dimka Maslov ©   (28.09.12 22:04)
> У меня почему-то сразу получилось.

Так бы сразу. А то умничать только можете, а код дать слабо.:)


Dimka Maslov   (2012-09-28 22:04:00) [9]


> Есть ли какая-то причина, по которой инт и строки могут
> ненормально читаться через TFileStream.Read?
>


Есть и при этом только одна - голова.

type
 TStringArray = array of String;

procedure SaveArray(const A: TStringArray; Dest: TStream);
var
 i, N: Integer;
 S: String;
begin
 N := Length(A);
 Dest.Write(N, SizeOf(N));
 for i := Low(A) to High(A) do begin
   S := A[i];
   N := Length(S);
   Dest.Write(N, SizeOf(N));
   Dest.Write(PChar(S)^, N * SizeOf(Char));
 end;
end;

procedure LoadArray(var A: TStringArray; Source: TStream);
var
 i, N, L: Integer;
 S: String;
begin
 Source.Read(N, SizeOf(N));
 SetLength(A, N);
 for i := 0 to N - 1 do begin
   Source.Read(L, SizeOf(L));
   SetLength(S, L);
   Source.Read(PChar(S)^, L * SizeOf(Char));
   A[i] := S;
 end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 A: TStringArray;
 S: TFileStream;
begin
 SetLength(A, 3);
 A[0] := 'word';
 A[1] := 'summer';
 A[2] := 'type';
 S := TFileStream.Create('1.bin', fmCreate);
 try
   SaveArray(A, S);
 finally
   S.Free;
 end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
 A: TStringArray;
 S: TFileStream;
 i: Integer;
begin
 S := TFileStream.Create('1.bin', fmOpenRead);
 try
   LoadArray(A, S);
 finally
   S.Free;
 end;
 for i := Low(A) to High(A) do ShowMessage(A[i]);
end;


У меня почему-то сразу получилось.


MBo   (2012-09-28 21:54:00) [10]

Пора реальный код показать


Inovet   (2012-09-28 21:53:00) [11]

read что возвращает?


dm_member   (2012-09-28 21:19:00) [12]

Это маразм какой-то. Только что проверил, пошагово вывел всё, что пишу в файл и всё, что читаю оттуда.
Лог, в формате "переменная - её значение - размер в байтах".
например, i - 6 - 4 значит, что в файл пишется переменная i типа integer, её значение = 4, её размер = 4 (integer). Комментарии идут после //

Пишу:
1) i - 4 - 4
2) pointer(s)^ - 'word' - 4      // 4 = i*sizeof(char)
3) i - 6 - 4
4) pointer(s)^ - 'summer' - 6     // 6 = i*sizeof(char)
5) i - 4 - 4
6) pointer(s)^ - 'type' - 4     // 4 = i*sizeof(char)
7) i - 1 - 4

Читаю:
1) i - 4 - 4
2) pointer(s)^ - 'word' - 4
3) i - 6 - 4
4) pointer(s)^ - 'summer' - 6
5) i - 4 - 4
6) pointer(s)^ - '' - 4    // !!!
7) i - 1853189998 - 4     // !!!

Т.е. не читает последнюю строку и i. Размер последней строки читает правильно на шаге 5, но строка получается пустая. Последнее значение i вместо 1 получается почти два миллиарда.. При этом в файл записано всё корректно, это видно даже через блокнот.


dm_member   (2012-09-28 20:15:00) [13]


> Inovet ©   (28.09.12 19:47) [6]


По существу бы лучше что-нибудь.


dm_member   (2012-09-28 20:10:00) [14]


> Anatoly Podgoretsky ©   (28.09.12 19:35) [4]
...
Тебе еще везет, что AV не получил.


AV было, когда pointer не использовал.


> использовать указатель надо очень осторожно

Если я как-то не так его использую, хотелось бы подробней знать, как можно обращаться со строками типа string в подобных случаях. Не расскажете?


dm_member   (2012-09-28 20:02:00) [15]


> MBo ©   (28.09.12 19:45) [5]
между этими строками SetLength имеется?


Да.


Inovet   (2012-09-28 19:47:00) [16]

> [4] Anatoly Podgoretsky ©   (28.09.12 19:35)
> Тебе еще везет, что AV не получил.

или не везёт.


MBo   (2012-09-28 19:45:00) [17]

>fs.read(i, sizeof(integer));
>fs.read(pointer(s)^, i*sizeof(char));

между этими строками SetLength имеется?


Anatoly Podgoretsky   (2012-09-28 19:35:00) [18]

А ничего, что string это тип с автомаческим временем жизни, что означает особые структуры в рантайм? И использовать указатель надо очень осторожно, понимая что делаешь. Тебе еще везет, что AV не получил.


dm_member   (2012-09-28 19:25:00) [19]


> Дмитрий С ©   (28.09.12 18:52) [2]
Код в студию.


Вопрос, повторю, общий. Есть ли какая-то причина, по которой инт и строки могут ненормально читаться через TFileStream.Read?

Но раз уж это так важно, вот:

fs.read(i, sizeof(integer));
... операции с i...
fs.read(i, sizeof(integer));
fs.read(pointer(s)^, i*sizeof(char));
... операции с s ...
fs.read(i, sizeof(integer));
fs.read(pointer(s)^, i*sizeof(char));
... операции с s ...
fs.read(i, sizeof(integer));
fs.read(pointer(s)^, i*sizeof(char));
... операции с s ...
fs.read(i, sizeof(integer));
fs.read(pointer(s)^, i*sizeof(char));
... операции с s ...
fs.read(i, sizeof(integer));
fs.read(pointer(s)^, i*sizeof(char));
...
и т.д.


Дмитрий С   (2012-09-28 18:52:00) [20]


> Код я проверял построчно, последовательность при записи
> и чтении совпадает.

Код в студию.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо