Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2013.03.31;
Скачать: [xml.tar.bz2];

Вниз

Ошибка чтения разнотипных данных из 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.004 c
2-1348818757
ixen
2012-09-28 11:52
2013.03.31
Firebird и текстовое вычисляемое поле


15-1354711862
Error0xDEADBEEF
2012-12-05 16:51
2013.03.31
VirtualBox


8-1227335832
Б
2008-11-22 09:37
2013.03.31
Media


15-1353699619
Пит
2012-11-23 23:40
2013.03.31
ЖКХ развод?


2-1347384231
Писатель
2012-09-11 21:23
2013.03.31
Масштабирование BMP





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский