简体   繁体   English

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

[英]Reading specific parts of a binary file in Java

I have built a simple Java program to read data from FRX property files. 我建立了一个简单的Java程序来从FRX属性文件中读取数据。 The issue I am having however, is I need to be able to only read a certain part of the binary from the file. 但是,我要解决的问题是我只能从文件中读取二进制文件的特定部分。 More specifically, I need to begin reading from the file at the value corresponding to a given hex value, and end reading where the ASCII characters stop for that given string of text. 更具体地说,我需要从文件开始读取对应于给定十六进制值的值,并结束读取该给定文本字符串的ASCII字符的位置。

I was capable of doing this in C# using the following program : 我能够使用以下程序在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);
        }
    }

And this is my Java program, with which I believe I can just use DataInputStream to do what I need, however I'm unsure of how to use its methods to seek a hex position to start reading bytes and set the length properly. 这是我的Java程序,我相信可以使用DataInputStream来执行所需的操作,但是我不确定如何使用其方法来查找十六进制位置以开始读取字节并正确设置长度。 If I run this current code I get no output written in my new text file, where I would expect to just get the output past the first 10 bytes, so I think I don't understand ReadInt() or skipBytes correctly: 如果运行此当前代码,我的新文本文件中将没有任何输出,我希望在该文本文件中仅获得前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();
            }
        }
    }
}

My question is , is there an easy way to implement seeking a certain hex position and reading binary to a length in my code, or should I be using something like RandomAccessFile to accomplish this... 我的问题是 ,是否有一种简单的方法可以实现在我的代码中查找特定的十六进制位置并读取二进制文件的长度,还是应该使用RandomAccessFile之类的方法来实现此目的?

Well I see one issue: you are writing the index variable of the for loop instead of the next byte from the file. 好吧,我看到一个问题:您正在编写for循环的索引变量,而不是文件中的下一个字节。 You should at the very least switch out.write(c) to out.write(din.). 您至少应该将out.write(c)切换到out.write(din。)。 Do you expect to write the next ten integers or the next 10 bytes? 您希望写下十个整数还是下十个字节? Assuming you want to write the next ten bytes, the following works for me: 假设您要写入接下来的十个字节,以下内容对我有用:

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();
            }
        }
    }
}

If you can use Java 7, it is a lot less code to use a try-with-resources loop. 如果可以使用Java 7,则使用try-with-resources循环的代码要少得多。 This code was for Java 6. I am only closing the File input/output streams since they should be the ones maintaining the file handles. 这段代码是针对Java 6的。我仅关闭文件输入/输出流,因为它们应该是维护文件句柄的流。 You could close the other streams to be on the safe side of course. 当然,您可以关闭其他流以确保安全。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM