Текущий архив: 2003.03.03;
Скачать: CL | DM;
ВнизBlockRead, BlockWrite - забавную штуку обнаружил. Найти похожие ветки
← →
asafr (2003-02-18 15:08) [0]Здравствуйте.
Написал простую тестовую программку, работающую с файлом через BlockRead и BlockWrite, при этом обнаружил интересную штуку, принцип которой ясен, но как избавится от неё - мне не совсем понятно. Сначала код программки:
type
TSad = record
field1 : string;
field2 : string;
field3 : string;
end;
..............
..............
..............
{Запись в файл file1.log}
procedure TForm1.bt_BlockWriteClick(Sender: TObject);
var
Sad : TSad;
m_file: file;
begin
Sad.field1 := "Строка_1";
Sad.field2 := "Строка_2";
Sad.field3 := "Строка_3";
AssignFile(m_file, "file1.log");
{$I-}
Rewrite(m_file,1);
BlockWrite(m_file, Sad.Field1, sizeof(TSad));
BlockWrite(m_file, Sad.Field2, sizeof(TSad));
BlockWrite(m_file, Sad.Field3, sizeof(TSad));
CloseFile(m_file);
end;
{Чтение из файла file1.log}
procedure TForm1.bt_BlockReadClick(Sender: TObject);
var
m_file: file;
sad :TSad;
p :^TSad;
begin
AssignFile(m_file, "file1.log");
{$I-}
Reset(m_file,1);
Memo1.Clear;
p:=@Sad;
BlockRead(m_file, p^.Field1, sizeof(TSad));
Memo1.Lines.Add(p^.Field1);
BlockRead(m_file, p^.Field2, sizeof(TSad));
Memo1.Lines.Add(p^.Field2);
BlockRead(m_file, p^.Field3, sizeof(TSad));
Memo1.Lines.Add(p^.Field3);
CloseFile(m_file);
end;
Все элементарно: В файл file1.log записываются три строки "Строка_1", "Строка_2", "Строка_3" при нажатии кнопки bt_BlockWrite и читаются эти строки при нажатии кнопки bt_BlockRead -> данные заносятся в Memo1. Все прекрасно работает, НО..... В режиме Design в коде программы в ручную меняем значения sad.field1, sad.field2, sad.field3 -> запускаем программу и сразу же нажимаем на кнопку Чтения Данных из Файла (bt_BlockRead), НЕ нажимая перед этим на кнопку записи. В результате в Memo1 выводяться уже измененные данные... Такое впечатление, что программа читает не из файла file1.log, а из тех областей памяти, зарезервированных для sad.field1, sad.field2, sad.field3. Почему так и как с этим бороться? Что я сделал не так?
← →
icWasya (2003-02-18 15:39) [1]ну во первых - почему пишется p.Field1, а SizeOf(TSad) ??
а вовторых внимательно прочитай, что такое тип String --
или посмотри исходники VCL - как там пишут/читают String"и
← →
asafr (2003-02-18 17:47) [2]Ну, посмотрел... Исправил... Но проблема остпется....
← →
MBo (2003-02-18 17:58) [3]проверяешь, сработала ли BlockRead (AmtTransferred или обработка ошибок)?
← →
icWasya (2003-02-18 18:01) [4]
type
TSad = record
field1 : string;
field2 : string;
field3 : string;
end;
..............
..............
..............
{Запись в файл file1.log}
procedure TForm1.bt_BlockWriteClick(Sender: TObject);
var
Sad : TSad;
m_file: file;
L : LongWord;
begin
Sad.field1 := "Строка_1";
Sad.field2 := "Строка_2";
Sad.field3 := "Строка_3";
AssignFile(m_file, "file1.log");
{$I-}
Rewrite(m_file,1);
L:=Length(Sad.Field1)
BlockWrite(m_file, L, sizeof(L));
BlockWrite(m_file, Sad.Field1[1], L);
L:=Length(Sad.Field2)
BlockWrite(m_file, L, sizeof(L));
BlockWrite(m_file, Sad.Field21[1], L);
L:=Length(Sad.Field3)
BlockWrite(m_file, L, sizeof(L));
BlockWrite(m_file, Sad.Field3[1], L);
CloseFile(m_file);
end;
{Чтение из файла file1.log}
procedure TForm1.bt_BlockReadClick(Sender: TObject);
var
m_file: file;
sad :TSad;
p :^TSad;
L :LongWord;
begin
AssignFile(m_file, "file1.log");
{$I-}
Reset(m_file,1);
Memo1.Clear;
p:=@Sad;
BlockRead(m_file, L, sizeof(L));
SetLength(p^.Field1,L);
BlockRead(m_file, p^.Field1[1], L);
Memo1.Lines.Add(p^.Field1);
BlockRead(m_file, L, sizeof(L));
SetLength(p^.Field2,L);
BlockRead(m_file, p^.Field2[1], L);
Memo1.Lines.Add(p^.Field2);
BlockRead(m_file, L, sizeof(L));
SetLength(p^.Field3,L);
BlockRead(m_file, p^.Field3[1], L);
Memo1.Lines.Add(p^.Field3);
CloseFile(m_file);
end;
← →
jack128 (2003-02-18 20:02) [5]Вижу как ты опключаешь I/O checks ($I-), но не вижу как ты её(проверку) включаешь($I+ если забыл :))
и нет проверки IOResult.
А вообще вроде все правильно,так что ещё раз проверь работают ли BlockRead"ы
← →
woland (2003-02-18 22:57) [6]А зачем тебе BlockRead?
...
var f : file of TSad;
s : TSad;
...
assignfile(f,"fname");
Read(f,s);//чтение
...
Write(f,s);//запись
CloseFile(f);
← →
Ricks (2003-02-18 23:08) [7]Лучше использовать
type
TSad = record
field1 : array[0..255] of Char;
field2 : array[0..255] of Char;
field3 : array[0..255] of Char;
end;
Тогда и проблем не должно быть
← →
jack128 (2003-02-19 00:03) [8]2 woland ©
BlockRead нужен потому что в записи присутствуют длинные строки(string), а вот если автор воспользуется советом Ricks"а,
то можно использовать и типизированные файлы...
← →
ION T (2003-02-19 00:08) [9]> Ricks © (18.02.03 23:08)
Памяти не жалко?
Писать надо файлстримом, сначала длинну строку затем саму строку....читать аналогично. Одним оператором тут не обойтись....
← →
woland (2003-02-19 00:09) [10]
> jack128 ©
Согласен. Хотя можно и просто записать так
TSad = record
field1 : string[255];
field2 : string[255];
field3 : string[255];
end
← →
jack128 (2003-02-19 00:18) [11]2 ION T ©
собственно автор так и делает(только не через файл стрим, а через нетип. файл), а вот почему не работает - это вопрос..
← →
ION T (2003-02-19 00:46) [12]Так делает не автор, а icWasya © (18.02.03 18:01) и делает, заметим, правильно и всё работает....
← →
jack128 (2003-02-19 00:50) [13]ошибочка вышла...
Хотя {I+} - надо бы включить
← →
asafr (2003-02-19 11:04) [14]Да... Не было с вечера - и очень много ответов. Всем спасибо - очень ценные замечания.
icWasya, ты был прав: тебе отдельное спасибо.
С уважением ко всем, Сафронов Андрей
Страницы: 1 вся ветка
Текущий архив: 2003.03.03;
Скачать: CL | DM;
Память: 0.48 MB
Время: 0.009 c