Томский государственный университет систем управления и радиоэлектроники
Опубликован: 01.11.2012 | Доступ: свободный | Студентов: 651 / 76 | Длительность: 06:01:00
Лекция 5:

Файлы

< Лекция 4 || Лекция 5: 123 || Лекция 6 >

Файловый ввод/вывод

Оператор 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

Пример:

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

Пример:

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 = 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
< Лекция 4 || Лекция 5: 123 || Лекция 6 >