Uploaded by cesapec513

5F ФАЙЛЫ A

advertisement
Лекция 5
ФАЙЛЫ
Назначение файлов
Исходные данные
Промежуточные вычисления
Результаты вычислений
Конвертация данных
Обмен данными с другими программами
Внешние и внутренние файлы
Внешний файл –
именованная область на внешнем носителе.
C:\docum.inf
D:\DATA\results.txt
E:\geometry.dat
Внутренний файл –
символьная строка или массив.
character(100) buffer
characrer(1000) temp(10)
Файловые записи
Запись – единица обмена данными
между программой и внешней памятью.
Расположены в файле последовательно.
Форматные записи
внутреннее  внешнее представление
Неформатные записи
внутренне представление
Запись конец файла
последняя запись в файле.
Форматные файлы
Содержат форматные записи.
Каждая запись оканчивается управляющими
символами (возврат каретки, перевод строки).
Возможность "ручного" редактирования.
Скорость обработки файлов низкая.
Больший объём файлов.
Внешние и внутренние файлы.
Неформатные файлы
Содержат неформатные записи.
Отсутствует возможность "ручного" редактирования.
Скорость обработки файлов высокая.
Меньший объём файлов.
Внешние файлы.
Двоичные файлы
Содержат данные в двоичном представлении.
Длина записи равна 1 байту.
Отсутствует возможность "ручного" редактирования.
Эффективны для хранения больших объёмов данных
(хранение промежуточных вычислений).
Внешние файлы.
Последовательный доступ
запись
запись запись
запись
файловый
указатель
Доступ к данным по порядку
Записи переменной длины
Добавление новой записи – в конец файла
Прямой доступ
запись запись запись запись запись запись
файловый
указатель
Доступ к данным произвольный
Записи одинаковой длины
Внешний файл
может быть прямого и последовательного доступа
Внутренний файл
только последовательного доступа
Оператор Open
open (unit =
file =
err
=
iostat=
...)
u
name
label
i-var
,
,
,
,
&
&
&
&
Создает устройство ввода/вывода с номером u и
подсоединяет к нему внешний файл name.
open (unit = 1, file = "data.txt")
open (unit = 2, file = "D:\DOCUM\price.inf")
Параметры оператора Open
uint - номер устройства
file – имя файла
err
- метка на оператор обработки ошибки
iostat – номер ошибки (0 – отсутствие).
... – один или несколько спецификаторов (  40 )
Параметры оператора Open
СПЕЦИФИКАТОРЫ
ACCESS
ACTION
ASSOCIATEVARIABLE
ASYNCHRONOUS
BLANK
BLOCKSIZE
BUFFERCOUNT
BUFFERED
CARRIAGECONTROL
CONVERT
DECIMAL
DEFAULTFILE
DELIM
DISPOSE
ENCODING
FORM
IOFOCUS
MAXREC
MODE
NAME
NEWUNIT
NOSHARED
ORGANIZATION
PAD
POSITION
READONLY
RECL
RECORDSIZE
RECORDTYPE
ROUND
SHARE
SHARED
SIGN
STATUS
TITLE
TYPE
USEROPEN
Примеры оператора Open
! двоичный файл
open(1,file = "backup.bin",form = 'binary')
! добавление записей в конец файла
open(2,file = "history.txt",access = 'append')
! только для чтения
open(3,file = "data.txt", action = 'read')
! файл должен существовать
open(4,file = "geometry.dat", status = 'old')
! асинхронный ввод/вывод
open(5,file = "tornado.dat", asynchronous = 'yes')
! файл доступен другим приложениям
open(6,file = "base.dat", share = 'denynone')
! файл недоступен другим приложениям
open(7,file = "base2.dat", share = 'denyrw')
Файловый ввод/вывод
Оператор read – чтение данных из файла
Последовательный доступ
форматные
read(unit, format, ...)
неформатные
read(unit, ...)
Прямой доступ
форматные
read(unit, format, rec, ...)
неформатные
read(unit, rec, ...)
Внутренние файлы
read(unit, format, ...)
Ввод/вывод в файлы
Оператор write – запись данных в файл
Последовательный доступ
форматные
write(unit, format, ...)
неформатные
write(unit, ...)
Прямой доступ
форматные
write(unit, format, rec, ...)
неформатные
write(unit, rec, ...)
Внутренние файлы
write(unit, format, ...)
ПРИМЕРЫ
! ЗАПИСЬ ДАННЫХ ВО ВНТУРЕННИЙ ФАЙЛ
program buffer
character(20) buf
integer(4) a,b,c,d
!----- читаем формулу в символьную строку
write(*,"(A,\)") "Enter expression......."
read(*,"(A)") buf ! во внутренний файл
!-------- заменяем все плюсы на пробелы
do k = 1,len(buf)
if (buf(k:k) == '+') buf(k:k) = ' '
end do
read(buf,*) a,b,c,d
write(*,*) a+b+c+d
end
ПРИМЕРЫ
! ЗАПИСЬ ДАННЫХ ВО ВНЕШНИЙ ФАЙЛ ПОСЛЕДОВАТЕЛЬНОГО ДОСТУПА
program buffer
character(20) buf
integer(4) a,b,c,d
!----- читаем формулу в символьную строку
write(*,"(A,\)") "Enter expression......."
read(*,"(A)") buf ! во внутренний файл
!-------- заменяем все плюсы на пробелы
do k = 1,len(buf)
if (buf(k:k) == '+') buf(k:k) = ' '
end do
read(buf,*) a,b,c,d
write(*,*) a+b+c+d
end
ПРИМЕРЫ
! ЗАПИСЬ ДАННЫХ ВО ВНЕШНИЙ ФАЙЛ ПРЯМОГО ДОСТУПА
program random_file
real x
integer :: k = 0
open (1, file = "C:\numbers.txt", access = 'direct', &
recl = 10, form = 'formatted')
do
call random_number(x)
k = k+1
x = x-0.78
write(1,"(f10.4)", rec = k) x
if (abs(x)<0.0001) exit
end do
write(1,"(i10)", rec = 1) k
close(1)
end
Данные записанные в файл
4644
-0.7545
-0.4275
-0.1131
0.1831
0.0583...
Оператор Backspace
Перемещает файловый указатель
на одну запись назад в файлах последовательного
доступа.
backspace (unit = u
, &
err
= label , &
iostat = i-var)
backspace(1)
backspace(2, err = 200)
backspace(3, err = 200, iostat = ios)
Оператор Rewind
Перемещает файловый указатель
в начало первой записи.
rewind (unit = u
, &
err
= label , &
iostat = i-var)
rewind(1)
rewind(2, err = 200)
rewind(3, err = 200, iostat = ios)
Функция EOF
Возвращает .TRUE. если файловый указатель
установлен на запись "конец файла".
В противном случае результат .FALSE.
Часто используется для чтения
всех данных из файла
do while ( .NOT.eof(1) )
read(1,*) param
...
end do
Функция EOF
program read_file
real(4), allocatable :: A(:)
real(4) AT
integer(8) :: k = 0
open(1,file = "C:\data.txt")
do while (.NOT.EOF(1)) ! подсчёт элементов массива
read(1,*) AT
k = k+1
end do
allocate(A(k)) ! размещение массива
rewind(1)
k = 1
do while (.NOT.EOF(1)) ! чтение элементов массива
read(1,*) A(k)
k = k+1
end do
end
Оператор Inquire
Возвращает свойства устройства, файла или папки.
INQUIRE (FILE=name, ERR=label, ID=idvar,
&
IOMSG=msgvar, SIZE=sz, IOSTAT=ivar, &
DEFAULTFILE=def, slist)
INQUIRE (UNIT=iounit, ERR=label, ID=idvar,
IOMSG=msgvar, SIZE=sz,
IOSTAT=ivar, slist)
&
&
INQUIRE (DIRECTORY=dir, EXIST=ex,
DIRSPEC=dirspec, ERR=label,
ID=idvar, IOMSG=msgvar,
SIZE=sz, IOSTAT=ivar)
&
&
&
INQUIRE (IOLENGTH=len) out_item_list
Оператор Inquire
program inquire_list ! ***** Вычисление размера списка вывода
real(8) A(100)
complex(16) S(20)
integer ioL
inquire(iolength = ioL) A,S,B
! размер списка вывода = 361
end
program if_exist ! ***** Проверка существования файла
character(100) fname
logical exists
write (*, *) 'Enter the file name: '
read (*, '(a)') fname
inquire (file = fname, exist = exists)
if (.not. exists) write (*,'(2a/)') 'Cannot find ', fname
end
Оператор Close
Отсоединяет файл от устройства ввода/вывода и
закрывает это устройство
close (unit
err
iostat
status
=
=
=
=
u
, &
label , &
ivar , &
stat)
status – символьное выражение принимающее
значения: keep или delete
program delete_file ! ***** Удаление файла
open(1,file = "C:\data.txt")
read(1,*) a,b,c
close(1,status = 'delete')
end
Асинхронный ввод/вывод
Параллельное выполнение файлового ввода/вывода
и других операторов программы.
Спецификатор asynchronous='yes' в операторах
open, write, read.
open (1, asynchronous = 'YES')
! синхронный вывод
write(1,*, asynchronous = 'NO') A, B, C
! асинхронный вывод
write(1,*, asynchronous = 'YES') D, E, F
Асинхронный ввод/вывод
Переменные участвующие в асинхронном
вводе/выводе получают атрибут asynchronous.
Явное задание атрибута при объявлении.
real, asynchronous :: MS, NV
complex, asynchronous :: TN(100,100)
Оператор wait
ожидает окончание асинхронной
работы с файлом.
Асинхронный ввод/вывод
Неаккуратное использование асинхронной работы с
файлом может приводить к гонкам данных.
program asyn_data_races
real(4) :: A(100,100) = 1.0
open(1,file = "C:\AS.txt", asynchronous = 'YES')
do k = 1,10
rewind(1)
write (1,*,asynchronous = 'YES') A
A = real(k)
end do
close(1)
end
Массив А
записывается в файл
и одновременно
изменяется !
Асинхронный ввод/вывод
Содержимое файла C:\AS.txt
содержит разные данные !
...
9.000000
9.000000
9.000000
9.000000
9.000000
10.00000
10.00000
10.00000
10.00000
10.00000
...
9.000000
9.000000
9.000000
9.000000
9.000000
10.00000
10.00000
10.00000
10.00000
10.00000
9.000000
9.000000
9.000000
9.000000
9.000000
10.00000
10.00000
10.00000
10.00000
10.00000
9.000000
9.000000
9.000000
9.000000
10.00000
10.00000
10.00000
10.00000
10.00000
10.00000
Асинхронный ввод/вывод
Анализ программы asyn_data_races
с помощью Intel Inspector XE 2011
указывает на гонки данных в программе.
Асинхронный ввод/вывод
Используем оператор wait, чтобы дождаться
завершения записи данных в файл.
program asyn_data_races
real(4) :: A(100,100) = 1.0
open(1,file = "C:\AS.txt", asynchronous = 'YES')
do k = 1,10
rewind(1)
write (1,*,asynchronous = 'YES') A
wait(1) ! дожидаемся, когда завершится поток,
! отвечающий за запись данных в файл
A = real(k)
end do
close(1)
end
Оператор Flush
Сброс логических буферов
при буферизованном выводе
program prog
integer, parameter :: N = 100
real A(N)
open(1, buffered = 'yes', file = 'dat')
write(1, *) A
flush(1)
call C_subroutine('dat') ! читает данные из файла dat
! ----- некоторый код
end
При буферизации, логически записанные данные могут
физически не успеть попасть на диск,
что вызовет ошибку чтения данных.
Процедуры модуля ifport
ACCESS
CHANGEDIRQQ
CHANGEDRIVEQQ
CHDIR
CHMOD
DELDIRQQ
DELFILESQQ
FINDFILEQQ
FULLPATHQQ
GETDRIVEDIRQQ
GETDRIVESIZEQQ
Определение доступа к файлу
Установка директории текущей
Установка диска текущим
Смена рабочей директории
Смена атрибутов файла
Удаление директории
Удаление файлов
Поиск файлов
Полное имя файла или директории
Путь текущей рабочей директории
Размер текущего диска и
доступного пространства
Процедуры модуля ifport
GETDRIVESQQ
GETFILEINFOQQ
PACKTIMEQQ
Имена имеющихся дисков
Информация о файле
Упаковывает время для
использования в SETFILETIMEQQ.
RENAMEFILEQQ
Переименование файла
SETFILEACCESSQQ Способ доступа к файлу
SETFILETIMEQQ Установка даты изменения файла
SPLITPATHQQ
Выделяет в полном имени
UNPACKTIMEQQ
4 компоненты файла
(диск, папки, имя, расширение)
Распаковка упакованного времени
*Задание*
Промежуточное сохранение вычислений.
В программе save_results организовать
промежуточное автосохранение
массива A через каждые auto итераций
в файл numerical.save.
Предусмотреть:
1) возможность продолжения вычислений при
повторном запуске программы;
2) обработку ошибок;
*Задание*
program SAVE_DATA
use ifport
implicit none
integer, parameter :: M = 150
real(16) A(M,M,M), B(M,M,M), C(M,M,M)
integer, parameter :: N = 1000 ! кол-во итераций
integer i,j,k,it
do it = 1,N
write(*,*) "Current iteration = ",it
call random_number(A)
call random_number(B)
call random_number(C)
do i = 1,M
do j = 1,M
do k = 1,M
A(i,j,k) = exp(B(k,j,i))*cos(C(j,k,i)**A(i,k,j))
end do
end do
end do
end do
END
* Вариант программы *
program save_data
use ifport
implicit none
integer, parameter :: M=150
real(16) A(M,M,M), B(M,M,M), C(M,M,M)
integer, parameter :: N = 1000 ! кол-во итераций
character(20) ::
name = 'C:\numerical.save', & ! файл автосохранения
tmpname = 'C:\numerical.tmp'
! файл временной копии
integer, parameter :: auto = 10 ! интервал автосохранения
integer i,j,k,it, itstart, ires
logical ex, ext
inquire(file=name,
exist = ex)
inquire(file=tmpname, exist = ext)
if (.NOT. ex) then ! если нет файла автосохранения
if (.NOT. ext) then ! если нет временной копии
write(*,*) "No data saved. Starting at iteration = 1" ! 1) тогда новый расчет
itstart=1
else
open(1,file=tmpname, status='OLD', form='binary') ! 2) иначе данные могут быть во временой копии
read(1, ERR=100, END=101) itstart, A
write(*,*) "Data was saved at iteration = ", itstart
close(1)
end if
else
write(*,*) "Reading saved data from file....." ! 3) данные могут быть в файле автосохранения
open(1,file=name, status='OLD', form='binary')
read(1, ERR=100, END=101) itstart, A
close(1)
if (ext) then ! 4) если есть файл и временная копия
write(*,*) "Finding more than one copy. Deleted..."
ires=DelFilesQQ(tmpname)
end if
end if
* Вариант программы *
do it=itstart,N
write(*,*) "Current iteration = ",it
if (mod(it,auto)==0) then
! автосохранение промежуточных вычислений
open(2, file=tmpname, form='binary') ! сначала сохраняем во временный файл
write(2,ERR=102) it, A
close(2)
ires=DelFilesQQ(name) ! удаляем предыдущий файл автосохранения
ires=RenameFileQQ (tmpname, name) ! файлом автосохранения становится временная копия
write(*,*) "Data succesfully saved at iteration = ", it
end if
call random_number(A)
call random_number(B)
call random_number(C)
do i=1,M
do j=1,M
do k=1,M
A(i,j,k)=exp(B(k,j,i))*cos(C(j,k,i)**A(i,k,j))
end do
end do
end do
end do
stop
! ----- обработка ошибок -----100 stop "Error while reading data file !"
101 stop "End of data file encountered !"
102 stop "Error while writing data file !"
END
Download