- •Операции над внешними файлами
- •Оператор Read
- •Оператор Write
- •Оператор Close
- •Файлы последовательного доступа Форматные файлы
- •Неформатные файлы
- •Файлы прямого доступа
- •Добавление записи в файл прямого доступа.
- •Удаление записи из файла прямого доступа
- •Создание информационно-справочной системы
- •Выбор метода доступа в файле и типа записи
Добавление записи в файл прямого доступа.
Добавление может быть выполнено просто, если мы знаем количество записей в файле прямого доступа. Для этого, используя инструкцию Find(num_f rec=num_r) установить указатель на новую запись, и записать требуемое значение Write (num_f, rec=num_r)<значение> или просто Write (num_f, rec=num_r) <значение>
Когда количество записей в файле неизвестно, можно предложить следующую последовательность действий: сначала прочитать и сосчитать все записи в файле, а затем дописать новую запись вслед за последней записью.
А можно для определения количества записей в файле прямого доступа использовать специальную функцию FSEEK( unit, offset, from), которая находится в библиотечном файле dfport. Чтобы воспользоваться этой функцией надо в свою программу подключить библиотеку: use dfport.
Функция имеет следующий синтаксис:
FSEEK( unit, offset, from)
Unit –номер устройства
Offset – отступ от текущего указателя
From – позиция куда установить : seek_set –начало seek_cur – текущая позиция seek_end – конец файла
Дальше воспользоваться оператором inquire (num_f, nextrec=nr), со спецификатором nextrec, где будет находиться номер последней записи в файле.
!функция, определяющая количество записей в файле прямого доступа
integer function NumLastRec( Num)
use dfport !подключение библиотеки
integer, intent(in):: num
integer nr, res
logical tf
inquire (num, opened=tf) !определяет открыт ли файл
If (.not. tf ) then
numlastrec=0
print*,'файл не подсоединен к устройству'
stop
endif
res=FSEEK( num, 0, Seek_end)
inquire (num, nextrec=nr) !возвращает ном. посл. зап.
numlastrec=nr
end
program main
!Добавление записи в файл прямого доступа
implicit none
integer nr, x, i
integer NumLastRec
open(10, file='out3.dat', form='unformatted', access='direct', recl=sizeof(x))
x=100
write(10, rec=4) x
write(10, rec=2)50
print*,'isx fil' !исходный файл
find(10, rec=1) !установка файла на начало
i=1
do while(.not. eof (10))
read(10, rec=i)x
print*,x
i=i+1
enddo
nr=NumLastRec(10)
print*, 'nr=', nr !вывод на экран номера последней записи в файле
nr=nr+1 ! формирование номера новой записи
write(10, rec=nr) 500 !запись нового значения 500 в конец файла
find(10, rec=1) !переход на начало файла
print*,'файл после добавления'
i=1
do while(.not.eof(10))
read(10,rec=i)x
print*,x
i=i+1
enddo
close(10)
end
Удаление записи из файла прямого доступа
Удаление записи из файла прямого доступа может быть выполнено с использованием оператора Delete.
Этот оператор используется для файлов прямого доступа. Удаляет запись с заданным номером. Оператор логически удаляет заданную запись из файла, помечая ее как удаленную (физически не удаляется: проставляется 0 на месте удаленной). При удалении записи, если не было ошибки, указатель автоматически устанавливается на следующую запись. Если номер записи не указан, то удаляется текущая запись.
Delete ([unit=]<номер устройства>,
[rec=<целочисленное выражение>]
[,err=<метка>]
[,iostat=<целочисленная переменная>])
Однако эти действия не приводят к физическому удалению записи в файле. Поэтому, для удаления какой-либо записи из файла, как и в файле последовательного доступа, используется вспомогательный (временный) файл.
Удаление записей из неформатного файла последовательного доступа.
Пример
В неформатном файле последовательного доступа хранятся вещественные числа. Удалить из файла все отрицательные числа.
subroutine create_sq(n)
implicit none
integer,intent(in)::n
integer i
real x
open (50, file='isxseq.txt', access= 'sequential', form='unformatted', status='new')
do i=1,n
print*,'bb cislo'
read *,x
write(50 )x
enddo
close(50)
end subroutine
subroutine view_sq()
implicit none
real x
open (10, file='isxseq.txt', form='unformatted', status='old')
print*,'fail sq'
do while (.not.eof (10))
read(10) x
print '(f3.0,2x\)', x
enddo
close(10)
!11 print*,'ochibka open'
end subroutine
subroutine del_f()
implicit none
real x
open (10, file='isxseq.txt', form='unformatted', status='old')
open (20, form='unformatted', status='scratch') !открываем врем. файл
do while (.not. eof (10)) !
read(10) x ! читаем из исходного файла
if (x>=0) write(20) x !записываем во вспомогательный
enddo
rewind(10) !переход на начало исходного файла
rewind(20) !переход на начало вспомогательного файла
do while (.not.eof (20))
read(20) x !читаем из вспомогательного
write(10)x !пишем в исходный
enddo
close(10)
close(20)
end subroutine
program main
implicit none
integer,parameter::n=10
call create_sq (n)
print*,'isx fil'
call view_sq()
call del_f()
print*,'posle delete'
call view_sq()
end
Удаление записей из неформатного файла прямого доступа.
Пример
В неформатном файле прямого доступа удалить все отрицательные числа.
Для решения задачи, как и в файле последовательного доступа, используем временный файл. Временный файл может быть выбран и прямого и последовательного доступа.
Процедура удаления с временным файлом прямого доступа.
subroutine del_zap ()
implicit none
integer i, k
real x
!исходный файл
open (30, file='f_dir.txt', access='direct', form='unformatted', recl=4)
!временный файл
open(10, access='direct', form='unformatted', recl=4, status='scratch')
i=0 !номер записи исходного файла
k=0 !номер записи временного файла
do while (.not.eof (30))
i=i+1 !формирование номера считываемой записи
read(30, rec=i) x
if (x>0)then
k=k+1 ! формирование номера записи во врем. файле
write(10, rec=k) x
endif
enddo
find(10, rec=1) !перешли на начало временного файла
close(30, status='delete') !удалили исходный файл
!снова открыли исходный файл для записи
open (30, file='f_dir.txt', access='direct', form='unformatted',recl=4)
i=0
!переписываем из временного файла в основной
do while (.not.eof (10))
i=i+1
read (10, rec=i) x !читаем из временного
write (30, rec=i)x !пишем в основной
enddo
print*,'ok perezap del,kol=',i
close(10) !при закрытии временный файл удаляется
close(30)
end subroutine
Процедура удаления записи с использованием в качестве временного файла - неформатный файл последовательного доступа.
subroutine del_zap ()
implicit none
integer i, k
real x
!открываем исходный файл
open (30, file='f_dir.txt', access='direct', form='unformatted', recl=4)
!открываем временный файл (неформатный)
open(10, form='unformatted', status='scratch')
i=0 !формирование номера записи
do while (.not.eof (30))
i=i+1
read(30, rec=i) x !прочитали запись из исходного файла
if (x>0)then
write(10) x !записали во временный файл
endif
enddo
rewind(10) !вернулись на начало временного файла
close(30, status='delete') ! удалили исходный файл
! заново открыли исходный файл
open (30, file='f_dir.txt', access='direct', form='unformatted',recl=4)
i=0
do while (.not.eof (10))
i=i+1
read (10) x ! прочитали запись из временного файла
write (30, rec=i)x ! записал в основной
enddo
close(10)
close(30)
end subroutine
Пример