Hi,

I'll quickly explain what i am trying to do before telling the problem i am facing.

Requirement:

  1. Store the contents of a file into an object.
  2. Send the object through HTTP socket to another client server.
  3. Have the server fetch the file contents from the object.
  4. Compress it.
  5. Store the compressed file's content back into the object.
  6. Send the new object back to the server.
  7. Server fetched the compressed file contents from the recieved object and writes to a zip file

Problem:

The final output file [the zip file] is corrupted. On opening it comes up as an invalid archive.

Observations:

The problem seems to be in how i store the file contents in the object.
This is because the client, while compressing, creates a temp zip file which it then reads and stores into the object.
This temporary file was a valid zip, but the contents seemed to be corrupted.

Code Snippets

I am currently storing the file contents as a String in the object.
Getting the file contents into the string like the following:

        fileContents = FileUtils.readFileToString(new File(path), Charset.forName("UTF-8"));

Sending the object over the socket using :

        outStream.writeObject(msg);
        outStream.flush();

where outStream is an ObjectOutputStream.

Reading the object on the client using ObjectInputStream :

        Job job = (Job) in.readObject();

Compressing using the following :

        FileOutputStream fos = new FileOutputStream(job.getFileName() + ".zip");
        ZipOutputStream zos = new ZipOutputStream(fos);
        ZipEntry ze= new ZipEntry(job.getFileName());
        zos.putNextEntry(ze);

        byte[] bytes = job.getFileContents().getBytes(Charset.forName("UTF-8"));
        zos.write(bytes,0,bytes.length);

        zos.closeEntry();
        zos.close();

Using similar techniques to store the compressed file contents back to the object, send it and recieve it back at the server side.

After recieveing the object, the contents are written to a file likewise :

        FileOutputStream fOut = new FileOutputStream(newFile);
        byte[] bytes = completedJob.getFileContents().getBytes(Charset.forName("UTF-8"));
        fOut.write(bytes);
        fOut.close();

Any help would be greatly appreciated.

Thanks,
Aravind

Recommended Answers

All 3 Replies

You haven't posted all the relevant code, but using String and getBytes(Charset...) is the wrong way to go when you need to read and write raw bytes from/to a stream. Using any kind of String or Charset will result in bytes being interpreted and replaced according to their character equivalences in whatever character set. You need to be reading and writing uninterpreted bytes, eg by using InputStream and read(byte[] b) and OutputStream and write(byte[] b)

Hi,

By talking about the missing relevent code if you meant about the FileUtils, then its the Apache Commons IO FileUtils. If there is anything else you were looking for, please let me know. I'll put it here.

Anyway, i removed all the Charsets mentioned.

So code is now kind of like this :

    byte[] bytes = completedJob.getFileContents().getBytes();
    fOut.write(bytes);

But still i get the same error. Nothing seemed to have changed. And I didn't get the part about using InputStream and OutputStream. I couldn't find a way to read a String through a stream.

Any views on this?

Thanks,
Aravind Suresh

Onca again: Your zip file needs to be read and written directly as bytes without any kind of conversion or interpretation. Using Strings will always involve some kind of conversion or interpretation, and will corrupt your file contents. Get rid of the Strings completely. Read/write the zip file contents into/from an array of bytes directly.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.