有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java中的资源文件格式处理

我正在尝试用Java为特定的资源归档文件格式实现一个处理器。该格式有一个Header由三个char描述、一个伪字节和一个指示文件数量的字节组成

然后,每个文件都有一个条目,由一个伪字节、一个描述文件名的12-char字符串、一个伪字节和一个在三字节数组中声明的偏移量组成

阅读这种结构的合适课程是什么?我已经尝试了RandomAccessFile,但它不允许读取数据数组,例如,通过调用readChar()三次,我只能读取三个char,等等

当然我可以扩展RandomAccessFile来做我想做的事情,但是必须有一个合适的现成类来做这种处理,不是吗

这是我的C#标题阅读器:

protected override void ReadHeader()
{
    Header = new string(this.BinaryReader.ReadChars(3));
    byte dummy = this.BinaryReader.ReadByte();
    NFiles = this.BinaryReader.ReadByte();
}

共 (2) 个答案

  1. # 1 楼答案

    我认为你的C代码很幸运,因为它依赖于在其他地方设置的字符编码,如果它与文件中每个字符的字节数不匹配,你的代码可能会失败

    在Java中实现这一点最安全的方法是严格读取字节并自己进行字符转换。如果您需要搜索功能,那么RandomAccessFile确实是最简单的解决方案,但是应该指出InputStream允许跳过,因此如果您不需要实际的随机访问,只需要跳过一些文件,您当然可以使用它

    在任何一种情况下,您都应该按照文件规范从文件中读取字节,然后根据已知编码将它们转换为字符。您永远不应该相信不是由Java程序编写的文件包含除byte之外的任何Java数据类型,即使它是由Java编写的,也可能在编写时被转换为原始字节

    因此,您的代码应该大致如下:

    String header = "";
    int nFiles = 0;
    
    RandomAccessFile raFile = new RandomAccessFile( "filename", "r" );
    
    byte[] buffer = new byte[3];
    int numRead = raFile.read( buffer ); 
    header = new String( buffer, StandardCharsets.US_ASCII.name() );
    
    int numSkipped = raFile.skipBytes(1);
    
    nFiles = raFile.read(); // The byte is read as an integer between 0 and 255
    

    健全性检查(检查实际读取了3个字节,跳过了1个字节,并且nFiles不是-1)和异常处理已被跳过,以简洁起见

    如果使用InputStream,则大致相同

  2. # 2 楼答案

    我会和^{}一起去。这将允许您任意搜索,但也将高效、透明地处理太大而无法轻松放入RAM中的大型文件

    在我看来,这是从文件中读取这样的结构化二进制数据的最佳方法

    然后,您可以在此基础上构建自己的数据结构,以处理特定的文件格式