首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何检测文件是格式化的还是未格式化的?

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

Stack Overflow用户
提问于 2016-07-29 13:59:21
回答 2查看 883关注 0票数 0

我使用的方式如下。我尝试以默认格式打开一个文件,并测试读取它。如果失败(错误或到达文件末尾),则未格式化。但这并没有给我对文件类型的信心,毕竟,为什么一个未格式化的文件不能给出格式化的读取,为什么一个格式化的文件给出一个失败的未格式化的读取。我期望未格式化的文件作为格式化的读取最有可能返回错误,但不能保证,格式化的文件读取作为非格式化的读取会产生奇怪的东西,但不会返回错误(测试代码实际上返回文件的结尾)。有没有更好的方法来检查文件类型?

EN

回答 2

Stack Overflow用户

发布于 2016-07-29 23:20:21

简短的回答

格式化文件主要包含ASCII。处理器和实现允许您拥有非ascii,将它们写到文件中是可以的,但是如果以格式化的方式读取它们,那么读回它们可能是一个问题。假设您的格式化文件只包含ASCII字符,并且您的未格式化文件不限于文本,则以下子例程将完成此工作。

代码语言:javascript
复制
!
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中格式化文件和非格式化文件的区别。

  1. 计算机内存中数据的内部和外部表示。

通过内部表示,我指的是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个字节的值。这是确定文件内容的关键。

  1. Fortran格式化和未格式化的文件

当谈到fortran时,它主要使用格式化文件作为人类可读的内容。该文件的内容将是中间表示,限于英语的ASCII。未格式化的文件表示数据在CPU中处理时的二进制或内部表示形式。它就像RAM的转储。

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

我不得不补充说,生活并不是那么简单。这个过程只给出了一个很高的概率,而不是确切的事实。全部在ASCII范围内并不能保证它自动是字符。如果你有一个字符文件,不管它是格式化的还是固定大小的记录未格式化,它都会包含ASCII。

票数 2
EN

Stack Overflow用户

发布于 2016-07-29 16:20:56

一种方法是以逻辑方式命名文件。就我个人而言,我对格式化数据使用.dat、.txt或.csv,对二进制数据使用.bin。除非你有文件的hundreds+,也许你可以用编辑器打开它们,看看它是什么样子的?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38651487

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档