lazyprogrammer
lazyprogrammer

Reputation: 629

FileOutputStream:Something That I am Missing Out?

I have this program that reads 2 Kb Data from a binary file adds some header to it and then writes it to a new file.
The code is

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

First it should write the header and then the file.But the output file is full of data that does not belong to the file.It is writing some garbage data.What may be the problem?

Upvotes: 1

Views: 1075

Answers (3)

Zaw Than oo
Zaw Than oo

Reputation: 9935

I would like suggest to use lib community supported like apache common-io for IO features. There are usefule classes and method;

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

Upvotes: 0

user207421
user207421

Reputation: 311050

In addition to what @Dmitri has pointed out, there is something seriously wrong with the way you are writing the metadata.

  1. You are writing the metadata every time around the loop, which cannot be right.

  2. You are essentially allocating 4 bytes for it, via "2048".getBytes(), then copying many more than 4 bytes into it, then writing the 4 bytes. This cannot be right either, in fact it should really be throwing ArrayIndexExceptions at you.

  3. It looks as though the metadata is supposed to contain three binary integers. However you are putting String data into it. I suspect you should be using DataOutputStream.writeInt() directly for these fields, without all the String.valueOf()/getBytes() and System.arraycopy() nonsense.

Upvotes: 1

Dmitri
Dmitri

Reputation: 9157

It's not quite clear with some of the declarations missing, but it looks like your problem is with the fis.read() method: the second argument is an offset in the byte array, not the file (common mistake).

You probably want to use relative reads. You also need to check the return value from .read() to see how many bytes were actually read, before writing the buffer out.

The common idiom is:

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

Edit

That's a pretty weird way of writing out your metadata, I assume that's what the (unused) DataOutputStream is for?

You don't need to keep flushing the output stream, just close it when you're done.

Upvotes: 4

Related Questions