Вы можете скачать презентацию к данной лекции здесь.
Исходные данные
Промежуточные вычисления
Результаты вычислений
Конвертация данных
Обмен данными с другими программами
Внешний файл - именновання область на внешнем носителе.
C:\docum.inf
D:\DATA\results.txt
E:\geometry.dat
Внутренний файл – символьная строка или массив.
character(100) buffer
characrer(1000) temp(10)
Запись – единица обмена данными между программой и внешней памятью.
Расположены в файле последовательно.
Форматные записи внутреннее → внешнее представление
Неформатные записи внутреннее представление
Запись конец файла последняя запись в файле.
Содержат форматные записи.
Каждая запись оканчивается управляющими символами (возврат каретки, перевод строки).
Возможность "ручного" редактирования.
Скорость обработки файлов низкая.
Больший объём файлов.
Внешние и внутренние файлы.
Содержат неформатные записи.
Отсутствует возможность "ручного" редактирования.
Скорость обработки файлов высокая.
Меньший объём файлов.
Внешние файлы.
Содержат данные в двоичном представлении.
Длина записи равна 1 байту.
Отсутствует возможность "ручного" редактирования.
Эффективны для хранения больших объёмов данных (хранение промежуточных вычислений).
Внешние файлы.
Доступ к данным по порядку
Записи переменной длины
Добавление новой записи - в конец файла
Доступ к данным произвольный
Записи одинаковой длины
Внешний файл может быть прямого и последовательного доступа
Внутренний файл только последовательного доступа
open (unit = u ,
file = name ,
err = label ,
iostat= i-var ,
...)
Создает устройство ввода/вывода с номером u и подсоединяет к нему внешний файл name.
open (unit = 1, file = "data.txt")
open (unit = 2, file = "D:\DOCUM\price.inf")
uint - номер устройства
file – имя файла
err - метка на оператор обработки ошибки
iostat – номер ошибки (0 – отсутствие).
... – один или несколько спецификаторов ( ≈ 40 )
| ACCESS | ENCODING | RECORDSIZE |
| ACTION | FORM | RECORDTYPE |
| ASSOCIATEVARIABLE | IOFOCUS | ROUND |
| ASYNCHRONOUS | MAXREC | SHARE |
| BLANK | MODE | SHARED |
| BLOCKSIZE | NAME | SIGN |
| BUFFERCOUNT | NEWUNIT | STATUS |
| BUFFERED | NOSHARED | TITLE |
| CARRIAGECONTROL | ORGANIZATION | TYPE |
| CONVERT | PAD | USEROPEN |
| DECIMAL | POSITION | |
| DEFAULTFILE | READONLY | |
| DELIM | RECL | |
| DISPOSE |
! двоичный файл 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 (unit = u ,
err = label ,
iostat = i-var)
backspace(1) backspace(2, err = 200) backspace(3, err = 200, iostat = ios)
Перемещает файловый указатель в начало первой записи.
rewind (unit = u ,
err = label ,
iostat = i-var)
rewind(1) rewind(2, err = 200) rewind(3, err = 200, iostat = ios)
Возвращает .TRUE. если файловый указатель установлен на запись "конец файла". В противном случае результат .FALSE.
Часто используется для чтения всех данных из файла
do while ( .NOT.eof(1) ) read(1,*) param ... end do
Пример:
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 (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
Пример:
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 (unit = u ,
err = label ,
iostat = ivar ,
status = 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 ожидает окончание асинхронной работы с файлом.
Неаккуратное использование асинхронной работы с файлом может приводить к гонкам данных.
Содержимое файла C:\AS.txt содержит разные данные !
... 9.000000 9.000000 9.000000 9.000000 9.000000 9.000000 9.000000 9.000000 9.000000 9.000000 9.000000 9.000000 9.000000 9.000000 9.000000 9.000000 9.000000 9.000000 9.000000 10.00000 10.00000 10.00000 10.00000 10.00000 10.00000 10.00000 10.00000 10.00000 10.00000 10.00000 10.00000 10.00000 10.00000 10.00000 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
Сброс логических буферов при буферизованном выводе
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
При буферизации, логически записанные данные могут физически не успеть попасть на диск, что вызовет ошибку чтения данных.
| ACCESS | Определение доступа к файлу |
| CHANGEDIRQQ | Установка директории текущей |
| CHANGEDRIVEQQ | Установка диска текущим |
| CHDIR | Смена рабочей директории |
| CHMOD | Смена атрибутов файла |
| DELDIRQQ | Удаление директории |
| DELFILESQQ | Удаление файлов |
| FINDFILEQQ | Поиск файлов |
| FULLPATHQQ | Полное имя файла или директории |
| GETDRIVEDIRQQ | Путь текущей рабочей директории |
| GETDRIVESIZEQQ | Размер текущего диска и доступного пространства |
| GETDRIVESQQ | Имена имеющихся дисков |
| GETFILEINFOQQ | Информация о файле |
| PACKTIMEQQ | Упаковывает время для использования в SETFILETIMEQQ |
| RENAMEFILEQQ | Переименование файла |
| SETFILEACCESSQQ | Способ доступа к файлу |
| SETFILETIMEQQ | Установка даты изменения файла |
| SPLITPATHQQ | Выделяет в полном имени 4 компоненты файла (диск, папки, имя, расширение) |
| UNPACKTIMEQQ | Распаковка упакованного времени |
Промежуточное сохранение вычислений. В программе save_results организовать промежуточное автосохранение массива A через каждые auto итераций в файл numerical.save.
Предусмотреть:
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
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.