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

Вниз

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

 
dm_member ©   (2012-09-28 18:00) [0]

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

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

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


 
MBo ©   (2012-09-28 18:23) [1]

Логирование и тщательная пошаговая отладка

P.S. Про более высокоуровневые методы структурирования данных, записи и чтения не помешает в очередной раз напомнить


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


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

Код в студию.


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


> Дмитрий С ©   (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));
...
и т.д.


 
Anatoly Podgoretsky ©   (2012-09-28 19:35) [4]

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


 
MBo ©   (2012-09-28 19:45) [5]

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

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


 
Inovet ©   (2012-09-28 19:47) [6]

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

или не везёт.


 
dm_member ©   (2012-09-28 20:02) [7]


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


Да.


 
dm_member ©   (2012-09-28 20:10) [8]


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


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


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

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


 
dm_member ©   (2012-09-28 20:15) [9]


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


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


 
dm_member ©   (2012-09-28 21:19) [10]

Это маразм какой-то. Только что проверил, пошагово вывел всё, что пишу в файл и всё, что читаю оттуда.
Лог, в формате "переменная - её значение - размер в байтах".
например, 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 получается почти два миллиарда.. При этом в файл записано всё корректно, это видно даже через блокнот.


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

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


 
MBo ©   (2012-09-28 21:54) [12]

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


 
Dimka Maslov ©   (2012-09-28 22:04) [13]


> Есть ли какая-то причина, по которой инт и строки могут
> ненормально читаться через 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;


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


 
Inovet ©   (2012-09-28 22:13) [14]

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

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


 
sniknik ©   (2012-09-28 22:16) [15]

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


 
dm_member ©   (2012-09-28 22:23) [16]


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


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

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

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


 
Inovet ©   (2012-09-28 22:26) [17]

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

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


 
dm_member ©   (2012-09-28 22:31) [18]


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

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


 
dm_member ©   (2012-09-28 22:36) [19]


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

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


 
Inovet ©   (2012-09-28 22:40) [20]

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

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

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


 
Inovet ©   (2012-09-28 22:42) [21]

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

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



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

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

Наверх




Память: 0.53 MB
Время: 0.01 c
15-1354739404
Юрий
2012-12-06 00:30
2013.03.31
С днем рождения ! 6 декабря 2012 четверг


15-1354686540
Медвежонок Пятачок
2012-12-05 09:49
2013.03.31
Кин-Дза-Дза


15-1354659174
Sinoptik2013
2012-12-05 02:12
2013.03.31
Информер погоды на рабочий стол


2-1348818757
ixen
2012-09-28 11:52
2013.03.31
Firebird и текстовое вычисляемое поле


2-1348434236
ankazh
2012-09-24 01:03
2013.03.31
поиск в поле MEMO через SQL