与C#相比,从Java获取错误的字节数
所以我有一些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
不同的方式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(); } } } }
Elizion,
这可能是因为您可能正在读取使用little endian存储的int。 因此,Java使用Big endian和.NET little endian。
使用如下函数将一个小端int转换为java中的big endian int。
/** * Byte swap a single int value. * * @param value Value to byte swap. * @return Byte swapped representation. */ public static int swap (int value) { int b1 = (value >> 0) & 0xff; int b2 = (value >> 8) & 0xff; int b3 = (value >> 16) & 0xff; int b4 = (value >> 24) & 0xff; return b1 << 24 | b2 << 16 | b3 << 8 | b4 << 0; }
请尝试查看以下post。
将Little Endian转换为Big Endian
我意识到我的错误在这一点上。 现在已经实现了LittleEndianDataInputStream
,我可以正确地使用SkipBytes
来设置我的初始字节位置,并将根据需要返回字符串标题。 当然,我最初只生成前24个字节,因为对于FRX文件中的某些给定属性,二进制文件的前4个字节中的任何内容必须保持24的长度。 我必须使用skipBytes
设置偏移量以生成任何有意义的内容,因为FRX文件中的属性长度存储在4个字节的组中,后面跟着包含该属性的字节。
例如,如果我设置din.skipBytes(308);
,然后FRX文件中的第308到第312个字节保存字符串的字节长度,我需要的Caption属性(例如140),由readInt
输出。 因此接下来的140个字节将包含我需要的字符串,而我的for
循环将正确迭代。