在 Java 中读取二进制文件的特定部分

Reading specific parts of a binary file in Java

我构建了一个简单的 Java 程序来从 FRX 属性 文件中读取数据。然而,我遇到的问题是我需要能够只从文件中读取二进制文件的特定部分。更具体地说,我需要从文件中与给定十六进制值对应的值开始读取,并在给定文本字符串的 ASCII 字符停止处结束读取。

我能够使用以下程序在 C# 中执行此操作:

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

    public class GetFromFRX
    {
        public static void Main()
        {
            StringBuilder buffer = new StringBuilder();
            using (BinaryReader b = new BinaryReader(File.Open("frmResidency.frx", FileMode.Open)))
            {
                try
                {
                    b.BaseStream.Seek(641, SeekOrigin.Begin);
                    int length = b.ReadInt32();

                    for (int i = 0; i < length; i++)
                    {
                        buffer.Append(b.ReadChar());
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine( "Error obtaining resource\n" + e.Message);
                }

            }
            Console.WriteLine(buffer);
        }
    }

这是我的 Java 程序,我相信我可以使用 DataInputStream 来做我需要的事情,但是我不确定如何使用它的方法来寻找十六进制位置以开始阅读字节并正确设置长度。如果我 运行 这个当前代码我没有在我的新文本文件中写入任何输出,我希望输出超过前 10 个字节,所以我想我不明白 ReadInt()skipBytes 正确:

  import java.io.*;
  import java.util.*;

  public class Tester3 {
    public static void main(String[] args) throws IOException {

        FileInputStream in = null;
        FileOutputStream out = null;
        DataInputStream din = null;
        DataOutputStream dout = null;

        try {
            in = new FileInputStream("frmResidency.frx");
            din = new DataInputStream(in);
            out = new FileOutputStream("disisworkinlikeacharm.txt");
            dout = new DataOutputStream(out);
            din.skipBytes(10);
            int length = din.readInt();
            int c;

            for(c = 0 ; c < length; c++){
                out.write(c);
            }
        } finally {
            if (in != null) {
                in.close();
            }
            if (out != null) {
                out.close();
            }
            if (dout != null) {
                dout.close();
            }
            if (din != null) {
                din.close();
            }
        }
    }
}

我的问题是,有没有一种简单的方法可以在我的代码中实现查找某​​个十六进制位置并将二进制读取到一定长度,或者我应该使用类似 RandomAccessFile 完成这个...

使用 din.skipBytes(pos) 移动到输入中所需的偏移量。

好吧,我看到了一个问题:您正在写入 for 循环的索引变量,而不是文件中的下一个字节。您至少应该将 out.write(c) 切换为 out.write(din.)。您希望写入接下来的十个整数还是接下来的 10 个字节?假设你想写接下来的十个字节,以下对我有用:

import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Test {

    public static void main(String[] args) throws IOException {

        FileInputStream in = null;
        FileOutputStream out = null;
        try {
            in = new FileInputStream("c:\tmp\test.txt");
            DataInputStream din = new DataInputStream(in);
            out = new FileOutputStream("c:\tmp\test.out");
            DataOutputStream dout = new DataOutputStream(out);

            din.skipBytes(10);
            int length = din.readInt();
            System.out.println(length);
            int c;

            for (c = 0; c < length; c++) {
                // TODO: first read byte and check for EOF
                out.write(din.read());
            }
        } finally {
            if (in != null) {
                in.close();
            }
            if (out != null) {
                out.close();
            }
        }
    }
}

如果可以使用Java7,使用try-with-resources循环代码会少很多。此代码用于 Java 6。我只关闭文件 input/output 流,因为它们应该是维护文件句柄的流。当然,为了安全起见,您可以关闭其他流。