【发布时间】:2015-01-26 16:09:09
【问题描述】:
所以我有一些 FRX 二进制文件,我试图使用 Java 的二进制读取方法从中获取字符串标题。
我有能力这样做,并使用以下程序指定在 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 中做同样的事情,我构建了以下程序。现在我已经实现了 Guava 以使用 LittleEndian 等价物,但是现在我的长度打印为 24,因此我只得到输出文件中的前 24 个字节。 ReadInt 是否不适合这种情况,并且功能与ReadInt32 不同?
import java.io.*;
import com.google.common.io.*;
public class RealJavaByteReader {
public static void main(String[] args) throws IOException {
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("frmResidency.frx");
LittleEndianDataInputStream din = new LittleEndianDataInputStream(in);
out = new FileOutputStream("output.txt");
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();
}
}
}
}
【问题讨论】:
-
Seek是干什么用的? -
尝试实例化一个缓冲区,如 byte[] buffer = new byte[4];然后使用 out.read(buffer);将字节读入缓冲区。然后,您可以使用 System.out.println(DatatypeConverter.printHexBinary(buffer)); 打印缓冲区的内容。检查缓冲区的内容以查看您是否前进到正确的位置。在十六进制编辑器中打开它也可能会有所帮助。听起来您正在读取的 int 的第一个字节的前导位已设置。如果您希望更大的数据适合带符号的 int,您可能需要读取 4 个字节并手动转换为 long...
-
在 C# 中,
Seek正在设置我的索引的起始位置,这是对应于十六进制值的十进制值,表示我需要的字符串标题的开始字节。 -
DataInput.readInt采用大端格式;BinaryReader.ReadInt32采用 little-endian 格式...所以这是 start 的问题。在您至少获得合适的长度之前,我不会再进一步。 -
另外,在 C# 中,您将字符值写入
StringBuilder,而在 Java 中,您将字节值写入文件。您似乎也没有对dout做任何事情。
标签: java c# binary byte fileinputstream