如何检测文件是格式化还是未格式化?

时间:2016-07-29 05:59:21

标签: fortran

我使用的方式如下。我尝试以默认格式化表单打开文件并测试它。如果失败(错误或达到文件结束),则无格式化。但是,这并不能让我对文件类型充满信心,毕竟,为什么未格式化的文件无法提供格式化的读取,为什么格式化的文件会给出失败的无格式读取。我希望未格式化的文件读取为格式化返回最可能的错误但不保证,格式化文件读取为无格式提供奇怪的事情但不是错误(测试代码实际上返回文件末尾)。有没有更好的方法来检查文件类型?

2 个答案:

答案 0 :(得分:1)

一种方法是以逻辑方式命名文件。 我个人使用.dat,.txt或.csv格式化数据,我使用.bin作为二进制数据。 除非你有数百个文件,否则你可以用编辑器打开它们,看看它是什么样的?

答案 1 :(得分:1)

简短回答

格式化文件主要包含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。或者你可以说你认为它是ASCII,如果80%以上是ASCII。通过使用基于流的IO,可以使子例程变得简单。

答案很长

首先要了解: - 计算机内存(RAM,磁盘等)中数据的内部表示; - 外部代表; - 以及它们之间的区别。 第二件事是理解格式化与未格式化文件的区别。

  1. 计算机内存中数据的内部和外部表示。
  2. 通过内部表示,我指的是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浮点数),内部表示允许字节采取所有可能的256个值(除了用于定义标记NaN Inf等的极少数值,但它们仍然是值)。如果您正在处理英文文本(ASCII),则内部表示允许字节仅采用前127个值。 当谈到外部表示时,一切都必须变成字形:数字和字符都一样。中间表示必须将数字映射到字形。每个号码必须变成一串数字。因为数字也是ASCII字符,所以一切都限制在127个字节值。这是确定文件内容的关键。

    1. Fortran格式化和未格式化的文件
    2. 说到fortran,它主要使用格式化文件来处理人类可读的内容。文件的内容将是中间表示,限于英语的ASCII。 无格式文件表示在CPU中处理的数据的二进制或内部表示。它就像是RAM的转储。

      现在要使用现代fortran编译器检测内容,您只需打开文件并逐字节读取它并检查它是否只包含ASCII。如果你得到非ASCII,你有一个未格式化的文件,否则你有一个格式化的文件。逐字节读取可以通过在现代编译器中使用基于流的IO或每个1字节的固定大小的记录来完成。后者是示例中使用的那个。

      我必须补充一点,生活并非那么简单。那个程序只有很高的概率而不是确切的事实。全部在ASCII范围内并不保证它是自动字符。 如果你有一个字符文件,无论是格式化的还是固定大小的记录都没有格式化,它将包含ASCII。