我使用的方式如下。我尝试以默认格式打开一个文件,并测试读取它。如果失败(错误或到达文件末尾),则未格式化。但这并没有给我对文件类型的信心,毕竟,为什么一个未格式化的文件不能给出格式化的读取,为什么一个格式化的文件给出一个失败的未格式化的读取。我期望未格式化的文件作为格式化的读取最有可能返回错误,但不能保证,格式化的文件读取作为非格式化的读取会产生奇怪的东西,但不会返回错误(测试代码实际上返回文件的结尾)。有没有更好的方法来检查文件类型?
发布于 2016-07-29 23:20:21
简短的回答
格式化文件主要包含ASCII。处理器和实现允许您拥有非ascii,将它们写到文件中是可以的,但是如果以格式化的方式读取它们,那么读回它们可能是一个问题。假设您的格式化文件只包含ASCII字符,并且您的未格式化文件不限于文本,则以下子例程将完成此工作。
!
subroutine detect_format(fName)
character(*), intent(in) :: fName
integer :: fId, stat
character :: c
logical :: formatted
!
stat = 0
formatted = .true. !assume formatted
open(newunit=fId,file=fName,status='old',form='unformatted',recl=1)
! I assume that it fails only on the end of file
do while((stat==0).and.formatted)
read(fId, iostat=stat)c
formatted = formatted.and.( iachar(c)<=127 )
end do
if(formatted)then
print*, trim(fName), ' is a formatted file'
else
print*, trim(fName), ' is an unformatted file'
end if
close(fId)
!
end subroutine detect_format如果未格式化的文件仅包含字符,则此过程将不起作用。无论如何,格式化和非格式化字符文件之间没有区别,除非它是具有可变记录大小的非格式化字符文件。在这种特殊情况下,您可以使用保存的记录大小来捕获它。
您可以使用一些启发式方法来简化它。例如,如果前100个字节是ASCII,您可以说您认为它是ASCII。或者你可以说,如果超过80%是ASCII,你可以认为它是ASCII。通过使用基于流的IO,可以使子例程变得简单。
长长的答案
首先要理解:-数据在计算机存储器(RAM、磁盘等)中的内部表示;-外部表示;-以及它们之间的区别。第二件事是理解fortran中格式化文件和非格式化文件的区别。
通过内部表示,我指的是CPU处理数据的形式。这就是二进制表示。在内部表示中,您必须知道数据的类型才能赋予其含义。所谓外部表示,我指的是打印在屏幕上或从打印机打印到纸张上的字形。例如,如果我们只处理数字,字形是基于拉丁语的语言的符号(0,1,2,...,9),(I,II,III,IV,X,...)为了罗曼。遵循其他语言中的字形的link。我有点偏离fortran标准的定义,但这是为了过渡的目的。fortran标准仅使用符号(0,1,2,...,9),但某些实现考虑了小数分隔符,可以是逗号或点。人类的大脑能够通过观察外部表示来找出它是什么。在内部表示和外部表示之间,有一个中间表示,它帮助人和计算机相互理解。fortran中格式化文件和未格式化文件的区别就在于这种形式。该中间形式是外部表示的计算机内部表示(计算机不存储字形,它仅在您想要查看时根据请求绘制字形)。作为计算机表示,中间形式是二进制的,但它与外部表示(字形)具有1对1的对应关系。
在计算机科学中,存储单位是字节。有些人喜欢去比特的级别,但这并不是必须的。存储在计算机内存中的数据仅仅是字节串。一个字节本身就是一个8位的字符串,这意味着一个字节可以存储256种可能的值。此外,字节通常由4或8组成(在过去,他们将其称为单词)。现在,只有当您知道它包含的数据类型时,任何字节或字节组才有意义。您可以将相同的4字节字符串处理为4字节整数、4字节IEEE浮点数、4字节字符的字符串等。如果您正在处理4字节数字(整数或IEEE浮点),内部表示允许byte接受所有可能的256个值(除了极少数用于定义标记NaN Inf等的值,但它们仍然是值)。如果您正在处理英文文本(ASCII),则内部表示允许byte只接受前127个值。当涉及到外部表示时,一切都必须转换为字形:数字和字符一样。中间表示必须将数字映射到字形。每个数字都必须转换为一串数字。因为数字也是ASCII字符,所以所有内容都限制为127个字节的值。这是确定文件内容的关键。
当谈到fortran时,它主要使用格式化文件作为人类可读的内容。该文件的内容将是中间表示,限于英语的ASCII。未格式化的文件表示数据在CPU中处理时的二进制或内部表示形式。它就像RAM的转储。
现在,要用现代fortran编译器检测内容,您只需打开文件,逐字节读取它,并检查它是否只包含ASCII。如果你得到的是非ASCII格式的文件,那么你就有一个未格式化的文件,否则你就有一个格式化的文件。在现代编译器中,可以通过使用基于流的IO或每个1字节的固定大小记录来逐个字节地读取。后者就是示例中使用的那个。
我不得不补充说,生活并不是那么简单。这个过程只给出了一个很高的概率,而不是确切的事实。全部在ASCII范围内并不能保证它自动是字符。如果你有一个字符文件,不管它是格式化的还是固定大小的记录未格式化,它都会包含ASCII。
发布于 2016-07-29 16:20:56
一种方法是以逻辑方式命名文件。就我个人而言,我对格式化数据使用.dat、.txt或.csv,对二进制数据使用.bin。除非你有文件的hundreds+,也许你可以用编辑器打开它们,看看它是什么样子的?
https://stackoverflow.com/questions/38651487
复制相似问题