6

I have some working code in python that I need to convert to Java.

I have read quite a few threads on this forum but could not find an answer. I am reading in a JPG image and converting it into a byte array. I then write this buffer it to a different file. When I compare the written files from both Java and python code, the bytes at the end do not match. Please let me know if you have a suggestion. I need to use the byte array to pack the image into a message that needs to be sent over to a remote server.

Java code (Running on Android)

Reading the file:

File queryImg = new File(ImagePath);
int imageLen = (int)queryImg.length();
byte [] imgData = new byte[imageLen];
FileInputStream fis = new FileInputStream(queryImg);
fis.read(imgData);

Writing the file:

FileOutputStream f = new FileOutputStream(new File("/sdcard/output.raw"));
f.write(imgData);
f.flush();
f.close();

Thanks!

Dave Jarvis
  • 30,436
  • 41
  • 178
  • 315
smitten
  • 311
  • 2
  • 5
  • 13
  • Can you be more specific about what is wrong with the output? Is is the right size; which bytes are wrong; how does the Python output differ from the Java output? What exactly is the Python part doing? – Cameron Skinner Jan 11 '11 at 23:00
  • It looks like the file is not corrupted. I guess I was wrong to expect that the python windows output will be bit-exact with java-android output – smitten Jan 12 '11 at 00:43

2 Answers2

5

InputStream.read is not guaranteed to read any particular number of bytes and may read less than you asked it to. It returns the actual number read so you can have a loop that keeps track of progress:

public void pump(InputStream in, OutputStream out, int size) {
    byte[] buffer = new byte[4096]; // Or whatever constant you feel like using
    int done = 0;
    while (done < size) {
        int read = in.read(buffer);
        if (read == -1) {
            throw new IOException("Something went horribly wrong");
        }
        out.write(buffer, 0, read);
        done += read;
    }
    // Maybe put cleanup code in here if you like, e.g. in.close, out.flush, out.close
}

I believe Apache Commons IO has classes for doing this kind of stuff so you don't need to write it yourself.

Cameron Skinner
  • 51,692
  • 2
  • 65
  • 86
  • I am still seeing the same problem. I printed the return value of FileInputStream.read and it was the same as the file length. I anyway changed my code to loop to make sure that I am always reading the entire file. – smitten Jan 11 '11 at 22:55
  • Hmm. So is the output file the right size? If it is, how many bytes are being corrupted? Is it only towards the end of the file or are there problems across the whole output? – Cameron Skinner Jan 11 '11 at 22:58
  • To be very precise, I see one wrong value at 757th byte. And then, data is mostly wrong after the 876th byte! – smitten Jan 11 '11 at 23:16
  • If you are just copying the data from place to place there is no need to load the data into a buffer at all, unless you are manipulating it in some way. Just use the nio file channel interface and transferTo.... – time4tea Jan 12 '11 at 00:30
0

Your file length might be more than int can hold and than you end up having wrong array length, hence not reading entire file into the buffer.

Jasmin
  • 1
  • I am testing this code with a file of size 6406 bytes. So, at the moment, I am not running into this. Though, I should add a check for this. Thanks – smitten Jan 11 '11 at 22:55