tags:

views:

1342

answers:

6

This problem seems to happen inconsistently. We are using a java applet to download a file from our site, which we store temporarily on the client's machine.

Here is the code that we are using to save the file:

URL targetUrl = new URL(urlForFile);
InputStream content = (InputStream)targetUrl.getContent();
BufferedInputStream buffered = new BufferedInputStream(content);
File savedFile = File.createTempFile("temp",".dat");

FileOutputStream fos = new FileOutputStream(savedFile);
int letter;
while((letter = buffered.read()) != -1)
    fos.write(letter);
fos.close();

Later, I try to access that file by using:

ObjectInputStream keyInStream = new ObjectInputStream(new FileInputStream(savedFile));

Most of the time it works without a problem, but every once in a while we get the error:

java.io.StreamCorruptedException: invalid stream header: 0D0A0D0A

which makes me believe that it isn't saving the file correctly.

A: 

What do you mean by "later"? Is the "later" possibly in a separate thread? Are you sure the file has finished being written by then?

Michael Sharek
+4  A: 

I'm guessing that the operations you've done with getContent and BufferedInputStream have treated the file like an ascii file which has converted newlines or carriage returns into carriage return + newline (0x0d0a), which has confused ObjectInputStream (which expects serialized data objects.

Paul Tomblin
Anything ending in -Stream deals exclusively with bytes, i.e. does not even have a concept of lines, and will not transform the input in any text-related way.
Michael Borgwardt
+1  A: 

If you are using an FTP URL, the transfer may be occurring in ASCII mode.

Try appending ";type=I" to the end of your URL.

Darron
+1  A: 

Why are you using ObjectInputStream to read it?

As per the javadoc:

An ObjectInputStream deserializes primitive data and objects previously written using an ObjectOutputStream.

Probably the error comes from the fact you didn't write it with ObjectOutputStream.

Try reading it wit FileInputStream only.

Here's a sample for binary ( although not the most efficient way )

Here's another used for text files.

OscarRyz
A: 

You could also step back from the code and check to see if the file on your client is the same as the file on the server. If you get both files on an XP machine, you should be able to use the FC utility to do a compare (check FC's help if you need to run this as a binary compare as there is a switch for that). If you're on Unix, I don't know the file compare program, but I'm sure there's something.

If the files are identical, then you're looking at a problem with the code that reads the file.

If the files are not identical, focus on the code that writes your file.

Good luck!

Michael Debro
+1  A: 

There are 3 big problems in your sample code:

  1. You're not just treating the input as bytes
  2. You're needlessly pulling the entire object into memory at once
  3. You're doing multiple method calls for every single byte read and written -- use the array based read/write!

Here's a redo:

URL targetUrl = new URL(urlForFile);
InputStream is = targetUrl.getInputStream();
File savedFile = File.createTempFile("temp",".dat");
FileOutputStream fos = new FileOutputStream(savedFile);

int count;
byte[] buff = new byte[16 * 1024];
while((count = is.read(buff)) != -1) {
    fos.write(buff, 0, count);
}
fos.close();
content.close();
Ry4an