Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Файлы.doc
Скачиваний:
42
Добавлен:
26.03.2015
Размер:
274.94 Кб
Скачать

Неформатные файлы

Рассмотрим теперь неформатные файлы последовательного и прямого доступа.

Неформатный файл не может быть создан и просмотрен в текстовом редакторе. Для его создания обязательно нужна программа, т.к. данные хранятся в машинном представлении (данные передаются без преобразования). Метод доступа будет фигурировать в операторе open в спецификаторе access = ‘sequential/direct’, а формат в спецификаторе form = ' unformatted'.

Из неформатного файла одним оператором ввода можно прочитать только одну запись. Каждый оператор вывода создает одну запись.

Рассмотрим сначала неформатные файлы последовательного доступа.

Для этих файлов справедливы все правила, которые используются для обработки, корректировки, добавления и удаления текстовых файлов. Разница лишь в том, что чтение и запись осуществляется без формата. Кроме того, как уже упоминалось для их создания и просмотра нужна специальная программа.

Пример

В неформатном файле последовательного доступа хранятся вещественные числа. Удалить из файла наименьшее значение .

Удаление будем делать, используя вспомогательный файл.

Вообще лучше сделать в отдельном проекте неформатный файл и подключить его в свой проект, чтобы не создавать файл при каждом запуске программы.

!процедура создания неформатного файла

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_min ()

implicit none

real x, min

open (10, file= 'isxseq.txt', form= 'unformatted', status='old')

open (30, form='unformatted', status='scratch') !временный файл

!нахождение наименьшего значения в файле

read(10) min ! чтение из файла первой записи

do while (.not. eof (10))

read(10) x

if (x < min) min=x

enddo

!удаление с использованием временного файла

rewind(10)

do while (.not. eof (10))

read(10) x

if (x /= min) write(30 ) x

enddo

rewind (10)

rewind (30)

do while (.not. eof (30))

read(30) x

write(10)x

enddo

close(10)

close(30)

end subroutine

program main

implicit none

integer, parameter:: n=10 !количество создаваемых чисел

call create_sq (n)

print*,' исходный файл '

call view_sq()

call del_min()

print*,' файл после удаления'

call view_sq()

end program

Файлы прямого доступа

В файле, присоединенном для прямого доступа, все записи имеют одинаковую длину, которая задается в операторе open, спецификатором recl.

В операторе open для неформатного файла прямого доступа обязательно должны быть спецификаторы:

open (<номер устройства> , file='<имя файла>', access= 'direct' , recl= <размер записи>)

Для определения размера записи можно использовать функцию:

Sizeof (<имя переменной> (recl = Sizeof (<имя переменной>)

Спецификатор form=' unformatted ' в случае прямого доступа задается по умолчанию и может быть опущен.

В случае форматного файла прямого доступа, он обязателен form=' formatte '.

Каждая запись в файле прямого доступа имеет свой уникальный номер. Читать и записывать данные в файл прямого доступа можно необязательно по порядку их номеров. Можно в него занести запись с любым порядковым номером (например, сначала запись №5, а затем запись №2). Если в файле не было записей с №1 и 2, все равно под них будет зарезервировано место (при просмотре их значения равны нулю).

В неформатном файле прямого доступа можно позиционировать (установить указатель) непосредственно на запись с № n:

В CVF для этих целей можно использовать оператор find.

Find (<номер устройства>, rec=№ n)

Этот оператор только устанавливает указатель на нужную запись.

Или использовать оператор Read (<номер устройства>, rec=№ n), если хотим прочитать запись и ее анализировать.

При использовании оператора write будет заменена та запись, номер которой задан спецификатором rec=№ n.

Write (<номер устройства>, rec=№ n)<новая запись>

Пример

Запись в неформатный файл прямого доступа может производиться в любом порядке.

program main

implicit none

integer x, y, z, i, n

open(10,file='a.txt',form='unformatted',access='direct',recl=4,status='new')

y = 15

write(10, rec=2)88 !записали в файл на 2 место - 88

write(10, rec=5)y !записали в файл на 5 место – значение y

write(10, rec=5)111 !заменили в файле 15 на 111

do I = 1, 5

read(10, rec=i) x

print*, x !вывод файла на экран (5 записей)

enddo

read(10, rec=4) y !прочитали 4 –ую запись

print*, y !вывели ее на экран

!Добавим в файл запись.

write(10, rec =6) 20 !записали на 6 место - 20

!установили указатель на 1-ую запись

find(10, rec=1)

print*, ' полученный файл '

i=0 !счетчик записей

do while (.not. eof (10))

i=i+1 !формируем номер записи

read(10, rec= i) z !считываем очередную запись

print*, z

enddo

close(10)

end

Получили: 0 88 0 0 111 20 (на месте не введенных компонент - 0)

Создание и просмотр неформатных файлов последовательного и прямого доступа осуществляется только программным путем.

Для создания и просмотра неформатных файлов прямого доступа напишем отдельную программу. Для этого лучше создать отдельный проект. В дальнейших задачах будем использовать эти процедуры, подключая их в свой проект.

Еще один вариант использования оператора inquire:

Для контроля открытия файла можно использовать следующую последовательность операторов:

logical tf

inquire( filenum, opened=tf)

if (.not. tf)then

print*,'file not opened'

stop

endif

Openedлогическая переменная, которая возвращает значение TRUE при опросе файла, если файл присоединен к устройству и FALSE в противном случае.

Процедуры создания и просмотра неформатных файлов прямого доступа можно поместить в модуль и подключать модуль в свой проект при необходимости или поместить в файлах отдельно.

Модуль, в котором помещены процедуры создания и просмотра неформатных файлов прямого доступа:

module in_out_fil

contains

!создание неформатного файла прямого доступа

subroutine create_dir(n)

implicit none

integer,intent(in)::n

integer i

real x

open (30, file='new_dir.txt', access= 'direct', form='unformatted', recl=4, status='new', err=21)

do i=1, n

print*,'bb cislo'

read *, x

write(30, rec=i, err=22) x ! rec=i

enddo

print*, 'zapis ok'

close(30)

return

21 print*,'ochibka open dir'

stop

22 print*,'oshibka write'

end subroutine

!Процедура просмотра неформатного файла прямого доступа

subroutine view_dir()

implicit none

integer i

real x

i=0

open (60, file='new_dir.txt', access='direct', form='unformatted', recl=4, status='old', err=21)

print*,'исходный файл'

do while (.not. eof (60))

i=i+1

read (60, rec = i) x ! rec=i- обязательно

print '(F4.0, 2x\)', x !вывод на экран

enddo

close(60)

return

21 print*,'ochibka open'

stop

end subroutine

end module

Пример

Вещественные числа хранятся в неформатном файле прямого доступа. Заменить максимальное значение удвоенным произведением.

В этом случае корректировка производится без вспомогательного файла.

!замена max на 2*max в файле прямого доступа

! n- количество вводимых чисел

subroutine create_dir ( n )

implicit none

integer, intent(in):: n

integer i

real x

open (30, file='new_dir.txt', access= 'direct', form='unformatted', recl=sizeof (x), err=21)

do i=1, n

print*,'bb cislo'

read *, x ! считывание числа с клавиатуры в ОП

write(30, rec=i, err=22) x !запись из ОП в файл

enddo

print*, ' zapis ok'

close(30)

return

21 print*, 'ochibka open dir'

return

22 print*, 'oshibka write'

stop

end subroutine

subroutine view_dir()

implicit none

integer i

real x

i=0

open (60, file='new_dir.txt', access='direct', form='unformatted', recl=4, status='old', err=21)

print*,' f ail dir'

do while(.not. eof (60))

i=i+1

read(60, rec=i) x

print '(f4.0, 2x\)', x

enddo

close(60)

return

21 print*, 'ochibka open'

stop

end subroutine

! процедура замены

subroutine chenc()

implicit none

integer i, imax

real x, max

open (10, file='new_dir.txt', access='direct', form='unformatted', recl=4, status='old', err=21)

!нахождение наибольшего значения и номера записи

i=1

read(10, rec=i) max

imax=i

do while (.not. eof (10))

i=i+1

read(10, rec=i) x

if (x < max) then

max=x

imax=i

endif

enddo

read (10, rec= imax) x !прочитали из файла запись с № imax

x=2*x ! увеличили в 2 раза х в ОП

write(10, rec= imax) x !записали измененный х в файл

close(10)

return

21 print *, 'ochibka open'

stop

end subroutine

program main

implicit none

integer,parameter:: n=10

call create_dir (n)

print*,'isx fil'

call view_dir()

call chenc()

print*,'posle zameni'

call view_dir()

end

Пример

В неформатном файле прямого доступа хранятся целые числа. Поменять местами наименьшее значение с первым. Результат вывести на экран.

subroutine create_dir(n)

implicit none

integer,intent(in)::n

integer i

real x

open (30, file='new_dir.txt', access= 'direct', form='unformatted', recl=4, status='new', err=21)

do i=1, n

print*,'bb cislo'

read *, x

write(30, rec=i, err=22)x

enddo

print*, 'zapis ok'

close(30)

return

21 print*, 'ochibka open dir'

stop

22 print*, 'oshibka write'

stop

end subroutine

subroutine view_dir()

implicit none

integer i

real x

i=0

open (60, file='new_dir.txt', access='direct', form='unformatted', recl=4, status='old', err=21)

print*,'fail dir'

do while(.not. eof (60))

i=i+1

read(60, rec=i) x

print '(f4.0, 2x\)', x

enddo

close(60)

return

21 print*, 'ochibka open'

stop

end subroutine

subroutine chenc()

implicit none

integer i,imin

real x,min

open (10, file='new_dir.txt', access='direct', form='unformatted', recl=4, status='old', err=21)

read(10,rec=1)min

i=1

imin=1

do while(.not.eof (10)

i=i+1

read(1, rec=i) x

if (x<min) then

min=x

imin=i

endif

enddo

read (10, rec=1) x

write(10, rec=1) min

write(10, rec= imin) x

close(10)

return

21 print*,'ochibka open'

stop

end subroutine

program main

implicit none

integer,parameter::n=10

call create_dir (n)

print*,'isx fil'

call view_dir()

call chenc()

print*,'posle zameni'

call view_dir()

end

Записями (компонентами) неформатного файла прямого доступа могут быть массивы.

Пусть в файле хранятся два целочисленных массива по 5 элементов каждый. Напишем процедуру создания файла, в котором хранятся массивы из определенного количества элементов, а также процедуру просмотра этого файла.

program main

implicit none

integer, parameter:: narr=2, n=5 !количество массивов

call create_dir (narr, n)

print*,'isx fil'

call view_dir(n)

end

subroutine create_dir(narr, n)

implicit none

integer, intent(in):: narr, n !количество массивов

integer i

real x(n)

open (30, file= 'mas_dir.txt', access= 'direct', form='unformatted', recl=sizeof (x) , err=21)

do i=1, narr

print*,'введи’, i, ‘ –ый массив'

read *, x !чтение массива с клавиатуры

write(30, rec=i, err=22) x !запись массива в файл

enddo

print*, 'zapis ok'

close(30)

return

21 print*, 'ochibka open dir'

stop

22 print*, 'oshibka write'

stop

end subroutine

subroutine view_dir ( n )

implicit none

integer i

real x (n)

i=0

open (60, file='mas_dir.txt', access='direct', form='unformatted', recl=sizeof (x), err=21)

print*,'fail dir'

do while (.not. eof (60))

i=i+1

read(60, rec=i) x !чтение массива из файла

print*,i, ' massiv'

print '(f4.0, 2x\)', x !вывод массива на экран

enddo

close(60)

return

21 print*, 'ochibka open'

stop

end subroutine

Соседние файлы в предмете Программирование на Pascal