【问题标题】:Breaking binary files破坏二进制文件
【发布时间】:2012-09-14 08:05:52
【问题描述】:

参考我的previous question

我用以下方法制作了程序:
程序首先从文件中读取 2k 的数据,并将其存储到一个字节数组中。
然后将要添加到每个数据包的数据也存储在一个数组中,并将两者都添加到数组列表中。 然后将数组列表写入文件的输出流。

代码在这里:

File bin=chooser.getSelectedFile();
int filesize=(int)bin.length();
int pcount=filesize/2048; 
byte[] file=new byte[filesize];
byte[] meta=new byte[12];
int arraysize=pcount*12+filesize;
byte[] rootfile=new byte[46];
ArrayList al = new ArrayList();
String root;
prbar.setVisible(true);
int mark=0;
String metas;
try{
    FileInputStream fis=new FileInputStream(bin);
    FileOutputStream fos=new FileOutputStream(bin.getName().replace(".bin", ".xyz"));
    ObjectOutputStream os=new ObjectOutputStream(fos);
    root="46kb"+"5678"+"0000"+pcount+"MYBOX"+"13"+"S208";
    rootfile=root.getBytes();
    for(int n=0;n<=pcount;n++)
    {
        fis.read(file, 0, 2048);
        mark=mark+2048;
        int v=(mark/filesize)*100;
        prbar.setValue(v);
        metas="02KB"+"1234"+n;
        meta=metas.getBytes();

        al.add(rootfile);
        al.add(meta);
        al.add(file);
    }
    os.writeObject(al.toArray());
}
catch(Exception ex){
    erlabel.setText(ex.getMessage());
}

程序运行没有任何错误,但文件未正确创建。 要么方法错误,要么代码错误。

请帮忙

【问题讨论】:

  • “未正确创建”是什么意思?结果是什么?它与预期结果有何不同?

标签: java io arraylist bytearray


【解决方案1】:

您似乎正在编写自己的二进制格式,但您使用的 ObjectOutputStream 具有自己的标头。 writeObject 以允许 Java 进程反序列化该对象的方式写入 Object 而不是数据,例如使用它的类层次结构和字段名称。

对于二进制文件,我建议您使用带有 BufferedOutputStream 的普通 DataOutputStream,这样会更高效,并且可以做您想做的事情。

我还建议您在生成数据时写入数据,而不是使用 ArrayList。这将使用更少的内存,使代码更简单,更快。


我会写成这样的代码

File bin = chooser.getSelectedFile();
int filesize = (int) bin.length();
int pcount = (filesize + 2048 - 1) / 2048;
byte[] file = new byte[2048];

FileInputStream fis = new FileInputStream(bin);
String name2 = bin.getName().replace(".bin", ".xyz");
OutputStream os = new BufferedOutputStream(new FileOutputStream(name2));
byte[] rootfile = ("46kb" + "5678" + "0000" + pcount + "MYBOX" + "13" + "S208").getBytes("UTF-8");

for (int n = 0; n < pcount; n++) {
    os.write(rootfile);
    byte[] metas = ("02KB" + "1234" + n).getBytes("UTF-8");
    os.write(metas);

    int len = fis.read(file);

    os.write(file, 0, len);
    int percent = 100 * n / pcount;
    prbar.setValue(percent);
}
ow.close();

【讨论】:

  • 仅供参考...在这部分代码中 fis.read(file, 0, 2048);标记=标记+2048; int v=(标记/文件大小)*100; prbar.setValue(v); metas="02KB"+"1234"+n;元=metas.getBytes(); al.add(根文件); al.add(元); al.add(文件);添加到列表中的第一件事是根文件,然后是元文件,然后是文件,对吗?但是当我看到文件时,所有的元字符串都在文件的末尾?为什么??
  • 您能否更新您按照我的说明删除 ObjectOutputStream 和 ArrayList 的问题中的代码?
  • 我正在使用带有 apache commons 序列化工具的数组列表。
  • 您需要确保您使用的任何库都不会使用 ObjectOutputStream 或者您不能使用它。这将解释为什么所有的元数据都在最后。这是因为 Java 序列化只发送每个对象一次,并且由于只有 meta 更改,因此只有这些会出现在末尾。
  • 我更改并删除了很多。这也会更有效率。
【解决方案2】:

从小到大:

int v=(mark/filesize)*100;

我认为使用整数除法总是产生 0。

int v = mark * 100 / filesize;

byte[] 对象(例如file)被创建一次并且多次添加到列表中。 您将获得最后一次覆盖的 n 个副本。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-21
    • 2011-09-04
    • 2012-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多