在文件中区分ASCII文本和二进制内容

3

我有一个文件,里面既包含ASCII文本,也包含二进制内容。我想提取文本,而不必解析二进制内容,因为二进制内容有180MB。我能否简单地提取文本以进行进一步操作...最好的方法是什么。

ASCII文本位于文件开头。


1
这两个部分是如何分隔的? - John Feminella
当我查看原始文件时,似乎第一行是ASCII码,其余部分是二进制的,所以只读取第一行是否足够呢?我猜这可能是一个快速而简单的解决方案。我想知道的是,有没有一种方法可以检测ASCII码停止并且二进制码开始的位置? - Ankur
只读取第一行就好了。这样做不仅减少了麻烦,而且如果每行都以换行符作为分隔符的话,这也是正确的解决方案。 - John Feminella
文件格式是什么?常见的格式可能会有一个提取数据的框架。 - Tim R
这是一个FITS文件 - 如果有提取数据的框架,那就太好了。 - Ankur
也请看一下HTTP请求解析。原理类似。 - finnw
6个回答

3

有4个Java库可以读取FITS文件,点击这里查看:

Java

nom.tam.fits

开发了一个Java FITS库,提供了高效的FITS图像和二进制表的I/O,至少对于Java而言。Java库支持所有基本的FITS格式和gzip压缩文件。包括支持访问数据子集,并且可以使用HIERARCH约定。

eap.fits

包括用于查看和编辑FITS文件的应用程序和小应用程序。还包括一个用于读写FITS数据的通用包。如果可用的话,它可以读取PGP加密文件。

jfits

jfits库支持FITS图像和ASCII和二进制表。支持关键字和数据的内联修改。

STIL

纯Java通用表I/O库,可以读取和写入FITS二进制表等其他表格式。它高效,并且可以提供比物理内存大得多的FITS表的快速顺序或随机读取访问。不支持FITS图像。


1
假设有一个令牌可以将文件分成二进制和 ASCII 组件(例如,一个单独的行上的 "#END#"),你可以执行以下操作:
import java.io.*;

// ...

public static void main(String args[]) {
  try {
    FileInputStream f = new FileInputStream("object.bin");
    DataInputStream d = new DataInputStream(f);
    BufferedReader b = new BufferedReader(new InputStreamReader(d));

    String s = "";
    while ((s = b.readLine()) != "#END#") {
      // ASCII contents parsed here.
      System.out.println(s);
    }

    d.close();
  } catch (Exception e) {
      System.err.println("kablammo! " + e.getMessage());
  }
}

似乎€经常是第一个字符,也许我可以利用它。 - Ankur

1

编写一个方法,检查特定字符是否符合您的条件(这里,我已经涵盖了键盘上找到的字符)。一旦您遇到该方法返回false的字符,就知道您已经遇到了二进制。请注意,有效的ASCII字符也可能构成二进制的一部分,因此您可能最终会得到一些额外的字符。

static boolean isAsciiCharacter(char c) {
    return (c >= ' ' && c <= '~') ||
            c == '\n' ||
            c == '\r';
}

1

我不知道有没有Java类可以读取ASCII字符并忽略其余部分,但在这里我能想到的最简单的方法是使用strings实用程序(假设您正在使用基于Unix的系统)。

概要 strings [ - ] [ -a ] [ -o ] [ -t format ] [ -number ] [ -n number ] [--] [file ...]

描述 Strings会在二进制文件或标准输入中查找ASCII字符串。 Strings对于识别随机对象文件和许多其他事物非常有用。字符串是以换行符或空字符结尾的4个(默认值)或更多打印字符序列。除非给出了-标志,否则strings将查找对象文件的所有部分,除了(__TEXT,__text)部分。如果未指定文件,则读取标准输入。

然后,您可以将输出导入另一个文件并对其进行任何操作。

编辑:有了额外的信息,所有ASCII字符都在开头,这样就更容易通过编程方式提取文本;尽管如此,这仍然比编写代码要快。

你将会把多个这样的文件作为输入吗? - danben

1
假设您可以确定ASCII内容的结尾位置,只需从文件中读取字符,直到找到其结尾,并关闭文件。

问题在于如何确定ASCII内容的结束位置。 - Ankur
1
没有简单的方法。最好的办法是在遇到第一个非可打印字符时停止(因为您知道它不会在ASCII部分中),但是在那之前,您仍然可能会捕获一些二进制部分开头的垃圾数据。如果您知道二进制部分的确切结构,比如说它总是以相同的字符序列开头,那么您可以查找该序列以确定ASCII部分的结束位置。 - Anon.

1

一个FITS文件的前2880个字节是ASCII头数据,表示36个80列的“卡片图像”。没有行终止符号,只有一个36x80的ASCII数组,必要时用空格填充。在二进制数据之前可能会有额外的2880字节的ASCII头;您需要解析第一组头来知道期望多少ASCII。

但我完全赞成Oscar Reyes的建议,使用现有的软件包来解码FITS文件!他提到的两个软件包都由NASA的戈达德太空飞行中心托管,他们也负责维护FITS格式。这是您可以得到的最权威的来源。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接