file_handling_class.f90
Go to the documentation of this file.
1 !> @file file_handling_class.f90
2 !!
3 !! The error file code for this file is ***W18***.
4 !! @brief Module \ref file_handling_class
5 !!
6 
7 !> Provide some basic file-handling routines
8 !!
9 !! @author Darko Mocelj
10 !! @date 07.05.04
11 !!
12 !! \b Edited:
13 !! - 12.11.09: Christian Winteler
14 !! - 11.01.14: Oleg Korobkin
15 !! - 07.11.16: Oleg Korobkin
16 !! - 22.01.21: Moritz Reichert
17 !! .
19  use error_msg_class
20  implicit none
21  integer, parameter, private :: min_unit=10 !< Minimum unit number
22  integer, parameter, private :: max_unit=9999 !< Maximum unit id
23 
24  !
25  ! Public and private fields and methods of the module
26  !
27  public:: &
30 
31  contains
32 
33  !> Finds the next unused unit number
34  !!
35  !! In case there is no open slot for a new file
36  !! this subroutine will call an error.
37  !! For example if there are more files open than
38  !! \ref max_unit, this error will get called.
39  function get_next_io_unit() result(next)
40  integer :: next !< the next available unit number
41  !
42  integer,save:: last_unit=min_unit - 1 ! previously found open slot
43  integer :: fail_count ! number of failures
44  logical :: is_open ! file status
45 
46  fail_count= 0
47  next= last_unit + 1
48  forever: do
49  inquire(unit=next,opened=is_open)
50  if (.not. is_open) then
51  last_unit=next !found it
52  exit forever
53  end if
54  next= next + 1
55  if (next > max_unit) then
56  last_unit= min_unit
57  if (fail_count<3) then ! attempt reset 3 times
58  fail_count= fail_count + 1
59  next= min_unit
60  else
61  ! complain and exit
62  call raise_exception("Cannot find open slot to open a file.",&
63  "get_next_io_unit",&
64  180003)
65  endif
66  end if !reset try
67  enddo forever
68 
69  end function get_next_io_unit
70 
71 
72  !> Shorthand for opening a new unformatted file for writing (output file)
73  function open_unformatted_outfile(file_name) result(unit_no)
74  character(len=*), intent(in) :: file_name !< path to open
75  integer :: unit_no !< unit number
76  integer istatus
77 
78  unit_no= get_next_io_unit()
79  open (unit=unit_no, file=trim(file_name), status="unknown",form='unformatted',iostat=istatus)
80  if (istatus /= 0) call raise_exception("Could not open file: "//&
81  trim(adjustl(file_name)),"open_unformatted_outfile",&
82  180004)
83  end function open_unformatted_outfile
84 
85 
86 
87  !> Open an unformatted file for reading
88  function open_unformatted_infile(file_name) result(unit_no)
89  character(len=*), intent(in) :: file_name !< path to open
90  integer :: unit_no !< unit number
91  integer istatus
92 
93  unit_no= get_next_io_unit()
94  open (unit=unit_no, file=trim(file_name), status="old",form='unformatted',iostat=istatus)
95  if (istatus /= 0) call raise_exception("Could not open file: "//&
96  trim(adjustl(file_name)),"open_unformatted_infile",&
97  180004)
98  end function open_unformatted_infile
99 
100 
101 
102  !> Shorthand for opening a new file for writing (output file)
103  !!
104  !! This function is used to open a file in order
105  !! to write into it. It will also complain if it is
106  !! not possible.
107  function open_outfile(file_name) result(unit_no)
108  character(len=*), intent(in) :: file_name !< path to open
109  integer :: unit_no !< unit number
110  integer istatus
111 
112  unit_no= get_next_io_unit()
113  open (unit=unit_no, file=trim(file_name), status="unknown",iostat=istatus)
114  if (istatus /= 0) call raise_exception("Could not open file: "//&
115  trim(adjustl(file_name)),"open_outfile",&
116  180004)
117 
118  end function open_outfile
119 
120 
121  !> Same for reading (input file)
122  !!
123  !! This function is used for read input files
124  !! and complain if it does not work.
125  function open_infile(file_name) result(unit_no)
126  character(len=*), intent(in) :: file_name !< path to open
127  integer :: unit_no !< unit number
128  integer istatus
129 
130  unit_no= get_next_io_unit()
131  open (unit=unit_no, file=trim(file_name), status="old",iostat=istatus)
132  if (istatus /= 0) call raise_exception("Could not open file: "//&
133  trim(adjustl(file_name)),"open_infile",&
134  180005)
135 
136  end function open_infile
137 
138 
139  !> Close an external file
140  !!
141  !! This function is used to close a file and
142  !! complain if it does not work.
143  subroutine close_io_file(unit_no, file_name)
144  integer, intent(in) :: unit_no !< unit number
145  character(len=*), optional, intent(in) :: file_name !< for reporting
146  integer istatus
147 
148  if (unit_no.lt.min_unit .or. unit_no.gt.max_unit) then
149  ! Raise exception (out of bounds) depending on the available data
150  if (present(file_name)) then
151  call raise_exception("Unit value "//int_to_str(unit_no)//" is out of range"//&
152  new_line("A")//"when trying to close "//&
153  trim(adjustl(file_name)),"close_io_file",&
154  180006)
155  else
156  call raise_exception("Unit value "//int_to_str(unit_no)//" is out of range",&
157  "close_io_file",&
158  180006)
159  end if
160  endif
161 
162  ! Close the file
163  close(unit=unit_no,iostat=istatus)
164  ! Check if the file was closed properly
165  if (istatus /= 0) then
166  ! Raise exception depending on the available data
167  if (present(file_name)) then
168  call raise_exception("Closing a file, status = "//int_to_str(istatus)//"."//&
169  new_line("A")//"Unit number: "//int_to_str(unit_no)//&
170  new_line("A")//"File name: "//trim(adjustl(file_name)),&
171  "close_io_file",&
172  180007)
173  else
174  call raise_exception("Closing a file, status = "//int_to_str(istatus)//"."//&
175  new_line("A")//"Unit number: "//int_to_str(unit_no),&
176  "close_io_file",&
177  180007)
178  endif
179  endif
180 
181  end subroutine close_io_file
182 
183 
184 
185  !> Delete a file
186  !!
187  !! This function is used to delete a file. If the file does not
188  !! exist and raise_error is present, an error is raised.
189  !!
190  !! @author M. Reichert
191  subroutine delete_io_file(file_name,raise_error)
192  implicit none
193  character(len=*), optional, intent(in) :: file_name !< for reporting
194  integer :: istatus !< IO status variable
195  integer :: unit_no !< Unit number
196  logical,optional :: raise_error !< Raise error in case of failure
197 
198  unit_no= get_next_io_unit()
199  open (unit=unit_no, file=trim(file_name), status="old",iostat=istatus)
200 
201  if (istatus == 0) then
202  ! Delete the file if present
203  close(unit_no, status='delete')
204  else
205  ! Raise an error if necessary
206  if (present(raise_error)) then
207  call raise_exception("Deleting a file, status = "//int_to_str(istatus)//".",&
208  "delete_io_file",&
209  180008)
210  end if
211  end if
212  end subroutine delete_io_file
213 
214 
215 
216 
217 
218 
219  end module file_handling_class
file_handling_class::delete_io_file
subroutine, public delete_io_file(file_name, raise_error)
Delete a file.
Definition: file_handling_class.f90:192
error_msg_class
Error handling routines.
Definition: error_msg_class.f90:16
error_msg_class::int_to_str
character(:) function, allocatable, public int_to_str(num)
Converts a given integer to a string.
Definition: error_msg_class.f90:224
error_msg_class::raise_exception
subroutine, public raise_exception(msg, sub, error_code)
Raise a exception with a given error message.
Definition: error_msg_class.f90:245
file_handling_class
Provide some basic file-handling routines.
Definition: file_handling_class.f90:18
file_handling_class::get_next_io_unit
integer function, public get_next_io_unit()
Finds the next unused unit number.
Definition: file_handling_class.f90:40
file_handling_class::open_infile
integer function, public open_infile(file_name)
Same for reading (input file)
Definition: file_handling_class.f90:126
file_handling_class::max_unit
integer, parameter, private max_unit
Maximum unit id.
Definition: file_handling_class.f90:22
file_handling_class::open_outfile
integer function, public open_outfile(file_name)
Shorthand for opening a new file for writing (output file)
Definition: file_handling_class.f90:108
file_handling_class::min_unit
integer, parameter, private min_unit
Minimum unit number.
Definition: file_handling_class.f90:21
file_handling_class::close_io_file
subroutine, public close_io_file(unit_no, file_name)
Close an external file.
Definition: file_handling_class.f90:144
file_handling_class::open_unformatted_outfile
integer function, public open_unformatted_outfile(file_name)
Shorthand for opening a new unformatted file for writing (output file)
Definition: file_handling_class.f90:74
file_handling_class::open_unformatted_infile
integer function open_unformatted_infile(file_name)
Open an unformatted file for reading.
Definition: file_handling_class.f90:89