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

Вниз

Чтение файлов с изменяющейся структурой   Найти похожие ветки 

 
SeDOy   (2005-02-16 16:47) [0]

Мне надо анализировать файлы с данными, Но есть трудности.

Структура файла:
type
file1=record
data:array[1.190] of real;
text:string[1..194];
end;

Кол-во таких записей равно 1440.
Проблема в том что в каждом файле границы массивов могут изменяются, 1..195,1..198 и .т.д,
так же менется и длинна текста.
Мне посути не очень важно считыавть текст, мне нужен только массив значений типа real.

Как это сделать?
Так как дельфя не умеет делать динамический рекорд остаётся только
blockread/write

Но тогда я не пойму как из одной записи мне считать только значения real,
ведь запись(например) занимает 950 байт, из них 790байт значения real,
а остальные 160 байт - текст

Может кто сталкивался с такой ситуацией? помогите плиз!


 
Arm79 ©   (2005-02-16 17:16) [1]

Что то непонятно. Почему границы рекорда вообще плавают? интересно и поле text объявлено.

Вы уверены, что правильно привели структуру файла?

Может так правильнее?

type
 TMyRec = record
   data : real;
   text : string[255];
 end;
 TMyRecArray = array [1..190] of TMyRec;
var
 file1 : file of TMyRec;


Так как дельфя не умеет делать динамический рекорд
Поясните, что это значит


 
icWasya ©   (2005-02-16 18:18) [2]

и как тот, кто пишет, предполагает ЭТО читать


 
SeDOy   (2005-02-16 20:27) [3]

Нет, в моём случае правильно вот так

type
TMyRec = record
  data : real[1..190];
  text : string[194];
end;


так как одна запись это массив значений, а следующий
далее за ним  текст.

Так как дельфя не умеет делать динамический рекорд
Я имел ввиду что во время исполнения программы не возможно изменить границы массивов data и text


 
begin...end ©   (2005-02-16 20:31) [4]

> SeDOy   (16.02.05 20:27) [3]

Т.е. формат файла Вы изменить не можете? Нужно только решить проблему с чтением?


 
begin...end ©   (2005-02-16 21:40) [5]

> SeDOy   (16.02.05 16:47)

> Но тогда я не пойму как из одной записи мне считать
> только значения real, ведь запись(например) занимает
> 950 байт, из них 790байт значения real, а остальные
> 160 байт - текст

Ну так и считывайте нужное количество байт из файла с помощью уже упомянутой Вами процедуры BlockRead.

Например, есть файл с записями такого типа:

type
 TMyRecord = packed record
   Data: array [1..190] of Real;
   Text: string [194]
 end


Как будет выглядеть в файле эта запись, если её записывали именно как запись в типизированный файл (file of TMyRecord)? Вначале идут 190 * 8 = 1520 байт поля-массива Data: первые 8 байт - первый элемент, вторые 8 байт - второй элемент, и т.д. Затем сразу же идут 195 байт поля Text. Почему 195, а не 194? Потому что таков формат коротких строк - первый байт у них содержит длину (в Вашем случае длина равна 194, поэтому байт в файле, следующий за массивом Data, будет равен именно 194), а уже следом за ним идут символы. Таким образом, каждая запись будет занимать в файле 1520 + 195 = 1715 байт.

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

Ну и как же прочитать из файла то, что Вам нужно? Начнём с первой записи. Объявляем нетипизированный файл и читаем из него первые 1520 байт в массив:

var
 F: file;
 Arr: array [1..190] of Real;
begin
 AssignFile(F, "{путь к файлу}");
 Reset(F, 1);
 BlockRead(F, Arr, 1520);
 CloseFile(F)
end.


Вот и всё - теперь массив Arr заполнен.

А как прочитать, например, вторую запись? Для этого нужно сместиться в файле на нужную позицию. Если первая запись занимает 1715 байт, то, если считать, что нумерация байтов в файле начинается с нуля, получается, что первая запись занмает байты 0..1715, а вторая запись начинается с 1715-го байта. Используем процедуру Seek и читаем:

var
 F: file;
 Arr: array [1..190] of Real;
begin
 AssignFile(F, "{путь к файлу}");
 Reset(F, 1);
 Seek(F, 1715);
 BlockRead(F, Arr, 1520);
 CloseFile(F)
end.


Теперь в массиве Arr будет содержимое поля Data из второй записи (если, конечно, вторая запись в файле была).

Разумеется, вместо конкретных чисел (1520 и 195) можно использовать функцию SizeOf (SizeOf(MyRecord.Data) и SizeOf(MyRecord.Text)).

Всё вышесказанное относится к случаю, когда в файл были записаны упакованные (packed) записи. В случае неупакованных дело несколько усложняется.

Только объясните, наконец - почему бы всё-таки не читать из файла именно записи, и потом в этих записях использовать только поле Data, а на поле Text просто не обращать внимание?


 
begin...end ©   (2005-02-16 21:43) [6]

> begin...end ©   (16.02.05 21:40) [5]

> получается, что первая запись занмает байты 0..1715, а
> вторая запись начинается с 1715-го байта

Опечатка. Следует читать: "получается, что первая запись занимает байты 0..1714, а вторая запись начинается с 1715-го байта".


 
Slym ©   (2005-02-17 06:37) [7]

Сделай с запасом:
type
TMyRecord = packed record
  DataSize:byte;
  Data: array [1..200] of Real;
  Text: string [255];
end

Все данные поместятся...
DataSize пиши количество данных в штуках
Text заканчивай #0


 
Arm79 ©   (2005-02-17 09:59) [8]

2 Slym ©   (17.02.05 06:37) [7]

Text заканчивай #0
При таком объявлении Text нет нужды в #0. Это же ShortString

2 SeDOy   (16.02.05 20:27) [3]
Границы менять можно. Вам ни о чем не говорят динамические массивы?
это объявления типа array of real без указания границ диапазона. Границы устанавливаются в коде через SetLength.

2 begin...end ©   (16.02.05 21:40) [5]
Насколько я понимаю, если объявить переменную F: file как F: file of TMyRecord, то можно обойтись отлично и без BlockRead. Обычный Read вполне подойдет. И смещения вычислять не нужно.

Согласен, форма организации записей в файл нелогична


 
begin...end ©   (2005-02-17 11:02) [9]

> Arm79 ©   (17.02.05 9:59) [8]

> Насколько я понимаю, если объявить переменную F: file
> как F: file of TMyRecord, то можно обойтись отлично и
> без BlockRead.

Разумеется. Я просто ответил на вопрос автора ветки о том, как считывать запись не целиком, а только отдельные её поля. Хотя для чего это может быть необходимо - не знаю. И об этом я тоже сказал в конце [5].

> Границы менять можно. Вам ни о чем не говорят
> динамические массивы?

Если сделать в записи поле типа динамический массив, то тогда уже обычным типизированным файлом (а следовательно, и процедурой Read) не обойтись.

Вопрос до сих пор неясен. Если в записях переменная длина полей (например, поля Data представляют собой массивы различной длины), то в таких случаях от записей обычно отказываются и пишут в нетипизированный файл по схеме "длина данных - сами данные".


 
Arm79 ©   (2005-02-17 11:13) [10]

2 begin...end ©   (17.02.05 11:02) [9]
Так и я про то же. Мне не понятно, то ли есть уже файлы, которые надо проанализировать, то ли он сам их пишет, а потом анализирует...

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


 
esu ©   (2005-02-17 12:33) [11]

Если нужно просто узнать какой тип использовать для чтения то получается.
1440*размер одной записи=размер файла
размер одной записи = 195 + x*sizeof(real)

решаем уравнение, получаем x далее по этому x можно использовать тот или иной тип.



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

Форум: "Основная";
Текущий архив: 2005.03.06;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.035 c
4-1106750531
Неуловимый Джо
2005-01-26 17:42
2005.03.06
Хук на запуск приложений


14-1108648630
Ilya___
2005-02-17 16:57
2005.03.06
подскажите, как можно щелчком на Label, открыть броузер с интерне


1-1109182411
Kerk
2005-02-23 21:13
2005.03.06
"Разделяемый" массив.


1-1108846915
Shamansky
2005-02-20 00:01
2005.03.06
FastReports?


1-1108906887
TeNY
2005-02-20 16:41
2005.03.06
Размер картики в TBitmap?





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский