1

我有这个程序,它从二进制文件中读取 2 Kb 数据,向它添加一些标题,然后将其写入一个新文件。
代码是

try {
        FileInputStream fis = new FileInputStream(bin);
        FileOutputStream fos = new FileOutputStream(bin.getName().replace(".bin",    ".xyz"));
        DataOutputStream dos=new DataOutputStream(fos);  
        fos.write(big, 0, big.length);
        for (int n = 1; n <= pcount; n++) {          
            fis.read(file, mark, 2048);
            mark = mark + 2048;             
            prbar.setValue(n);
            prbar.setString("Converted packets:" + String.valueOf(n));
            metas = "2048";
            meta = metas.getBytes();
            pc = String.valueOf(file.length).getBytes();
            nval = String.valueOf(n).getBytes();
            System.arraycopy(pc, 0, bmeta, 0, pc.length);
            System.arraycopy(meta, 0, bmeta, 4, meta.length);
            System.arraycopy(nval, 0, bmeta, 8, nval.length);          
            fos.write(bmeta, 0, bmeta.length);
            fos.flush();
            fos.write(file, 0, 2048);
            fos.flush();
       }
  }catch (Exception ex) {
        erlabel.setText(ex.getMessage());
  }

首先它应该写标题,然后是文件。但是输出文件中充满了不属于文件的数据。它正在写入一些垃圾数据。可能是什么问题?

4

3 回答 3

4

缺少一些声明还不太清楚,但看起来你的问题出在fis.read()方法上:第二个参数是字节数组中的偏移量,而不是文件中的偏移量(常见错误)。

您可能想使用相对读取。在写出缓冲区之前,您还需要检查返回值.read()以查看实际读取了多少字节。

常见的成语是:

InputStream is = ... 
OutputStream os = ...

byte[] buf = new byte[2048];
int len;
while((len = is.read(buf)) != -1)
  os.write(buf, 0, len);

is.close();
os.close();

编辑

这是写出元数据的一种非常奇怪的方式,我认为这就是(未使用的)DataOutputStream的用途?

您无需继续刷新输出流,只需在完成后将其关闭即可。

于 2012-10-19T04:30:14.613 回答
1

除了@Dmitri 指出的内容之外,您编写元数据的方式存在严重问题。

  1. 您每次都在循环中编写元数据,这是不对的。

  2. 您实际上是通过 为它分配 4 个字节"2048".getBytes(),然后将超过 4 个字节复制到其中,然后写入 4 个字节。这也不对,事实上它应该真的向你抛出 ArrayIndexExceptions。

  3. 看起来元数据应该包含三个二进制整数。但是,您将字符串数据放入其中。我怀疑您应该直接对这些字段使用 DataOutputStream.writeInt() ,而不是String.valueOf()/getBytes()胡说八道System.arraycopy()

于 2012-10-19T06:15:45.493 回答
0

我想建议使用lib社区支持的功能,例如apache common-ioIO。有有用的classesmethod;

org.apache.commons.io.DirectoryWalker;
org.apache.commons.io.FileUtils;
org.apache.commons.io.IOCase;

FileUtils.copyDirectory(from, to);
FileUtils.writeByteArrayToFile(file, data);
FileUtils.writeStringToFile(file, data);
FileUtils.deleteDirectory(dir);
FileUtils.forceDelete(dir);
于 2012-10-19T06:20:19.637 回答