如何在Java中清晰地读取ASCII和其他编码的文件?

如何在Java中清晰地读取ASCII和其他编码的文件?,java,ascii,readfile,Java,Ascii,Readfile,我有一个自定义图像文件,其中第一块数据是ASCII元数据。我需要能够用Java读取文件的ASCII元数据部分,并知道它何时结束,以及另一种编码中的“原始图像数据”何时开始 我正在考虑将所有文件读入一个字节[],然后以某种方式开始从中读取字节并将其转换为ASCII,直到我到达ASCII元数据部分的末尾,此时我将存储这些数据。然后,我可以按照不同的顺序重新排列原始二进制数据(无需读取)。然而,我能想到的唯一方法是逐字节读取ascii内容并寻找新行,然后在新行之前搜索所有内容,看看这是否是表示原始图像

我有一个自定义图像文件,其中第一块数据是ASCII元数据。我需要能够用Java读取文件的ASCII元数据部分,并知道它何时结束,以及另一种编码中的“原始图像数据”何时开始

我正在考虑将所有文件读入一个字节[],然后以某种方式开始从中读取字节并将其转换为ASCII,直到我到达ASCII元数据部分的末尾,此时我将存储这些数据。然后,我可以按照不同的顺序重新排列原始二进制数据(无需读取)。然而,我能想到的唯一方法是逐字节读取ascii内容并寻找新行,然后在新行之前搜索所有内容,看看这是否是表示原始图像数据开始的标记。但是,必须有更好的方法使用readLine()读取文件的ascii部分,然后能够立即从原始图像二进制文件开始,而无需在新的读卡器中重新打开文件,并转到我在另一个读卡器中找到“begin image”标记的行

有什么想法吗?

  • FileInputStream
    的形式打开文件(包装在
    BufferedInputStream
    中)
  • 通过tearrayoutputstream创建
  • 逐字节读取输入流,使用。将单个字节强制转换为
    char
    (隐式使用ASCII)
  • 同时,将所查看的每个字节写入
    ByteArrayOutputStream
  • 一旦找到标记,就可以开始从输入流读取图像数据
  • ByteArrayOutputStream
    获取字节数组,并使用
    新字符串(数组,“US-ASCII”)将其转换为字符串
通过在输入流上使用标记,可以很容易地进行字符串搜索,但是您必须小心使用哪种模式,以确保它在不开始读取图像数据的情况下找到标记(因为您希望自己从保留单独引用的基础输入流中读取该标记)


编辑:不幸的是,扫描器似乎也隐式使用了缓冲区,所以剩下的唯一选项是“手动”执行字符串搜索。

不确定您是否可以自己决定格式,但无论如何:

另一种策略是在文件的第一个位置写入一个整数值,其中包含用于ascii分区的字节数。 然后,您可以只读取该数量的字节,也可以轻松跳过ascii并直接转到二进制blob

此策略是有效的,但如果不更改计数,则无法更改ascii文本字符的数量

顺便说一句,请确保清理您的输入:不要试图读取文件中包含的更多数据,也不要分配机器无法读取的更多内存


就我个人而言,我还将使用文件的前几个字符来包含一些神奇的代码,这样您就可以对文件是否使用您的数据格式以及数据格式的版本进行最少的检查。

如果我的“开始图像”标记实际上是这样的话,这会起作用:{END}这将是5个字节;这个方法允许我搜索多个字节的字符串吗?当然可以。这只会使搜索更加复杂。查看维基百科页面上关于字符串搜索算法的链接,或者使用Scanner类。@michael:我正在尝试“Scanner”路线(不管怎样,BufferedReader)。我很难让FileInputStream开始抓取BufferedReader.readLine()关闭的字节(我先读取第一行,然后抓取下一个字节,但下一个字节不正确)。你知道怎么了吗?知道。你使用的是BufferedReader,这就是问题所在。不要。readLine()功能是缓冲的次要功能,也就是说,它以大块的形式从底层输入流中读取,因此无法在文本和图像数据之间的边界处继续。将其更改为scanner(保持代码的其余部分不变)不起作用。我也试着去掉BufferedInputStream,但也没用。它仍然在打印我使用BufferedReader时打印的字节。