классика Pascal. Работа с типизированными файлами в Delphi
Удивительно, но факт – запрос “delphi файлы” в Яндексе – это один из самых популярных запросов, касающихся Delphi. Популярнее только “delphi скачать” – видимо ещё не все слышали про такую штуку как Delphi Community Edition. Раз есть в Сети запрос – должен быть и ответ. Посмотрим, что получится в итоге.
Содержание статьи
Классика работы с файлами в Delphi – ключевое слово File
Этот способ, без преувеличения, можно назвать древнейшим способом работы с файлами в Pascal/Delphi. Однако и он до сих пор используется в работе, особенно, если это, например, лабораторная работа по информатике в школе или ВУЗе.
Для определения файловой переменной в Delphi/Pascal используется ключевое слово File. При этом, мы можем определить как типизированный файл, так и не типизированный, например:
type TPerson = record Name: string[20]; Family: string[20]; end; var UntypedFile: File; //нетипизированный двоичный файл TypedFile: File of TPerson;//типизированный файл
Для типизированного фала мы можем задать тип данных фиксированного размера (ShortString, String[20], Integer, Single и так далее), например, мы можем определить такие типизированные файлы:
IntFile: File of integer; StringFile: file of single; ShortStringFile: file of ShortString;
Или, как в примере выше использовать для указания типа запись (record), в которой все поля имеют фиксированный размер. Для типизированного файла нельзя указывать типы данных, размер которых не фиксирован, например, вот такие определения файловых переменных недопустимы:
type TIntArr = array of integer; var StrFile: file of string; //недопустимо - размер string заранее не известен ArrFile: file of TIntArr;//недопустимо - размер динамического массива заранее неизвестен
Более того, даже компилятор Delphi укажет вам на ошибку, сообщив следующее:
[dcc32 Error] E2155 Type ‘string’ needs finalization – not allowed in file type
Определив файловую переменную можно приступать к работе с файлом. Алгоритм работы при этом будет следующим:
- Ассоциировать файловую переменную с файлом на диске
- Открыть файл
- Записать/Прочитать файл
- Закрыть файл
При этом, для типизированных и не типизированных файлов работа в части чтения/записи несколько различается в плане используемых методов.
Работа с типизированными файлами в Delphi
Рассмотрим несколько примеров работы с типизированными файлами в Delphi.
Для начала, рассмотрим вариант работы с типизированным файлом, например, представленном выше:
type TPerson = record Name: string[20]; Family: string[20]; end; var TypedFile: File of TPerson;
Пример №1. Запись данных в типизированный файл Delphi
Запишем в наш файл две записи:
program example_1; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils; type TPerson = record Name: string[20]; Family: string[20]; end; var TypedFile: File of TPerson; Person: TPerson; begin //связываем файловую переменную с файлом на диске AssignFile(TypedFile,'MyFile.txt'); //открываем файл для записи Rewrite(TypedFile); //задаем имя/фамилию человека Person.Name:='Иван'; Person.Family:='Иванов'; //добавляем запись в файл Write(TypedFile, Person); //задаем имя/фамилию второго человека Person.Name:='Петр'; Person.Family:='Петров'; //записываем в файл Write(TypedFile, Person); //закрываем файл CloseFile(TypedFile); Readln; end.
Рассмотрим методы, используемые в этом примере:
function AssignFile(var F: File; FileName: String): Integer;
Связывает файловую переменную F с внешним файлом FileName. В качестве второго параметра может задаваться как абсолютный путь к файлу, например, ‘C:/MyFile.txt‘, так и относительный, например, в коде выше файл будет создан рядом с exe-файлом.
procedure Rewrite(var F: File; [ RecSize: Integer]);
Создает новый файл и открывает его. Если внешний файл с таким именем уже существует, он удаляется и на его месте создается новый пустой файл. Если F уже открыт, он сначала закрывается, а затем воссоздается. Текущая позиция файла устанавливается в начале пустого файла.
F – это переменная, связанная с внешним файлом с использованием AssignFile. RecSize – это необязательное выражение, которое можно указывать, только если F является нетипизированным файлом (об этом ниже).
procedure Write([var F: File]; P1; [ ..., PN]); overload;
procedure CloseFile(var F: File);
Прекращает связь между файловой переменной и файлом внешнего диска. F – это файловая переменная любого типа. Внешний файл, связанный с F, полностью обновляется, а затем закрывается, освобождая дескриптор файла для повторного использования.
В результате выполнения представленного выше кода, рядом с exe-файлом будет создан новый файл MyFile.txt, содержащий две записи, при этом, каждая запись будет иметь фиксированный размер, вне зависимости от фактических имени/фамилии.
Для того, чтобы в delphi не перезаписывать каждый раз файл, а добавлять в конец файла новые записи необходимо открывать типизированные файлы методом Reset. Рассмотрим пример добавления новых записей в типизированные файлы Delphi.
Пример №2. Добавление записей в типизированный файл Delphi
Рассмотрим такой пример Delphi:
program example_2; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils; type TPerson = record Name: string[20]; Family: string[20]; Age: integer; end; procedure ReadTypedFile; const cStr = '%s %s %d'; var F: File of TPerson; Person: TPerson; begin AssignFile(F, 'MyFile.txt'); Reset(F); while not Eof(F) do begin Read(F, Person); Writeln(Format(cStr, [Person.Name, Person.Family, Person.Age])); end; end; procedure AppendTypedFile; var F: file of TPerson; Person: TPerson; begin AssignFile(F, 'MyFile.txt'); // открываем файл для записи Reset(F); Seek(F, FileSize(F)); // задаем имя/фамилию человека Writeln('Введите имя: '); Readln(Person.Name); Writeln('Введите фамилию: '); Readln(Person.Family); Writeln('Введите возраст: '); Readln(Person.Age); // добавляем запись в файл Write(F, Person); // закрываем файл CloseFile(F); end; var TypedFile: File of TPerson; Person: TPerson; DoAppend: integer; begin if not FileExists('MyFile.txt') then begin AssignFile(TypedFile, 'MyFile.txt'); // открываем файл для записи Rewrite(TypedFile); // закрываем файл CloseFile(TypedFile); end; // связываем файловую переменную с файлом на диске repeat Writeln('Добавить в файл запись: 1 - Да; 2 - Нет'); Readln(DoAppend); case DoAppend of 1: AppendTypedFile; 2: break; end; until DoAppend = 0; //читаем все записи из типизированного файла ReadTypedFile; Readln; end.
Разберемся с тем, что здесь делается. Во-первых, условие:
if not FileExists('MyFile.txt') then
проверяет, существует ли файл на диске. Метод FileExist имеет следующее описание:
function FileExists(const FileName: string; FollowLink: Boolean = True): Boolean;
FileName – имя файла, существование которого необходимо проверить. Второй параметр – FollowLink учитывается только при использовании символической ссылки. То есть, если нужно проверить только наличие символической ссылки на файл, то параметр FollowLink устанавливается в False, а если нужно проверить наличие и символической ссылки на файл и самого файла, то FollowLink устанавливается в True (значение по умолчанию).
Таким образом, в нашем примере, если файла нет на диске то он создается пустым. Далее выполняется цикл:
repeat Writeln('Добавить в файл запись: 1 - Да; 2 - Нет'); Readln(DoAppend); case DoAppend of 1: AppendTypedFile; 2: break; end; until DoAppend = 0;
В этом цикле, если пользователь вводит
procedure AppendTypedFile; var F: file of TPerson; Person: TPerson; begin AssignFile(F, 'MyFile.txt'); // открываем файл для записи Reset(F); //смещаемся в конец файла Seek(F, FileSize(F)); // задаем имя/фамилию человека Writeln('Введите имя: '); Readln(Person.Name); Writeln('Введите фамилию: '); Readln(Person.Family); Writeln('Введите возраст: '); Readln(Person.Age); // добавляем запись в файл Write(F, Person); // закрываем файл CloseFile(F); end;
Здесь, в принципе, весь алгоритм расписан в комментариях к процедуре.
Метод Reset не воссоздает файл снова, как Rewrite, а открывает его для чтения/записи (в случае двоичных файлов). Что касается метода Seek, то он имеет следующее описание:
procedure Seek(var F: File; N: Integer);
F – файловая переменная, ассоциированная с файлом на диске, N – номер записи в файле (первый номер – 0). Чтобы переместиться сразу в конец файла, мы сделали такой вызов:
где FileSize – это метод Delphi имеющий следующее описание:
function FileSize(var F: File): Integer;
В случае использования типизированных файлов эта функция возвращает количество записей в файле.
После того, как пользователь вводит что-то кроме 1 срабатывает метод ReadTypedFile – чтение всех записей из файла:
procedure ReadTypedFile; const cStr = '%s %s %d'; var F: File of TPerson; Person: TPerson; begin AssignFile(F, 'MyFile.txt'); Reset(F); while not Eof(F) do begin Read(F, Person); Writeln(Format(cStr, [Person. Name, Person.Family, Person.Age])); end; end;
Здесь мы, опять же, открываем файл методом
function Eof([var F: File]): Boolean; overload;
Eof возвращает True, если текущая позиция файла находится за последним символом файла или файл пуст. В противном случае Eof возвращает False.
По аналогии с методом Write, метод Read производит чтение очередной записи из файла и имеет следующее описание:
procedure Read(var F: File; V1; [ ..., VN]);
Результат работы нашего примера может быть следующим:
Ещё одним полезным методом для работы с типизированными файлами может быть процедура Truncate:
procedure Truncate(var F: File);
Удаляет все записи после текущей позиции файла. Вызовите Truncate в коде Delphi, чтобы текущая позиция файла стала концом файла (Eof (F) вернет true).
Рассмотрим пример использования этой процедуры.
Пример №3. Удаление последних записей типизированного файла в Delphi
Воспользуемся файлом, созданным в предыдущем примере и удалим из него две последние записи:
program example_3; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils; type TPerson = record Name: string[20]; Family: string[20]; Age: integer; end; procedure ReadTypedFile; const cStr = '%s %s %d'; var F: File of TPerson; Person: TPerson; begin AssignFile(F, 'MyFile.txt'); Reset(F); while not Eof(F) do begin Read(F, Person); Writeln(Format(cStr, [Person.Name, Person.Family, Person.Age])); end; end; var TypedFile: File of TPerson; Person: TPerson; Count: integer; DoErase: integer; begin AssignFile(TypedFile,'MyFile.txt'); Reset(TypedFile); Count:=FileSize(TypedFile); if Count<2 then begin Writeln('Количество записей в файле меньше двух. Стереть все записи? 1 - Да; 2 - Нет'); Readln(DoErase); if DoErase=1 then Truncate(TypedFile); end else begin Seek(TypedFile, Count-2); Truncate(TypedFile); end; //читаем все записи из типизированного файла ReadTypedFile; Readln; end.
В этом примере мы делаем следующее:
- Открываем файл существующий AssignFile/Reset
- Определяем количество записей в файле (Count:=FileSize(TypedFile))
- Если количество записей меньше двух, то спрашиваем у пользователя стереть ли все записи и, в случае положительного ответа, вызываем метод Tuncate
- Если количество записей в файле больше двух, то смещаемся на нужную нам позицию в файле (Seek(TypedFile, Count-2)) и затираем две последние записи методом Truncate.
Подведем итог
Для работы с типизированными файлами в Delphi в самом общем случае нам необходимо выполнить следующую последовательность операций:
- Определить тип записей в файле – это могут быть стандартные типы данных Delphi с фиксированным размером: ShortString, integer, single и так далее или собственные типы данных, например, записи (record), но, в этом случае, главное условие – размер записи должен быть фиксированным.
- В коде Delphi/Pascal определить файловую переменную, используя ключевое слово file и, указав тип записей файла, определенный в пункте 1.
- Ассоциировать файловую переменную с внешним файлом на диске, используя метод AssignFile.
- Открыть файл для чтения/записи, используя методы Rewrite/Reset.
- Чтобы сделать в файл очередную запись используем метод Write, для чтения очередной записи из файла – используем метод Read.
- Закрыть файл методом CloseFile.
В целом, рассмотренные выше примеры не охватывают всех возможностей работы с типизированными файлами в Delphi, а, скорее, показывают основные операции по работе с типизированными файлами. Поэтому ниже представлен перечень методов которые могут применяться при работе с типизированными файлами в Delphi/Pascal.
Функции и процедуры для работы с типизированными файлами в Delphi/Pascal
Метод | Краткое описание |
procedure AssignFile(var F: File; FileName: String) | Ассоциирует файловую переменную F с внешним файлом FileName. Переменная FileName может быть как именем файла, так и содержать полный путь к файлу на диске. |
procedure CloseFile(var F: File); | Закрывает файл, ассоциированный с переменной F и освобождает переменную для дальнейшего использования. |
function Eof(var F: File): Boolean; | Проверяет конец файла и возвращает True, если файловый указатель стоит в конце файла. В случае записи True означает, что очередной компонент будет добавлен в конец файла, при чтении – что файл прочтен полностью. |
procedure Erase(var F: File); | Удаляет внешний файл, связанный с файловой переменной F. Перед удалением файла его необходимо закрыть методом CloseFile. |
function FilePos(var F: File): Integer; | Возвращает текущую позицию в файле. В коде Delphi используйте FilePos для файловой переменной открытого файла, чтобы определить текущую позицию в файле. Если текущая позиция в файле находится в начале, FilePos возвращает 0. |
function FileSize(var F: File): Integer;
| Для типизированных файлов возвращает количество записей в файле. |
procedure Read(var F: File; V1; [ ..., VN]); | Считывает из типизированного файла одну или несколько записей |
procedure Rename(var F: File; Newname: String); | Переименовывает файл, ассоциированный с переменной F |
procedure Reset(var F: File; [ RecSize: Integer]); | Открывает файл для чтения. Второй параметр RecSize указывается в случае использования нетипизированных файлов и указывает размер записи в файле в байтах |
procedure Rewrite(var F: File; [ RecSize: Integer]); | Воссоздает файл. Если файл существует, то Rewrite его удалит, а затем создаст снова. RecSize используется для нетипизированных файлов |
procedure Seek(var F: File; N: Integer); | Перемещает текущую позицию в файле к записи N (первая запись имеет номер 0) |
procedure Truncate(var F: File); | Стирает из файла данные, расположенные за текущей позицией |
procedure Write([var F: File]; P1; [ . .., PN]); | Записывает в файл F одну или несколько записей |
5 1 голос
Рейтинг статьи
Delphi записать в текстовый файл
AssignFile Связывает дескриптор файла с бинарным или текстовым файломBlockRead Читает блок записей данных из нетипизированного двоичного файла
BlockWrite Записывает блок записей данных в нетипизированный двоичный файл
File Определяет типизированный или нетипизированный файл
Read Позволяет прочитать данные из двоичного или текстового файла
ReadLn Позволяет прочитать полную строку данных из текстового файла
Reset Открывает текстовый файл для чтения, или двоичный файл для чтения/записи
ReWrite Открывает текстовый или двоичный файл для записи
TextFile Объявляет типа файл для того, чтобы сохранить строки текста
WriteLn Записывает законченную строку данных в текстовый файл
Базовый файловый ввод-вывод в Delphi
Каждый программист должен уметь работать с текстовыми файлами, файлами, содержащими записи, и файлами, которые не имеют определенной структуры или обрабатываются так, как если бы они не имели структуры. Вначале мы рассмотрим текстовые файлы, поскольку этот тип файлов используется наиболее часто.
Для получения доступа к текстовым файлам служат переменные типа Text:
Прежде чем можно будет приступить к работе с файлом, с помощью процедуры AssignFile его нужно присвоить переменной типа Text. Эта процедура принимает два параметра: переменную файла и имя файла.
После того как имя файла присвоено переменной файла, необходимо определить действия, которые нужно выполнять с файлом. Файл можно подготовить к чтению, записи или дополнению.
Чтобы подготовить файл к записи, необходимо использовать процедуру Rewrite, которая всегда создаст новый пустой файл. Если файл с таким же именем файла уже существует, процедура Rewrite вначале удаляет существующий файл, а затем заменяет его новым пустым файлом. Затем процедура открывает файл и устанавливает указатель позиции на начало файла.
При работе с текстовыми файлами процедуре Rewrite необходимо передавать только переменную типа Text:
Когда файл открыт и готов к записи, для записи текста в текстовый файл можно использовать стандартную процедуру WriteLn. При выполнении записи в текстовый файл первым параметром, переданным процедуре WriteLn, должна быть переменная файла:
По завершении работы с файлом его всегда следует закрывать, чтобы обеспечить корректное сохранение файла на диске и освободить любую память, занятую в процессе записи. Для закрытия файла служит процедура CloseFile, принимающая единственный параметр — файл, который нужно закрыть:
Пример программы записи строки текста в текстовый файл приведен в листинге 8.1.
Листинг 8.1. Запись текста в текстовый файл
Для подготовки файла к чтению используется процедура Reset. Эта процедура, подобно процедуре Rewrite, принимает только параметр типа файла. Ее можно считать безопасной в том смысле, что она успешно работает, если дисковод и/или каталог, указанный в имени файла, существует. В отличие от Rewrite, выполнение процедуры Reset будет невозможным, если файл, присвоенный переменной файла, не существует.
Для выполнения чтения данных из текстового файла можно использовать процедуру ReadLn. При этом первым передаваемым процедуре параметром должна быть переменная файла, а вторым — строковая переменная, которая будет временно хранить значение, считанное из файла.
Следующий пример демонстрирует считывание значений из текстового файла и их отображение на экране.
Листинг 8.2. Считывание текста из текстового файла
Этот код будет успешно работать до тех пор, пока существует файл data. txt. Если этот файл не существует, программа даст сбой. Во избежание остановки приложения при отсутствии файла необходимо выполнять проверку успешности открытия файла с помощью процедуры Reset.
Для выяснения наличия ошибок ввода-вывода необходимо непосредственно после вызова процедуры ввода-вывода, такой как Rewrite или Reset, вызвать функцию IOResult. Функция IOResult возвращает результат последней выполненной операции ввода-вывода. Если IOResult возвращает 0, это означает, что операция была выполнена успешно.
Для выполнения проверки ввода-вывода с помощью функции IOResult необходимо вначале отключить автоматическую проверку ввода-вывода. Для включения и отключения проверки ошибок ввода-вывода служит директива компилятора SI. Обычно автоматическую проверку ввода-вывода отключают перед вызовом процедуры ввода-вывода и снова включают сразу после выполнения этого вызова:
Следующий пример иллюстрирует выполнение проверки ввода-вывода и считывание текста из файла только в случае успешного его открытия.
Листинг 8.3. Проверка ошибок ввода-вывода
Помните, что после обращения к процедуре ввода-вывода функцию IOResult можно вызывать только один раз. Это обусловлено тем, что она сбрасывает результат выполнения последней операции ввода-вывода в 0. Поэтому, если вызвать функцию IOResult дважды подряд, первое обращение к ней правильно сообщит об ошибке, но второе обращение сообщит (ошибочно), что операция была выполнена успешно.
Когда нужно выполнить считывание всего текстового файла, его необходимо считывать последовательно до достижения конца файла. Для определения конца файла служит функция Eof. Эта функция принимает единственный параметр файла и возвращает булевское значение, указывающее, был ли достигнут конец файла:
Как правило, наиболее рациональный способ считывания текстового файла предусматривает использование цикла while, продолжающего итерации вплоть до достижения конца файла. Следующий пример иллюстрирует копирование содержимого одного текстового файла в другой с использованиемцикла while not Eof (результаты можно видеть на рис. 8.1).
Листинг 8.4. Копирование текстового файла
Рис. 8.1. Копирование текстового файла
В следующем примере цикл while not Eof в функции GetLineCount используется для получения количества строк текстового файла. Полученный результат затем используется в вызове функции SetLength для изменения размера динамического массива.
Листинг 8.5. Загрузка текстового файла в динамический массив
Как только приложение загрузило весь текстовый файл в динамический массив, файл можно закрыть и продолжить работу со строками в памяти. Конечно, со строками в массиве можно выполнять любые действия, но этот код всего лишь с помощью функции Uppercase преобразует (временно) символы строк в прописные и отображает их на экране.
Типизированные файлы представляют собой двоичные файлы, которые содержат элементы одинакового размера. Обычно типизированные файлы — это файлы, содержащие записи. Чтобы создать типизированный файл, вначале, используя следующий синтаксис, необходимо создать новый файловый тип данных:
В следующем коде продемонстрировано создание нового файлового типа, который можно использовать для считывания и записи записей в типизированном файле:
Обратите внимание, что строковые поля в объявлении записи имеют явно определенную длину. Длина строки должна быть определена явно, поскольку размер всей записи должен оставаться постоянным. Если требуется сохранить запись в файле на диске, обычные строки использовать нельзя, поскольку их длина может изменяться в любое время и компилятор не может определить их длину во время компиляции.
Существует несколько различий между текстовыми и типизированными файлами:
- При сбросе типизированного файла в нем можно выполнять считывание и запись (при сбросе текстового файла в нем можно выполнять только считывание).
- При выполнении считывания или записи из типизированного файла необходимо использовать процедуры Read и Write, а не ReadLn и WriteLn.
В листинге 8.6 демонстрируется работу с типизированными файлами.
Листинг 8.6. Работа с типизированными файлами
Еще одно существенное различие между текстовыми и типизированными файлами состоит в том, что в то время как текстовые файлы допускают только последовательный доступ, типизированные файлы допускают произвольный доступ к записям файла. Произвольный доступ возможен вследствие того, что все записи в файле имеют одинаковый размер, поэтому для считывания конкретной записи процедуре достаточно пропустить определенное, легко определяемое количество байт.
Для определения количества записей в файле можно использовать функцию FileSize. Для перехода к определенной записи в файле можно использовать процедуру Seek. Эта процедура принимает два параметра: переменную файла и целочисленное значение, указывающее номер записи (начиная с О), к которой необходимо выполнить переход.
Нетипизированные файлы — это файлы без определенной структуры. В общем случае, нетипизированные файлы — это типизированные файлы, в которых вместо записей используются байты. Объявление переменной нетипизированного файла выглядит следующим образом:
При работе с нетипизированными файлами обращения к процедурам Reset и Rewrite выглядят несколько иначе. Обычно обе эти процедуры в качестве заданного по умолчанию размера записи используют 128 байт. При работе с нетипизированными файлами этот размер должен быть установлен равным 1 байту. Это можно выполнить, передавая 1 в качестве второго параметра в обоих вызовах:
Для считывания и записи данных в нетипизированные файлы применяются процедуры BlockRead и BlockWrite. Объявления этих процедур показаны ниже:
Первый параметр — переменная нетипизированного файла, используемая для доступа к файлу на диске. Второй параметр — буфер, который процедуры используют для передачи данных в файл и из него.
Обычно этот буфер представляет собой статический массив байтов, но он может быть также и записью. Третий параметр указывает количество передаваемых байтов. Обычно это число равно размеру массива, который легко определить с помощью функции SizeOf. Необязательный параметр-переменная AmtTransferred можно использовать для отслеживания точного числа байтов, переданных в файл и из него.
Приложение, код которого представлен в листинге 8.7, использует процедуры BlockRead и BlockWrite для предоставления пользователю возможности копирования файлов. Приложение также дает пользователю возможность указывать имена исходного и целевого файлов в командной строке, как показано на рис. 8.2.
Рис. 8 .2. Передача параметров приложению
Листинг 8. 7. Копирование файлов с помощью процедур BlockRead и BlockWrite
Для выяснения количества параметров, которые пользователь передал приложению, применяется функция ParamCount. Эта функция не принимает никаких параметров и возвращает значение 0. если пользователь вызвал приложение без дополнительных параметров.
Для считывания параметров, переданных приложению, служит функция ParamStr, которая принимает единственный параметр типа Integer — индекс параметра. Если передать этой функции значение О, она возвратит путь и имя файла приложения. Индексы пользовательских параметров, если они переданы, начинаются с 1.
Вначале приложение проверяет, передал ли пользователь два параметра в командной строке. Если да, то ParamStr (1) содержит путь к исходному файлу, а ParamStr (2) — путь к файлу назначения.
Копирование выполняется в процедуре BlockCopyFile.
Ее первая строка:
использует функцию LowerCase для временного преобразования имен обоих файлов в строчные буквы и проверяет, указывают ли оба имени файлов на один и тот же файл. Если файл назначения и файл-источник совпадают, никакое копирование не требуется и оператор if-then вызывает процедуру Exit для выхода из процедуры.
Основная часть процедуры BlockCopyFile — цикл while, который вызывает процедуры BlockRead и BlockWrite:
Процедура BlockRead считывает из файла 1 Кбайт данных, записывает эти данные в массив Buffer и обновляет переменную BytesRead, которая всегда содержит точное количество переданных байтов. Выполнение цикла будет повторяться до тех пор, пока процедура BlockRead продолжает считывать данные из файла. Когда эта процедура достигнет конца файла, значение переменной BytesRead будет сброшено в 0, условие цикла while станет ложным и копирование файла завершится.
Чтение и запись переменных типа Record
Чтение и запись переменных типа Record Файл с множеством записей Обычно, я использую файл с заголовком, который я затем загружаю в память, и использую его для поиска необходимой мне записи.
type
TSaveHeader = record
scene: Integer;
hotspots: LongInt;
talk: LongInt;
hype: LongInt;
end;
var
SaveHeader: TSaveHeader;
procedure OpenSaveFile(fname: string);
var
f: file;
i: Integer;
begin
AssignFile(f, fname);
Reset(f, 1);
BlockRead(f, SaveHeader, Sizeof(TSaveHeader));
{ получаем один набор записи }
Seek(f, SaveHeader.hotspots);
for i := 1 to 50 do
BlockRead(f, somevar, sizeof_hotspotrec);
{ и так далее }
CloseFile(f);
end;
{ предположим, что файл открыт }
procedure GetHotspotRec(index: LongInt; var hotspotrec: THotspot);
var
offset: LongInt;
begin
offset := SaveHeader.hotspots + index * Sizeof(THotSpot);
Seek(f, offset);
BlockRead(f, hotspotrec, Sizeof(THotspot));
end;
Добавление записи в файл
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Edit1: TEdit; // спортсмен
ComboBox1: TComboBox; // страна
ComboBox2: TComboBox; // вид спорта
RadioGroup1: TRadioGroup; // медаль
Button1: TButton; // кнопка Добавить
Label5: TLabel;
Label4: TLabel;
procedure FormActivate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
// тип медали
TKind = (GOLD, SILVER, BRONZE);
// запись файла
TMedal = record
country: string[20]; // страна
sport: string[20]; // вид спорта
person: string[40]; // спортсмен
kind: TKind; // медаль
end;
var
Form1: TForm1;
f: file of TMedal; // файл записей — база данных
implementation
{$R *. DFM}
// активизация формы
procedure TForm1.FormActivate(Sender: TObject);
var
resp: word; // ответ пользователя
begin
AssignFile(f, ‘a:\medals.db’);
{$I-}
Reset(f); // открыть файл
Seek(f, FileSize(f)); // указатель записи в конец файла
{$I+}
if IOResult = 0
then button1.enabled := TRUE // теперь кнопка Добавить доступна
else
begin
resp := MessageDlg(‘Файл базы данных не найден.’ +
‘Создать новую БД?’, mtInformation, [mbYes, mbNo], 0);
if resp = mrYes then
begin
{$I-}
rewrite(f);
{$I+}
if IOResult = 0
then button1.enabled := TRUE
else ShowMessage(‘Ошибка создания файла БД.’);
end;
end;
end;
// щелчок на кнопке Добавить
procedure TForm1.Button1Click(Sender: TObject);
var
medal: TMedal;
begin
with medal do
begin
country := ComboBox1.Text;
sport := ComboBox2. Text;
person := Edit1.Text;
case RadioGroup1.ItemIndex of
0: kind := GOLD;
1: kind := SILVER;
2: kind := BRONZE;
end;
end;
write(f, medal); // записать содержимое полей записи в файл
end;
// завершение работы программы
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
CloseFile(f); // закрыть файл
end;
end.
DelphiWorld 6.0
Запись и чтение из файла массива записей
Это не очень Delphi-подобно (тем не менее, работа происходит с действительно паскалевскими записями), но вы можете писать и читать записи из/в файл, используя паскалевские процедуры для работы с файлами:
type
TMyRec = record ;
Field1: integer;
Field2: string;
end;
TMyRecArray = array[0..9] of TMyRec;
var
MyArray: TMyRecArray;
MyRec: TMyRec;
RecFile: file of TMyRec;
begin
{…здесь должен быть расположен код инициализации MyArray…}
AssignFile(RecFile, ‘MYREC.FIL’);
ReWrite(RecFile);
for i := 0 to 9 do
begin
Write(RecFile, MyRec[i]);
end;
CloseFile(RecFile);
end;
DelphiWorld 6.0
Запись и чтение из файла массива записей
Name:string[100];
Age:Byte;
Income:Real;
end;
var f:file of TR;
r:TR;
begin
//assign file
assignFile(f, ‘MyFileName’);
//open file
if FileExists(‘MyFileName’) then
reset(f)
else
rewrite(f);
//чтение 10й записи
seek(f,10);
read(f,r);
//запись 20й записи
seek(f, 20);
write(f,r);
closefile(f);
end;
DelphiWorld 6.0
Инструкция по установке ODIS 5.1.6, ODIS 5.1.3 и ODIS 4.4.10
Рекомендуемой операционной системой для работы VAS 5054A с ODIS 4.4.10 является Windows 7, при этом данная версия программы ODIS 4.4.10 на Windows 8 и 10 с VAS 5054A работать не будет. Последняя версия ODIS, которая работает с VAS 5054A на windows 10 и windows 8 является ODIS-Service 3.0.3 и ODIS-Engineering 6.6.1. В настоящий момент появилось решение позволяющее обойти это официальное ограничение и VAS 5054A может работать с Windows 10 с новыми версиями ODIS-Service и ODIS-Engineering, более подробно об установке ODIS на Windows 10 для VAS5054A в нашей следующей статье.
В настоящее время имеется новая версия ODIS 5.1.6. Инструкция по установке ODIS 5.1.6 аналогична установке программного обеспечения более ранней версии ODIS 4.4.10. При покупке диагностического сканера VAS 5054A в нашем интернет-магазине Вы получаете всегда новую актуальную версию программного обеспечения.
В рамках данной статьи рассматриваем установку на чистую операционную систему windows 7 32-bit. Перед этапом инсталлирования ODIS 4.4.10 в случае, когда на компьютере установлены более ранние версии ODIS необходимо выполнить их полное удаление.
Производим установку ODIS 4.4.10Для начала установки производим запуск OffboardDiagSetup-Service_VWMCD_4_4_10-B44_10_0_2.exe, запуск производим от имени администратора.
Выбираем язык установки. Для установки русского языка выбираем «Русский (RU)» и нажимаем OK
Нажимаем «Далее»
Выбираем путь установки (по умолчанию C:\Program Files (x86)\Offboard_Diagnostic_Information_System_Service) и жмем «Далее»
Целевая папка компонентов диагностики (по умолчанию C:\ODIS-DIAG-MODULES) и жмем «Далее»
В выборе платформы выбираем «Обычный ПК/ноутбук» и жмем «Далее»
В выборе активируемого диагностического интерфейса выбираем «VAS 5054» и жмем «Далее»
В следующем окне представлена информация по использованию VAS5054 с программой жмем «Далее»
В выборе файла лицензии с помощью кнопки «Обзор…» выбираем файл с лицензией (license.dat) и нажимаем «Далее»
В следующем окне нажимаем «Далее»
Начинается установка программы
В случае появления сообщений безопасности Windows о вопросе установки программного обеспечения для данного устройства ставим галку в поле «Всегда доверять программному обеспечению» и нажимаем «Установить»
Для завершения работы мастера установки нажимаем «Готово»
Перезагружаем компьютер
Производим запуск программы ODIS с рабочего стола
В окне ввода данных конфигурации PostSetup нажимаем «Выбор локального каталога…» и выбираем папку с обновлениями PostSetup (папка ODIS-Service_update_4_4_10-EU_20180807_s4DzQ) и нажимаем «OK»
Далее нажимаем на стрелку
Выбираем язык установки PostSetup, для установки русского языка выбираем «Русский (RU) (ru_RU)» (остальные языки выбирать не надо) и жмем на правую стрелку
Для установки обновления нажимаем на правую стрелку
Начинается достаточно долгий процесс установки PostSetup
После установки PostSetup открывается окно установленной программы, читаем информацию и жмем «OK»
Программа готова к использованию.
Подключаем VAS 5054A в USB и к автомобилю, производим установку драйвера, либо производим сопряжение трансмиттера посредством Bluetooth.
Обращаем внимание, что предлагаемые нами адаптеры VAS 5054A с оригинальным OKI M6636 (не путать с OKI M6636B, т.к. микросхемы OKI M6636 и OKI M6636B это не аналоги и имеют разную распиновку) полностью работоспособны с ODIS 4.4.10 и не требуют дополнительной доработки, а также поддерживают режим PassThru (J2534).
Подключение VAS 5054A по USB к ODIS подробно описано в нашей статье.
Подключение VAS 5054A по bluetooth к ODIS подробно описано в нашей статье.
Производим диагностику транспортного средства
Возможные вопросы при установке:
1) В выборе активируемого диагностического интерфейса отсутствует «VAS 5054»
Установка производится на операционную систему windows 8 или windows 10, при этом VAS 5054A с ODIS 4.4.10 работает только с Windows 7. Последняя версия ODIS, которая работает с VAS 5054A на windows 10 и windows 8 является ODIS-Service 3.0.3 и ODIS-Engineering 6.6.1.
2) Во время установки PostSetup в окне ввода данных конфигурации при выборе локального каталога через «Выбор локального каталога…» появляется сообщение «По указанному URL найти действительную конфигурацию ПО не удалось. Выберите другой URL»
Не верно выбрана папка с обновлениями, выбираем папку с PostSetup, содержащую обновления
3) Во время установки PostSetup появляется сообщение с ошибкой: !!! KB3033929/KB2921916/ERROR contact your administrator !!!
Произвести обновление для системы безопасности Windows 7 (KB3033929) с официального сайта microsoft и продолжить установку.
4) Ошибка: Framework start failed with ’13’
Данная ошибка возникает на этапе активации программы и решается повторной правильной активацией.
5) При запуске программы ODIS появляется сообщение с ошибкой: «failure creating the framework …»
Данная ошибка часто возникает после использования флешера GALLETTO 2 v54, для решения проверяем системную дату, установленную на компьютере и устанавливаем текущую дату.
6) При запуске программы появляется сообщение с предупреждением: ODS9013E Инфраструктура. Соединение онлайн VW.MirrorServer 2: В структуре данных обновления имеется ошибка. Обратитесь в службу поддержки.» а затем «ODS9023E Инфраструктура. Соединение онлайн VW.MirrorServer 2: Следующие языки на выбранном MirrorServer недоступны.» где будут отображаться все языки, выбранные в момент установки PostSetup (ru_RU, de_DE, en_US, en_GB и др)
Данные ошибки связаны с некорректностью (невозможностью) подключения к серверу обновлений и на функциональность программы не влияют (официальным пользователям рекомендовано обратиться в службу поддержки для корректного решения данного вопроса). Для уменьшения количества данных предупреждений в меню программы ODIS заходим в «Администрирование», далее во вкладке «Общее» выбираем пункт «Обновление» и устанавливаем периодичность обновлений в 7 дней. Для того чтобы совсем отключить данное сообщение необходимо открыть с помощью блокнота файл: «C:\Program Files (x86)\Offboard_Diagnostic_Information_System_Service\configuration\.settings\org.eclipse.internal.prefs и в строке VAUDAS_Day_Of_Last_Update=1538502826322 меняем значение на VAUDAS_Day_Of_Last_Update=111111111111111111
После данной процедуры сервис обновления будет работать только в ручном режиме.
7) При запуске программы ODIS появляется сообщение с ошибкой: ODS2522E Инфраструктура: Используемое здесь аппаратное обеспечение интерфейса автомобиля не поддерживается
Для решения данной ошибки запускаем файл ODS2522E_Fix_x86.exe или ODS2522E_Fix_x64.exe в зависимости от разрядности операционной системы.
Купить VAS 5054A с оригинальными OKI M6636 и TJA1054AT в качественном исполнении в интернет-магазине TOPDIAG.BY
SecretSilent — Мой little cyber-мир
Один из блогеров, ролики которого я иногда смотрю, всех приветствует примерно похожей фразой: «Hello, friends! Uuuhhh you look so beautiful today, totally stunning!» 🙂 Почти повторю и поздороваюсь (это почему-то не стало привычкой в моем недоблоге): «Доброго дня вам, мои дорогие друзья!»
Время от времени делаю усиленные попытки не забывать английский язык и смотрю/слушаю иностранные ролики. А совмещать с чем-то реально интересным для меня — польза вдвойне 🙂 Сегодня смотрела/слушала интервью — хоть и пятилетней давности — с вокалистом группы Starset Дастином Бэйтсом. Знакома с этим коллективом больше года наверное, но сподобилась побольше их послушать только сейчас. При прослушивании песни для каждого человека какой-то ее аспект будет играть главенствующую роль: насколько быстр барабанщик, насколько тяжелы гитарные рифы, каков мотивчик в целом, голос вокалиста(ов), смысл текста. Сначала прислушиваюсь к голосу. Если он мне приятен, хочется прочувствовать, о чем же там поется, а если смысла особо и нет, то мне и не интересно. А потом «зацениваю» всю аранжировку в целом. Это касается рок-групп в широком смысле этого слова. Стоит ли объяснять, что в Starset для моего восприятия все гениально сложилось вместе? Невероятно привлекательный вокал + тексты + инструменты (скрипка + электроника + гитары — так можно было? — невообразимо гармоничное сочетание). А переходы от спокойного вокала к агрессиву с хрипотцой? 💗 Была бы я 14-летней девочкой, завесила бы всю свою комнату плакатами Starset и Дастина Бэйтса 😁. Но я же серьезная женщина, поэтому Starset — неизменный спутник моих плейлистов сейчас.
Так вот в этом интервью он рассказывает и о самой группе, и кто вдохновляет на написание песен, и о смысле деятельности, композиций. Приятно послушать богатую и грамотную речь. Рекомендую 🙂
И вот еще одно неплохое:
Чтение файлов Excel (Delphi) | FlexCel Studio для VCL и FireMonkey документация
Обзор
Демонстрация, показывающая, как читать содержимое файла Excel с помощью FlexCel.
Концепции
Для чтения файла Excel вы используете класс TXlsFile, откуда вы может читать и писать в любой Excel 2.0 или новее файл.
Чтобы получить значение для отдельной ячейки, используйте TXlsFile.GetCellValue.
Чтобы получить значение ячейки при зацикливании всего листа, используйте TXlsFile.GetCellValueIndexed. Это быстрее, чем использовать GetCellValue, поскольку вы будете читать только используемые ячейки.
TXlsFile.GetCellValue и TXlsFile.GetCellValueIndexed вернет TCellValue, который будет одним из объектов, разрешенных в ячейке Excel
.С помощью GetCellValue и GetCellValueIndexed вы получите фактическое значения.Но если вы действительно хотите отображать отформатированные данные (для пример, если у вас есть число 2 с двумя десятичными знаками, и вы хотите display 2.00 вместо 2), нужно использовать другие методы. Там есть 2 способа сделать это:
TXlsFile.GetStringFromCell вернет богатую строку с ячейка отформатирована.
FormatValue отформатирует объект с помощью указанный формат, а затем вернуть соответствующую расширенную строку. TFlxNumberFormat.FormatValue используется внутри компании GetStringFromCell.
В Excel Даты дублируются . Единственная разница между свиданием и двойник находится в формате на ячейке. С участием FormatValue вы можете получить фактическую строку, которая отображается в Excel. Кроме того, чтобы преобразовать это двойное значение в DateTime, вы можете использовать TFlxDateTime.FromOADate.
Файлы
UReadingFiles.pas
блок UReadingFiles;
интерфейс
использует
Окна, Сообщения, SysUtils, Варианты, Классы, Графика,
Элементы управления, формы, диалоги, ImgList, ActnList, StdCtrls,
Вкладки, сетки, ExtCtrls, ComCtrls, ToolWin, UPaths,
VCL.FlexCel.Core, FlexCel.XlsAdapter;
тип
TFReadingFiles = класс (TForm)
ToolBar1: TToolBar;
ToolButton1: TToolButton;
ToolButton2: TToolButton;
ToolButton3: TToolButton;
ToolButton5: TToolButton;
ToolButton4: TToolButton;
ToolButton6: TToolButton;
SheetData: TStringGrid;
Вкладки: TTabSet;
Panel2: TPanel;
Label1: TLabel;
FmtBox: TEdit;
Действия: TActionList;
ActionOpen: TAction;
ActionValueInCurrentCell: TAction;
ActionInfo: TAction;
ActionClose: TAction;
OpenDialog: TOpenDialog;
ToolbarImages: TImageList;
StatusBar: TStatusBar;
ToolButton7: TToolButton;
ActionFormatValues: TAction;
ToolbarImages_300Scale: TImageList;
ToolbarImages_100Scale: TImageList;
Panel1: TPanel;
процедура ActionCloseExecute (Отправитель: TObject);
процедура ActionInfoExecute (Отправитель: TObject);
процедура ActionOpenExecute (Отправитель: TObject);
процедура ActionValueInCurrentCellExecute (Sender: TObject);
процедура SheetDataSelectCell (Sender: TObject; ACol, ARow: Integer;
var CanSelect: Boolean);
процедура ActionFormatValuesExecute (Отправитель: TObject);
процедура TabsClick (Отправитель: TObject);
процедура FormCreate (Отправитель: TObject);
частный
UpdatingCount, UpdatingCellsCount: целое число;
XLS: TExcelFile;
процедура ImportFile (const FileName: string);
процедура FillTabs;
процедура FillGrid (const Formatted: boolean);
процедура SelectedCell (const aCol, aRow: целое число);
процедура AnalizeFile (const Row, Col: integer);
функция FormatValue (const v: TCellValue; const Row,
Столбец: целое число): Строка;
процедура ClearGrid;
процедура ResizeGrid;
процедура BeginUpdatingGrid;
процедура EndUpdatingGrid;
процедура BeginUpdatingGridCells;
процедура EndUpdatingGridCells;
{Частные заявления}
общественный
деструктор Destroy; переопределить;
{Публичные заявления}
конец;
вар
FReadingFiles: TFReadingFiles;
выполнение
использует UFlexCelHDPI;
{$ R *.dfm}
процедура TFReadingFiles.ActionCloseExecute (Sender: TObject);
начинать
Закрывать;
конец;
процедура TFReadingFiles.ActionFormatValuesExecute (Sender: TObject);
начинать
ActionFormatValues.Checked: = не ActionFormatValues.Checked;
FillGrid (ActionFormatValues.Checked);
конец;
процедура TFReadingFiles.ActionInfoExecute (Отправитель: TObject);
начинать
ShowMessage ('Эта демонстрация показывает, как читать содержимое файла xls' + # 10 +
Кнопка «Открыть файл» загрузит файл Excel в набор данных.'+ # 10 +
Кнопка «Форматировать значения» применит формат к ячейкам или покажет необработанные данные. '+ # 10 +
Кнопка «Значение в текущей ячейке» отобразит дополнительную информацию о ячейке, выбранной в сетке. Попробуйте с формулами. ');
конец;
процедура TFReadingFiles.ActionOpenExecute (Отправитель: TObject);
начинать
если не OpenDialog.Execute, тогда выйти;
ImportFile (OpenDialog.FileName);
конец;
процедура TFReadingFiles.ActionValueInCurrentCellExecute (Отправитель: TObject);
начинать
AnalizeFile (SheetData.Строка, SheetData.Col);
конец;
деструктор TFReadingFiles.Destroy;
начинать
FreeAndNil (XL);
унаследованный;
конец;
процедура TFReadingFiles.SheetDataSelectCell (Sender: TObject; ACol,
ARow: целое число; var CanSelect: Boolean);
начинать
SelectedCell (aCol, aRow);
CanSelect: = true;
конец;
процедура TFReadingFiles.TabsClick (Отправитель: TObject);
начинать
FillGrid (ActionFormatValues.Checked);
конец;
процедура TFReadingFiles.FillTabs;
вар
s: целое число;
начинать
Tabs.Tabs.Clear;
для s: = 1 в Xls.SheetCount сделать
начинать
Tabs.Tabs.Add (Xls.GetSheetName (s));
конец;
конец;
процедура TFReadingFiles.ImportFile (const FileName: string);
вар
StartOpen: TDateTime;
EndOpen: TDateTime;
EndFill: TDateTime;
начинать
// Открываем файл Excel.
если Xls = nil, то Xls: = TXlsFile.Create (false);
StartOpen: = Сейчас;
xls.Открыть (Имя файла);
EndOpen: = Сейчас;
FillTabs;
Tabs.TabIndex: = Xls.ActiveSheet - 1;
EndFill: = Сейчас;
StatusBar.SimpleText: = 'Время загрузки файла:' + ElapsedTime (EndOpen, StartOpen) + 'Время загрузки файла и заполнения сетки:' + ElapsedTime (EndFill, StartOpen);
Заголовок: = 'Чтение файлов:' + ExtractFileName (Имя файла);
конец;
процедура TFReadingFiles.ClearGrid;
вар
r: целое число;
начинать
BeginUpdatingGrid;
пытаться
для r: = 1 в SheetData.RowCount do SheetData.Rows [r] .Clear;
наконец-то
EndUpdatingGrid;
конец;
конец;
процедура TFReadingFiles.BeginUpdatingGrid;
начинать
Inc (UpdatingCount);
если (UpdatingCount = 1), то
начинать
Отправить сообщение (SheetData.Handle, WM_SETREDRAW, 0, 0);
конец;
конец;
процедура TFReadingFiles.EndUpdatingGrid;
начинать
Dec (UpdatingCount);
если (UpdatingCount = 0), то
начинать
Отправить сообщение (SheetData.Handle, WM_SETREDRAW, 1, 0);
RedrawWindow (SheetData.Handle, nil, 0, RDW_ERASE или RDW_FRAME или RDW_INVALIDATE или RDW_ALLCHILDREN);
конец;
конец;
процедура TFReadingFiles.BeginUpdatingGridCells;
вар
c: целое число;
начинать
Inc (UpdatingCellsCount);
если (UpdatingCellsCount = 1), то
начинать
для c: = 1 в SheetData.ColCount выполните SheetData.Cols [c] .BeginUpdate;
конец;
конец;
процедура TFReadingFiles.EndUpdatingGridCells;
вар
c: целое число;
начинать
Dec (UpdatingCellsCount);
если (UpdatingCellsCount = 0), то
начинать
для c: = 1 в SheetData.ColCount do SheetData.Cols [c] .EndUpdate;
конец;
конец;
процедура TFReadingFiles.FillGrid (const Formatted: boolean);
вар
r, c, cIndex: целое число;
v: TCellValue;
начинать
если Xls = nil, тогда выйти;
BeginUpdatingGrid;
пытаться
если (Tabs.TabIndex + 1 <= Xls.SheetCount) и (Tabs.TabIndex> = 0), то Xls.ActiveSheet: = Tabs.TabIndex + 1 else Xls.ActiveSheet: = 1;
// Очистить данные в предыдущей сетке
ClearGrid;
SheetData.RowCount: = 1;
SheetData.ColCount: = 1;
FmtBox.Text: = '';
SheetData.RowCount: = Xls.RowCount + 1; // Включаем фиксированную строку
SheetData.ColCount: = Xls.ColCount + 1; // Включить фиксированный столбец. ОБРАТИТЕ ВНИМАНИЕ, ЧТО СЧЕТ МЕДЛЕННЫЙ. Мы используем его здесь, потому что он нам очень нужен. См. Документ Performance.pdf.
BeginUpdatingGridCells;
пытаться
если (SheetData.ColCount> 1), то SheetData.FixedCols: = 1; // он удаляется, когда мы устанавливаем ширину 1.
если (SheetData.RowCount> 1) затем SheetData.FixedRows: = 1;
для r: = 1 в Xls.RowCount сделать
начинать
// Вместо того, чтобы перебирать все столбцы, мы просто перебираем те, у которых есть данные. Это намного быстрее.
для cIndex: = 1 в Xls.ColCountInRow (r) сделать
начинать
c: = Xls.ColFromIndex (r, cIndex); // Настоящий столбец.
если отформатировано, то
начинать
SheetData.Cells [c, r]: = Xls.GetStringFromCell (r, c);
конец
еще
начинать
v: = XLS.GetCellValue (r, c);
SheetData.Cells [c, r]: = v.ToString;
конец;
конец;
конец;
ResizeGrid;
SelectedCell (1,1);
наконец-то
EndUpdatingGridCells;
конец;
наконец-то
EndUpdatingGrid;
конец;
конец;
процедура TFReadingFiles.ResizeGrid;
вар
r, c: целое число;
начинать
BeginUpdatingGrid;
пытаться
BeginUpdatingGridCells;
пытаться
если Xls = nil, то
начинать
SheetData.DefaultColWidth: = Round (64,0 * Font.PixelsPerInch / 96,0);
SheetData.DefaultRowHeight: = Round (18,0 * Font.PixelsPerInch / 96,0);
выход;
конец;
если (Tabs.TabIndex + 1 <= Xls.SheetCount) и (Tabs.TabIndex> = 0), то Xls.ActiveSheet: = Tabs.TabIndex + 1 else Xls.ActiveSheet: = 1;
SheetData.RowHeights [0]: = Round (20 * Font.PixelsPerInch / 96,0);
SheetData.ColWidths [0]: = Round (50 * Font.PixelsPerInch / 96,0);
// Заполняем заголовки строк
для r: = 1 в SheetData.RowCount - 1 шт.
начинать
SheetData.Cells [0, r]: = IntToStr (r);
SheetData.RowHeights [r]: = Round (Xls.GetRowHeight (r) / TExcelMetrics.RowMultDisplay (Xls) * Font.PixelsPerInch / 96,0);
конец;
// Заполняем заголовки столбцов
для c: = 1 в SheetData.ColCount - 1 сделать
начинать
SheetData.Cells [c, 0]: = TCellAddress.EncodeColumn (c);
SheetData.ColWidths [c]: = Round (Xls.GetColWidth (c) / TExcelMetrics.ColMult (Xls) * Font.PixelsPerInch / 96,0);
конец;
наконец-то
EndUpdatingGridCells;
конец;
наконец-то
EndUpdatingGrid;
конец;
конец;
процедура TFReadingFiles.SelectedCell (const aCol, aRow: целое число);
вар
Fmt: TFlxFormat;
начинать
если Xls = nil, тогда выйти;
если (aRow <1) или (aCol <1), тогда выйти;
Fmt: = Xls.GetCellVisibleFormatDef (aRow, aCol);
FmtBox.Text: = Fmt.Format;
конец;
процедура TFReadingFiles.AnalizeFile (константная строка, столбец: целое число);
вар
v: TCellValue;
Fmla: TFormula;
начинать
если (Xls = nil), то
начинать
ShowMessage ('Сначала нужно открыть файл');
выход;
конец;
если (Row <1) или (Col <1) или (Row> SheetData.RowCount - 1) или (Col> SheetData.ColCount - 1), то
начинать
ShowMessage ('Выбранная ячейка недействительна.');
выход;
конец;
ShowMessage (('Активный лист "" + xls.SheetName) + '"');
v: = xls.GetCellValue (строка, столбец);
// Сначала посмотрим, формула ли это
если v.IsFormula, то
начинать
Fmla: = v.AsFormula;
ShowMessage ('Cell' + TCellAddress.Create (Row, Col) .CellRef + 'содержит формулу:' + Fmla.Text + # 10 +
'Результат формулы:' + FormatValue (Fmla.FormulaResult, Row, Col));
выход;
конец;
ShowMessage ('Cell' + TCellAddress.Create (Row, Col) .CellRef + 'is' + FormatValue (v, Row, Col));
конец;
функция TFReadingFiles.FormatValue (const v: TCellValue; const Row, Col: integer): String;
вар
CellValue: String;
Отформатировано: строка;
HasDate, HasTime: логическое;
CellColor: TUIColor;
начинать
case v.ValueType of
TCellValueType.Empty: exit ('пусто');
TCellValueType.Boolean: exit ('логическое значение:' + BoolToStr (v.AsBoolean, true));
TCellValueType.Error: exit ('ошибка:' + TFormulaMessages.ErrString (v.AsError));
TCellValueType.Number:
begin // Помните, даты дублируются с форматом даты.Кроме того, все числа возвращаются как двойные, даже если они целые.
CellColor: = TUIColor.Empty;
CellValue: = TFlxNumberFormat.FormatValue (v, xls.GetCellVisibleFormatDef (Row, Col) .Format, CellColor, xls, HasDate, HasTime) .ToString;
если HasDate или HasTime, то
начинать
Результат: = 'значение DateTime:' + DateTimeToStr (v.ToDateTime (xls.OptionsDates1904)) + # 10 + 'Значение отображается как:' + CellValue;
конец
еще
начинать
Результат: = 'двойной:' + FloatToStr (v.AsNumber) + # 10 + 'Значение отображается как:' + CellValue + # 10;
конец;
выход;
конец;
TCellValueType.DateTime: // FlexCel в настоящее время не возвращает значения DateTime, поскольку даты являются числами.
начинать
exit ('значение DateTime:' + DateTimeToStr (v.AsDateTime));
конец;
TCellValueType.StringValue:
начинать
если v.AsString.RTFRunCount> 0, то Formatted: = 'FORMATTED' else Formatted: = '';
Результат: = 'a' + Форматированная + 'строка:' + v.AsString.ToString
+ # 10 + 'In html:' + v.AsString.ToHtml (xls, xls.GetCellVisibleFormatDef (Row, Col), THtmlVersion.Html_32, THtmlStyle.Simple, TEncoding.UTF8);
выход;
конец;
конец;
поднять Exception.Create ('Неожиданное значение в ячейке');
конец;
процедура TFReadingFiles.FormCreate (Отправитель: TObject);
начинать
RegisterForHDPI (Самостоятельная, ResizeGrid);
конец;
конец.
Создание базы данных с использованием файла типизированных файлов Delphi
Проще говоря, файл — это двоичная последовательность определенного типа.В Delphi существует три класса файлов: типизированный, текстовый и нетипизированный . Типизированные файлы — это файлы, которые содержат данные определенного типа, например, Double, Integer или ранее определенного настраиваемого типа записи. Текстовые файлы содержат читаемые символы ASCII. Нетипизированные файлы используются, когда мы хотим наложить на файл минимально возможную структуру.
Типизированные файлы
В то время как текстовые файлы состоят из строк, заканчивающихся комбинацией CR / LF (# 13 # 10), типизированные файлы состоят из данных, взятых из определенного типа структуры данных .
Например, следующее объявление создает тип записи с именем TMember и массив переменных записи TMember.
тип
TMember = запись
Имя: строка [50];
электронная почта:
строка [30];
Сообщений: LongInt;
конец ;
var Члены: массив [1..50] из TMember;
Прежде чем мы сможем записать информацию на диск, мы должны объявить переменную типа файла.В следующей строке кода объявляется файловая переменная F.
var F: файл TMember;
Примечание: чтобы создать типизированный файл в Delphi, мы используем следующий синтаксис:
var SomeTypedFile: файл из SomeType
Базовый тип (SomeType) для файла может быть скалярным типом (например, Double), типом массива или типом записи. Это не должна быть длинная строка, динамический массив, класс, объект или указатель.
Чтобы начать работу с файлами из Delphi, мы должны связать файл на диске с файловой переменной в нашей программе. Чтобы создать эту ссылку, мы должны использовать процедуру AssignFile , чтобы связать файл на диске с файловой переменной.
AssignFile (F, 'Members.dat')
После установления связи с внешним файлом файловую переменную F необходимо «открыть», чтобы подготовить ее к чтению и записи. Мы вызываем процедуру Reset, чтобы открыть существующий файл, или Rewrite, чтобы создать новый файл.Когда программа завершает обработку файла, файл необходимо закрыть с помощью процедуры CloseFile. После закрытия файла связанный с ним внешний файл обновляется. Затем файловую переменную можно связать с другим внешним файлом.
В общем, мы всегда должны использовать обработку исключений; при работе с файлами может возникнуть много ошибок. Например: если мы вызываем CloseFile для уже закрытого файла, Delphi сообщает об ошибке ввода-вывода. С другой стороны, если мы попытаемся закрыть файл, но еще не вызвали AssignFile, результаты будут непредсказуемыми.
Запись в файл
Предположим, мы заполнили массив членов Delphi их именами, адресами электронной почты и количеством сообщений и хотим сохранить эту информацию в файле на диске. Следующий фрагмент кода выполнит работу:
вар
F: файл из TMember;
i: целое число;
начало
AssignFile (F, 'members.dat');
Перепишите (F);
попробовать
для j: = от 1 до 50 до
Запись (F, члены [j]);
наконец
CloseFile (F);
конец ; конец ;
Чтение из файла
Чтобы получить всю информацию от ‘members.dat ‘, мы будем использовать следующий код:
вар
Член: TMember
F: файл из TMember; начало
AssignFile (F, 'members.dat');
Сброс (F);
попробовать
, а не Eof (F) действительно начинаются
Чтение (F, член);
{DoSomethingWithMember;}
конец ;
наконец
CloseFile (F);
конец ; конец ;
Примечание. Eof — это функция проверки EndOfFile.Мы используем эту функцию, чтобы убедиться, что мы не пытаемся читать за пределами конца файла (за пределами последней сохраненной записи).
В поисках и позиционировании
Обычно доступ к файлам осуществляется последовательно. Когда файл читается с использованием стандартной процедуры Read или записывается с использованием стандартной процедуры Write, текущая позиция файла перемещается к следующему компоненту файла с числовым порядком (следующая запись). Типизированные файлы также могут быть доступны случайным образом с помощью стандартной процедуры Seek, которая перемещает текущую позицию файла в указанный компонент.Функции FilePos и FileSize могут использоваться для определения текущей позиции файла и текущего размера файла.
{вернуться в начало - первая запись}
Искать (F, 0);
{перейти к 5-й записи}
Искать (Ж, 5);
{Перейти в конец - "после" последней записи}
Поиск (F, Размер файла (F));
Изменение и обновление
Вы только что научились писать и читать весь массив участников, но что, если все, что вам нужно, — это обратиться к 10-му члену и изменить адрес электронной почты? Следующая процедура делает именно это:
процедура ChangeEMail ( const RecN: целое число; const NewEMail: строка ); var DummyMember: TMember; начало
{назначить, открыть, блок обработки исключений}
Seek (F, RecN);
Чтение (F, DummyMember);
DummyMember.Электронная почта: = NewEMail;
{чтение переходит к следующей записи, у нас есть
вернуться к исходной записи, затем написать}
Seek (F, RecN);
Запись (F, DummyMember);
{закрыть файл} конец ;
Завершение задания
Вот и все — теперь у вас есть все необходимое для выполнения вашей задачи. Вы можете записывать информацию об участниках на диск, вы можете читать ее обратно и даже можете изменять некоторые данные (например, электронную почту) в «середине» файла.
Важно то, что этот файл не является файлом ASCII, а вот как он выглядит в Блокноте (только одна запись):
.Delphi Guide g 5 · ì. 5.. B V.Lƒ, „¨[email protected]Ï .. ç.ç.ï ..
Ускорение чтения нескольких текстовых файлов — RTL и Delphi Object Pascal
Я подозреваю, что вы столкнулись с чем-то, из-за чего я скрипел зубами в прошлом … TStringList не самый предсказуемый с точки зрения производительности, особенно когда вы устанавливаете для свойства Sorted значение True перед его заполнением…
Когда вы устанавливаете для свойства Sorted значение True в TStringList, список строк должен (конечно) поддерживать порядок при добавлении новых строк. Для этого он должен определить, куда вставить добавляемую строку. И для выполнения этого он использует двоичный поиск. См .: TStringList.AddObject () и который вызывает TStringList.Find () перед потенциальным вызовом InsertItem (). Затем см. TStringList.Find (). Это приводит к временной сложности O (n.log n) только для чтения n строк текста из одного файла, а не только за O (n) без.
Возможно, это нормально, но есть еще кое-что. Название и методы TStringList подразумевают, что это структура списка, хотя на самом деле это не так. Базовая структура данных представляет собой непрерывный массив строк. Это означает, что фактическая вставка становится все более дорогостоящей по мере роста TStringList, потому что вставки фактически O (n), даже если она использует довольно эффективную копию. См. TStringList.InsertItem (). Хотя System.Move () — довольно быстрая «блочная копия», она, тем не менее, будет увеличиваться по мере увеличения количества элементов в строковом списке.В обычном связанном списке стоимость фактической вставки после того, как вы нашли место, куда вы хотите вставить, составляет O (1). Затем есть аспект роста, добавляющий некоторые накладные расходы, например. базовый массив должен быть увеличен / увеличен, когда количество фактических строк совпадает с емкостью массива и вставляется другая. (Можно подозревать, что все это копирование и рост потенциально могут делать неприятные вещи с кешами ЦП и т. Д., Что также не влияет на производительность.)
Итак, суть этой небольшой обличительной речи в том, что поведение TStringList может немного отличаться от того, что можно было бы ожидать, и поэтому вы должны действовать соответствующим образом.
Учитывая, что ваши списки уже отсортированы, вы должны загрузить данные в несколько строковых списков без повторной проверки или сортировки на , что позволит избежать большинства ненужных накладных расходов. А затем напишите процедуру для многократного объединения их в окончательный список. (Если вы хотите пофантазировать, возможно, используйте минимальную кучу с учетом различной длины ввода?) Или, возможно, используйте что-то еще, как предлагали другие. (Возможно, нам следует написать TFastStringList, и, пока мы на нем, сделать его сопрягаемым, чтобы я мог возвращать экземпляры IFastStringList и подсчитывать ссылки на них и т. Д… Я отвлекся.)
Отредактировано автор ByteJugglerЧтение большого файла — embarcadero.delphi.win32
Чтение / запись действительно больших файлов XML … Delphi 2009Всем привет! Мне просто интересно, какие сейчас предпочтения чтение и запись действительно больших файлов XML? Раньше я использовал SAX, но он не обновлялся для Delphi 2009.у меня есть попробовал несколько других — но у меня проблемы с действительно большими файлами — вроде более 800 МБ или около того. Брэдли к сожалению, вы можете попробовать http://www.sourceforge.net/projects/alcinoe/ он работает с гигабайтом данных в SAX, но я не знаю, будет ли он работать под d2009 … «Брэдли Макдональд» написал в сообщении новости: [email protected] ….
Как читать очень большой файл ??
— = — MB7JZHvtf6KfyoBHXwdT
Тип содержимого: текст / простой
Кодирование передачи содержимого: 7 бит Привет, ребята, У меня очень большой файл.Он может содержать 1lac-строки .. также он
длина увеличивается динамически ..
Каждый раз (каждые 5 минут) мне нужно прочитать содержимое файла и сделать что-нибудь
работа .. Предположим, я прочитал строки в течение первых 5 минут, а затем после некоторого
время он также читает ту же строку, поэтому это занимает больше времени, и это
пустая трата времени.. Код следующий, открыть FF, «/ tmp |» || die «не могу получить доступ к файлу журнала \ n»;
пока (
Чтение больших файлов
Мне нужно прочитать файлы размером от 500 КБ до 1 мегабайта. Файл содержит записи 218 байт
длинный
в фиксированном формате. Мне нужно разобрать и переформатировать файл в 80-байтовые записи.
Здесь
быстрый и эффективный способ обработки такого большого файла? TIA
отметка
Вы пробовали драйвер Text ODBC, поставляемый с PB? Рой Марк Р. Зигман написал в сообщении …
> Мне нужно читать файлы размером от 500к до 1мег.Файл содержит записи 218
байты
> долго
> в фиксированном формате. Мне нужно разобрать и переформатировать файл в 80 байт
записи.
> Есть
> быстрый и эффективный способ обработки такого большого …
Чтение большого ini файла
Здравствуйте, Мне нужно прочитать ini-файл размером более 32 КБ.
Как я могу это сделать?
Когда я пробую это с помощью TIniFile, текст не завершен. Спасибо,
Бернарт Доминик —
В понедельник, 11 января 2010 г., 05:18:06 -0800, Доминик Бернарт <Доминик[email protected]> написал: > Мне нужно прочитать ini-файл размером более 32 КБ.
> Как я могу это сделать?
> Когда я пытаюсь это сделать с помощью TIniFile, текст оказывается неполным. Попробуйте TMemIniFile. HTH
айн
Доминик Бернарт писал: > Здравствуйте,
>
> Мне нужно прочитать ini-файл размером более 32 КБ.
> Как я могу это сделать?
> Wh …
Чтение очень больших файлов XML ??
Всем привет! Мне нужно уметь читать и работать с очень большими XML
документы.Эти документы могут иметь размер более 1 ГБ. Раньше я использовал SAX XML для Delphi, что было очень приятно, но даже он
были проблемы с некоторыми более крупными документами. Я реализовал и попробовал код OmniXML — очень хороший кстати, но он
плохо читается и в больших документах. Это не может показаться
прочитать файл XML размером 900 МБ на машине размером 4 ГБ. Итак — мне интересно, как другие справятся с этой проблемой? Какие
другие пакеты доступны? Составные части? Мне нравится OMNI для wr…
Чтение больших файлов mbox
Я хочу написать утилиту для обработки сообщений электронной почты
хранится в формате mbox. Некоторые файлы mbox могут быть довольно большими, сотни
в мегабайтах или гигах. Очевидно, что чтение всего файла на
однажды невозможно. Самый очевидный метод — установить $ / в
regex / \ n \ nFrom / (сообщения в формате mbox разделяются пустой строкой
и начинайте со строки От) и для чтения сообщений электронной почты по одному.Мне кажется, это будет довольно медленно. Другая возможность, что
приходит в голову читать кусками 64 КБ или около того фрагментов данных, а затем
разделить эти чу …
Проблема с чтением большого файла
Привет, Я пытаюсь добавить хранимую процедуру (createp.sql) в базу данных с помощью команды: ….. / bin / dbisql -q -b -c «………» создает p.sql но процесс там надолго застрял. Однако, если я сломаю
создает файл p.sql во множество небольших файлов, и тогда он работает.(файл createdp.sql содержит около 400 хранимых процедур) Спасибо,
Стейси Ле Используйте команду READ, чтобы прочитать файл. Есть ограничение на буфер
и использование команды READ поможет обойти это.
—
Джим Иган [TeamSybase]
Хьюстон, Техас
Не могли бы вы мне помочь с синтаксисом?
Я попытался использовать команду READ в d …
Eof файла, чтение файла и запись файла! Проблема !
Привет всем, Я хочу сделать 2 вещи. У меня большой файл, и я хочу читать его построчно до последнего.и бок о бок я хочу записать его в новый файл с некоторыми изменениями Я не собираюсь работать в линейном режиме чтения! как я получу конец файла и как
я сделаю все это. подскажите сценарий. Я не уверен, что понимаю ваш вопрос. Из файла справки PowerBuilder в линейном режиме! FileRead () вернет 0
когда он достигает конца файла (EOF), поэтому код должен быть тривиальным? Этот
просто снята с манжеты, но я могу представить, что это что-то вроде li_Readfile = FileOpen (…
проблемы с памятью при чтении больших файлов
Всем привет. Мне нужно прочитать большую (150 МБ) строку текстового файла с помощью
линия. Кто-нибудь знает, как это сделать, чтобы мой процесс не набухал до
300 мегабайт?
Я не следил за списком, извините, если этот вопрос
недавно подошел. Ответа в архивах не нашел.
Спасибо,
Брайан
В четверг, 7 февраля 2002 г., Брайан Хейс написал: > Всем привет. Мне нужно прочитать большую (150 МБ) строку текстового файла с помощью
> линия.Кто-нибудь знает, как это сделать, чтобы мой процесс не набухал до
> 300 мегабайт? Пока вы не читаете этот файл в массив (который был бы
foo …
Проблема при чтении большого файла XML
Всем привет,
У меня есть XML-файл, и я хочу преобразовать его в набор данных.
Я использую dataset.ReadXML (filename) .. но он выдает исключение system.outOfMemoryException ..
так как я могу выйти из этой проблемы ???
Спасибо …
Для файлов bix XML попробуйте прочитать файл с помощью XMLdatareader, который предназначен только для чтения.Средство чтения данных XML будет читать по одной строке за раз, и henc не даст вам проблемы с исключением нехватки памяти Викрам www.vikramlakhotia.com Пожалуйста, отметьте ответ, если это помогло вам Привет
Я хочу прочитать XML-файл и преобразовать его в dataset.coz. Я собираюсь использовать набор данных после этого ….
Чтение текстового файла в Delphi 2009
Привет, я недавно загрузил бесплатную 30-дневную пробную версию delphi 2009 для своего вычисление уровня AS. В настоящее время я использую программу для написания простых приложений coonsole.У меня проблемы с определенной командой Reset. Это код, который я ввел, и ошибка возникает при достижении сброса. В моей школе есть Delphi 7, я использовал его на 7, и он работает, но когда я пытаюсь запустить его в 2009 году, появляется сообщение об ошибке и предупреждение; [Предупреждение DCC] txtfilerandom.dpr (20): W1019 Для переменной управления контуром должна быть простая локальная переменная
[Ошибка DCC] txtfilerandom.dpr (28): E2070 Unknow …
Чтение файла и запись на iOS с использованием Delphi
Есть ли у кого-нибудь пример кода, который показывает, как читать и записывать файлы на устройстве iOS в Delphi? Или любую другую информацию по этой теме? Чем отличается ввод-вывод файлов в iOS на симуляторе и на самом устройстве iOS? Спасибо!
Почти то же самое в windows, но скорость чтения / записи намного меньше 🙂 {код}
//
// Встроенная графическая оболочка iOS для Delphi
//
unit iOS_Files; интерфейс {$ mode delphi}
{$ Modewitch objectivec1} использует
SysUtils, Типы, Классы, Варианты, Математика,
UITypes,
CFBase, CFURL,
CGContext, CGGeometry, CGColorSpace,
iPhoneВсе,
NSHelpers, // Автор: П…
Чтение большого текстового файла построчно
Привет, Я знаком с чтением текстового файла, используя: {код}
AssignFile () / ReadLn ()
а также
TStringList.LoadFromFile
{код} но вышеперечисленное недостаточно хорошо в моей текущей ситуации. Мне нужно открыть и захватить определенную строку (строки) в файле, выполнив поиск по 1) индексу ИЛИ 2) ключевому слову. Я пытался понять, как читать содержимое с помощью TFileStream. TStringList.LoadFromFile не работает для меня, потому что файл довольно большой.При использовании я получаю сообщение об ошибке «Недостаточно памяти». AssignFile () / ReadLn () работает слишком медленно, учитывая способ, которым я собираю данные. Иногда хожу …
Чтение файлов с файлового сервера
Привет всем мне нужно
помогите читать данные из файлов. Я храню файлы в файле
система и не может прочитать файл из файловой системы. Я хожу
doc и PDF-файлы в моей файловой системе. Может ли кто-нибудь помочь мне в
чтение файлов обратно из файловой системы … Вот мой код Если (uploadPDF.HasFile = False или uploadWord.HasFile = False) Тогда ‘Файл не загружен! & Nbs …
Delphi XE: Чтение базовой информации из DCP-файла
В этой статье я покажу, как читать некоторую базовую информацию из файлов DCP Delphi. Это включает в себя имя BPL для связи, необходимые DCP и содержащиеся модули. В течение последних последних недель я написал Project-Analyzationtool, который может полностью отключить все зависимости модулей и исправить пути поиска.Однако для этого мне пришлось работать и с DCP. Некоторый поиск не дал многого (кроме тех же вопросов, что и у меня). Я знаю, что все могло измениться с XE на XE8, но я надеюсь, что эта статья по-прежнему будет полезна для кого-нибудь, кто не работает в XE.
Итак, приступим к нашей грязной работе. Для анализа DCP я создал новый пакет под названием TestPackage.bpl. Он требует только RTL и имеет 2 пустых блока: MyUnit и Foo.OtherUnit. Это должно сделать работу для экспериментов. Возьмите любой Hex-редактор и изучите его.Вы увидите что-то вроде этого:
Вы можете заметить, что поток начинается с 4 символов AnsiChars «PKX0». Кажется, что все DCP начинаются с него, поэтому я объявил его нашей подписью DCP. Вы можете проверить это при загрузке файла, чтобы убедиться, что у вас есть DCP. В строке 3 вы увидите TestPackage.bpl. Это имя BPL, на который будет ссылаться компоновщик. Это необходимо при работе с BPL, которые имеют Postfixes. Например, для VCL150.bpl существует только файл VCL.dcp. И это то место, где вы найдете окончательное имя BPL.Сравнивая разные DCP, вы заметите, что имя BPL всегда начинается с одной и той же позиции (байт 33). Итак, наши первые 32 байта наверняка являются своего рода заголовком. Давайте внимательно посмотрим:
Я обозначил области, которые я уже проанализировал, и опишу их здесь. Красное поле — это наша подпись, как уже говорилось ранее. Зеленый и синий содержат числа, которые меняются в зависимости от количества содержащихся модулей и требуемых DCP. Повернувшись, вы заметите, что зеленый — это количество требуемых DCP, а синий — количество содержащихся единиц.Подождите, у нас есть единицы, почему он говорит мне, что их 3? Очень просто, DPK-файл вашего пакета (в данном случае TestPackage.dpk) тоже включен в этот список. Оранжевое поле просто содержит длину в байтах имени BPL, которое следует за заголовком (исключая завершающий символ NULL). Подводя итог, наш заголовок в Delphi выглядит так:
Но подождите, это еще не все!
Сразу после нашего BPL-Name мы заметим «RTL». Это связано с тем, что за ним непосредственно следует список строк с нулевым завершением, которые включают имена требуемых DCP.В нашем случае это просто «RTL». Итак, чтобы получить список необходимых DCP, вы просто читаете строку с нулевым завершением после строки с нулевым завершением в зависимости от количества требуемых DCP, как указано в нашем заголовке. После этого следует список содержащихся модулей с собственным заголовком. Подводя итог, можно сказать, что каждый элемент этого списка содержит 60-байтовый BLOB-объект, который я еще не исследовал. И 2 строки с нулевым завершением после каждого блока. Первая строка — это наше Unit-Name, вторая — это своего рода NameSpace. Если ваш блок не разделен точками, вторая строка всегда пуста и состоит только из NULL-символа.Но когда ваш модуль разделен точками, как «Foo.OtherUnit», он будет содержать «Foo». Этот шаблон продолжается с такими модулями, как «Foo.Bar.MyUnit», где NameSpace — «Foo.Bar». Я выделил эти поля зеленым / коричневым и синим / оранжевым. Итак, чтобы получить здесь список содержащихся единиц, вы просто пропустите 60 байтов и прочитаете 2 строки на элемент в зависимости от количества содержащихся единиц в нашем заголовке. Последним элементом всегда является блок Package-DPK. Итак, если вы все сделали правильно, вы можете получить такой результат:
Здесь есть на что обратить внимание: последняя запись, которая является DPK-Entry, кажется, имеет заголовок длиной 61.Я просто зациклил здесь образец из 60 байтов, поэтому у меня здесь есть дополнительный символ перед фамилией. Вы можете пропустить это.
Я надеюсь, что эта статья поможет вам начать работу с DCP-файлом Delphi.
Строка чтения текстового файла Delphi. Запись и чтение в / из текстового файла
Брезент для кемпинга Stealth
Delphi Basics. Стандартные компоненты. Delphi предоставляет ряд различных механизмов доступа к файлам. Самый старый из них поддерживает консоли, в которых процедуры Read, ReadLn, Write и WriteLn имеют синтаксис, в котором не указано имя файла.Без имени файла ввод и вывод ввода-вывода направляются на консоль. Следующая информация может быть полезна для получения степени онлайн-университета или для лучшего понимания Delphi.
Для современных приложений большее значение имеют операции с файлами на диске. В Delphi есть два основных набора процедур для работы с файлами. В этой статье и на этом веб-сайте описаны наиболее распространенные на Delphi. Другой тип — это тонкие оболочки для API Windows, которые зависят от платформы. Они также менее интуитивно поддерживают текстовые файлы.Здесь они не рассматриваются. Вдобавок, спрятанный, Delphi предоставляет очень элегантный способ чтения и записи полных текстовых файлов.
Класс TStringList имеет методы для загрузки списка строк из текстового файла. И для сохранения списка аналогично. См. Последний раздел этой статьи. Существует ряд основных операций для работы с текстовыми и двоичными файлами. Последний может содержать несимвольные значения данных.
Безопасна ли гранитовая посудаВо-первых, мы должны получить. Здесь мы получаем дескриптор текстового файла, обозначенного двоичными файлами типа TextFile с типом File.Мы просим Delphi назначить дескриптор файла для файла с именем Test. Затем мы должны открыть файл, используя этот дескриптор. Эта операция сообщает Delphi, как мы хотим обращаться с файлом. Есть 3 способа открыть файл: .Чтение строк из текстового файла очень похоже, но на всякий случай потребуется дополнительный шаг.
Перед попыткой чтения вы должны проверить, существует ли файл. Вам также понадобится дополнительная переменная для получения строк, которые вы читаете из файла. Это шаги :. Используйте команду AssignFile, чтобы подключить переменную TextFile к физическому файлу на диске.
Это означает, что на диске будет создан новый текстовый файл. Если файл с таким именем уже существует, он будет перезаписан.
Подпишитесь на RSS
Запишите строку в файл с помощью WriteLn. Вы можете повторять этот шаг сколько угодно раз. Наконец, «закройте» текстовый файл с помощью CloseFile. Текст; WriteLn F, Edit2. Вот шаги: Объявите две переменные: одну типа TextFile и одну типа String.
Если файл существует, перейдите к шагу 3.Если нет, то здесь все заканчивается. При желании вы можете показать пользователю сообщение об ошибке. Используйте AssignFile для подключения переменной TextFile к физическому файлу.
Считайте строку из файла в строковую переменную с помощью команды ReadLn. Повторите этот шаг, чтобы прочитать следующую строку файла. Исходный код Delphi. Для сохранения одной или нескольких строк в текстовый файл необходимо выполнить следующие действия: Объявить переменную типа TextFile.Util в System. Поскольку TBufferedFileStream происходит от TFileStream, это простая замена, позволяющая добавить его в ваши приложения и получить преимущества в скорости, которые он приносит.
Чтобы увидеть разницу в скорости, запустим тест! Дополнительно к использованию добавлен System. Записать файл для проверки методов чтения довольно просто. WriteLn в приведенном выше коде добавляет текст и добавляет символ 13 в конец каждой строки. Это действительно грубый тест, который очень сильно влияет на операцию чтения. Теперь я знаю, что приведенный выше код может быть простым для анализа, но не очень эффективным.
Потоковая передача предназначена для локального хранения и чтения данных, а не по сети.Буферизованный — хорошее объявление! Что касается примера, если эта проблема будет решена, очень простое исправление — чтение текстовых строк из любого потока будет намного быстрее:
Запись и чтение в / из текстового файла
Ваш адрес электронной почты не будет опубликован. Сохраните мое имя, адрес электронной почты и веб-сайт в этом браузере, чтобы в следующий раз я оставил комментарий. Подробнее на примере кода. Создать ‘test. Нанизывать ; наконец sw. Бесплатно; конец ; Памятка1. Добавить «Файл записан»; конец ; WriteLn в приведенном выше коде добавляет текст и добавляет символ 13 в конец каждой строки.Нанизывать ; наконец fStr. Бесплатно; конец ; sw.
Стоп; Памятка1. Я буду использовать это совсем немного. Спасибо за урок. Оставить комментарий Отменить ответ Ваш электронный адрес не будет опубликован. Этот веб-сайт использует файлы cookie для улучшения вашего опыта. Мы предполагаем, что вы согласны с этим, но вы можете отказаться, если хотите. Принять Подробнее. Необходимо всегда включено. Мы можем рассматривать работу с текстовым файлом в Delphi как аналогию воспроизведения или записи информации на кассету видеомагнитофона.
Хотя можно вносить изменения в текстовый файл, перемещаться по нему при обработке информации или добавлять данные в файл, кроме как в конце, рекомендуется использовать текстовый файл только в том случае, если мы знаем, что работаем с обычным текстом. и в таких операциях нет необходимости.Чтобы начать работу с текстовыми файлами, вам необходимо связать файл на диске с файловой переменной в вашем коде — объявить переменную типа TextFile и использовать процедуру AssignFile, чтобы связать файл на диске с файловой переменной.
Если мы хотим прочитать содержимое файла в виде списка строк, всего одна строка кода выполнит эту работу. Чтобы прочитать информацию из файла построчно, мы должны открыть файл для ввода с помощью процедуры сброса. После сброса файла мы можем использовать ReadLn для чтения информации из файла, считывает одну строку текста из файла, а затем переходит к следующей строке:.После добавления одной строки текста из файла в заметку компонент SomeTxtFile необходимо закрыть.
Это делается с помощью ключевого слова Close. Мы также можем использовать процедуру чтения для чтения информации из файла. Read работает так же, как ReadLn, за исключением того, что не перемещает указатель на следующую строку. Используйте функцию EOF, чтобы убедиться, что вы не пытаетесь читать дальше конца файла. Допустим, мы хотим отображать содержимое файла в окнах сообщений — по одной строке за раз, пока мы не дойдем до конца файла :.Примечание. Лучше использовать цикл «Пока», чем цикл «Пока», чтобы учесть маловероятную возможность того, что файл существует, но не содержит никаких данных.
WriteLn, вероятно, является наиболее распространенным способом отправки отдельных фрагментов информации в файл. Следующий код будет считывать текст из компонента Memo1 построчно и отправлять его в какой-нибудь вновь созданный текстовый файл. В зависимости от состояния файла, предоставленного процедуре перезаписи, он создает новый файл, открывает файл для вывода с именем, присвоенным SomeTextFile.
Если файл с таким именем уже существует, он удаляется, а на его месте создается новый пустой файл. Если SomeTextFile уже открыт, он сначала закрывается, а затем создается заново.
Текущая позиция файла устанавливается в начало пустого файла. Иногда нам просто нужно добавить текстовые данные в конец существующего файла. Если это так, мы вызовем Append, чтобы гарантировать, что файл открывается с доступом только для записи с указателем файла, расположенным в конце файла.
Что-то вроде :. В общем, вы всегда должны использовать обработку исключений при работе с файлами. Все предыдущие примеры следует переписать следующим образом: Вот методы работы с типизированными и нетипизированными двоичными файлами. Поделитесь электронной почтой Flipboard. Зарко Гайич. Эксперт по информатике. Твиттер Твиттер. Обновлено 11 февраля, Примечание: Memo1.Любая помощь приветствуется.
Если он заблокирован другой программой, как его вообще можно открыть ?? Rgds, Мартин Лурк, разработчик Delphi. Откройте его с помощью AssignFile и циклически перенесите квалифицированные строки в список строк.После тестирования метод a нестабилен, поэтому, наконец, я выбираю способ b и продолжаю. Также вызывается Flush. Здесь ничего не делает. Примечание. В настоящее время я не могу посещать группы новостей каждый день, так что будьте терпеливы, если вы не получите ответ сразу. Разработчик Lurc Delphi.
Поскольку действие ReadLn выполняется десятки тысяч раз в сети, время все еще остается большим. Есть ли другой эффективный способ сделать это? Вы можете немного увеличить производительность, если текстовый файл будет использовать больший буфер. См. Процедуру SetTextBuf.Переменная Textfile не содержит непосредственно дескриптор файла, это запись, см. TextRec в интерактивной справке.
Другие темы 1.
033-Чтение / запись текстовых файлов в Delphi ** Арабский ** إنشاء وقراءة الملفات النصيةНайдите конкретную строку в текстовом файле и измените только часть этой строки. Прочтите текстовый файл построчно. Re: Прочитать текстовый файл построчно. Мартин Джейм. Re: Чтение текстового файла построчно. Как я уже сказал, поскольку исходный файл является файлом журнала и заблокирован его хостом, я использую следующие шаги, чтобы прочитать его содержимое.Re: Прочитать текстовый файл построчно Спасибо, Питер. Переключить навигацию codeverge. Чтение большого файла.
Я получу текстовые файлы из трех штук. В файле больше миллиона строк записей.
Никель sdsКаждая строка содержит строки, разделенные запятыми. Надеюсь, что у всех строк одинаковые номера. Но, учитывая размер, не думаю, что у меня есть выбор. Есть ли еще что-то, что я мог бы улучшить?
E93839 fxn1 материнская платаTIA Tom. См. Статьи, связанные с этим сообщением. В этой ситуации рассмотрите возможность использования вместо этого класса TStreamReader.Создать имя файла; попробуйте, пока не исходный файл.
ReadLn; поля. Бесплатно; конец; наконец поля. Если вы просто прочитаете файл один раз, вы можете придерживаться старой обработки «TextFile», если хотите. Простое использование 64 КБ значительно ускорит его. Функция ReadLn работает быстро, особенно если длина ваших строк меньше байтов. Если вы хотите иметь произвольный доступ к содержимому файла, вы можете прочитать файл через окно «карта памяти».
Это очень быстро и удобно, но при 32-битном процессе вы не сможете сопоставить файл размером 3 ГБ за один раз, вы можете сопоставить до МБ более или менее, из моего эксперимента, в зависимости от вашего текущего использования памяти.Так что вам придется использовать «окно», которое намеренно скользит по файлу. Я рад, что спросил. Должно быть, раньше я использовал настройки буфера, но совсем забыл об этом. Однако предложение Реми использовать TStreamReader кажется правильным решением.
С одним из моих файлов зацикливается. Lbuffer содержит символы. Этот цикл будет читаться вечно. Проблема в том, что буфер содержал — должно быть повреждение файла. С исходным файлом readln строка this не приводит к бесконечному циклу.API не должен возвращать количество байтов для символьной строки. Количество байтов никогда не должно быть меньше количества символов, хотя оно может быть больше.
Какая кодировка точно установлена в FEncoding? По крайней мере, вы должны иметь возможность использовать TEncoding.
Other Threads
Объект по умолчанию, даже если вывод соответствует неправильному символу Unicode. Они работают только с одиночными байтами. Кодировки никогда не ставил. Ты прав.
Итак, действительно, файл закодирован в ANSI.Основы Delphi. Прочтите процедуру. Чтение данных из двоичного или текстового файла.
Кровь на туалетной бумаге, но не в стулеСистемный блок. Процедура чтения считывает одну строку данных из файла или консоли. Для текстовых файлов каждая строка текста анализируется на заданные переменные.
Эти переменные могут быть текстового или числового типов. Для строк читается вся строка, если она не превышает емкость строковой переменной — передается только то количество текста, которое умещается. При синтаксическом анализе чисел пробелы и концы строк рассматриваются как значения разделителей.Если числовое значение превышает емкость переменной, оно приводится к переменной без возникновения исключения.
При чтении строк или символов, ReadLn должен выполняться, когда достигается конец Eoln строки.
Похоронная процессия ангелов адаВ противном случае последующие вызовы чтения повторно возвращают нулевое значение. Для двоичных файлов значения данных Value1, Value2 и т. Д. Считываются из данных файла. Если файл, заданный FileHandle, является типизированным файлом, который определен как содержащий определенные записи, то эти значения должны относиться к записи того же типа.Вы не можете использовать Read для чтения из нетипизированного двоичного файла, объявленного как File без следующего типа. Чтобы читать из нетипизированного двоичного файла, используйте BlockRead.
Чтение не использует буферизацию — BlockRead более эффективен. Чтение также является директивой Delphi. Он используется с ключевым словом Property. Загрузите этот веб-сайт как программу для Windows. Показать полный код объекта.
Free Pascal — General — чтение строк в переменную UnicodeString из текстового файла с кодировкой UCS2 (UTF-16)
В 2019-09-06 07:24 LacaK написал:> От пользователя POV мы имеем такую ситуацию:
> — с одной стороны находится входной текстовый файл в кодировке UTF-16 (LE или BE)
> — с другой стороны есть FPC, где RTL-процедуры вроде AssignFile,
> Доступны SetTextCodePage, Reset, Read (Ln), Write (Ln).
>
> Моим первоначальным намерением было просто использовать вызов существующей процедуры
> SetTextCodePage с параметром CP_UTF16, который, на мой взгляд, будет
> просто сигнализируйте RTL, что текстовый файл ввода / вывода должен / должен быть закодирован
> с использованием UTF16.
Да, я считаю, что расширение SetTextCodePage с поддержкой UTF-16
имеет смысл (с некоторыми оговорками, подобными тому, что он должен быть
выполняется перед перезаписью в случае создания новых файлов, или иначе
Метка спецификации не будет добавлена в начало файла).Другой
Вопрос
в том, что должно произойти в записи текстового файла — поскольку
, упомянутый в другом моем сообщении, я бы предпочел добавить новое поле с указанием
Размер кодовой точки
вместо необходимости проверять конкретные значения кодовой страницы
во всех ветвях кода, которые необходимо создать для обработки
разница.
Более того, открытие файла несколько сложнее, потому что
Кодировка файла
может быть указана в самом файле. Мы бы
добавить код для чтения первых байтов каждый раз, когда Reset вызывается для
текстовый файл, не связанный с другим устройством (консолью), и установите
полей в записи текстового файла (возможно, переопределение явной настройки
из SetTextCodePage)? Лично я бы так и поступил, но у других может быть
другое мнение.
> Затем любой последующий вызов ReadLn с любой целевой переменной
> (ansistring, unicodestring, integer и т. Д.) Просто что-то сделает
> нравится:
> — прочитать из файла последовательность байтов, которая будет интерпретироваться как UTF-16, поэтому
> у нас будет на входе UnicodeString
Просто комментарий — если уже добавили эту поддержку, мы должны ИМХО разрешить
UTF-32 тоже.
> — эта UnicodeString будет далее транслитерирована в запрошенную
> переменная назначения (как в неявных преобразованиях FPC между
> UnicodeString и AnsiString с этим не будет проблем)
Да.
> (для записи (Ln) то же самое произойдет только в обратном порядке: исходная переменная
> -> UnicodeString -> Запись в файл)
>
> Если SetTextCodePage (CP_UTF16) не подходит, мы должны IMO
> представить любую новую процедуру, которая будет давать пользователю сигнал о возможности
> что «У меня есть текстовый файл в кодировке UTF-16» или «Я хочу, чтобы все записывались в
> мой текстовый файл должен быть закодирован UTF-16 «.
> (но лично я не вижу смысла вводить новую процедуру как
> SetTetCodePage мне идеально подходит)
См. Выше — новая процедура может не понадобиться, но я бы предпочел новый текст
Поле записи файла
в фоновом режиме для повышения эффективности и
ремонтопригодность.
> Итак, во-первых, нам нужен дизайн / предложение, которое / будет принято.
> (вероятно, здесь необходимы более глубокие знания внутреннего устройства RTL, так что это
> причина, по которой должны вмешаться и другие основные разработчики)
Правый.