2

I'm trying to read an XML file out of a ZIP archive. The relevant code is below:

ZipInputStream zis = new ZipInputStream(is);
ZipEntry entry = zis.getNextEntry();
while(entry != null) {
    if(entry.getName().equals("plugin.xml")) {
        int size = (int)entry.getSize();
        byte[] bytes = new byte[size];
        int read = zis.read(bytes, 0, size);

        System.out.println("File size: " + size);
        System.out.println("Bytes read: " + read);
    }
}

This, when working produces output as follows:

File size: 5224
Bytes read: 5224

The plugin.xml file being read is nothing special, and passes any XML validation I can find, however, minor changes to the XML file (deleting characters, adding characters, etc.) sometimes causes a situation where the "bytes read" from the input stream is less than the file size. In this case, I changed the text value of an XML attribute of the same file as above and got the following result:

File size: 5218
Bytes read: 5205 // the reader stopped early!

I cannot see any pattern in terms of which XML files will work and which won't. It seems to be completely random.

Has anyone come across anything like this before?

Edit: Forgot to mention, the Java code which reads in the plugin.xml file is embedded in an off-the-shelf application which I cannot change. My issue is trying to understand why it won't accept my XML file in some cases.

WayneC
  • 2,530
  • 3
  • 31
  • 44

2 Answers2

3

Where does it say that InputStream.read(), or any of its implementations or overrides, fills the buffer? Check the Javadoc. What is actually says is that read() either returns -1 indicating EOS or reads at least one byte into the buffer. You have to loop.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • Unfortunately, the code that reads the XML file from the ZIP is part of a vendor application that I can't change. I'm trying to understand why my XML file gets completely read sometimes and sometimes not. There does not seem to be a pattern. – WayneC Nov 01 '12 at 23:11
  • @WayneC Then complain to the vendor. If that's their code, it is wrong. It would never work over a socket, for example. The 'pattern' is that there is nothing in the Java API that requires it to work, so if it ever works at all it is a miracle. – user207421 Nov 05 '12 at 00:25
  • Turns out they had a patch for this exact issue. The piece I was missing was that if the compressed size of the file was less than the buffer size it would work. – WayneC Nov 06 '12 at 20:52
3

As was mentioned before, you need to use a loop. I had to solve this exact problem, so I figured I would post an example.

ZipInputStream zis = new ZipInputStream(is);
ZipEntry entry = zis.getNextEntry();
while(entry != null) {
    if(entry.getName().equals("plugin.xml")) {
        int size = (int)entry.getSize();
        byte[] bytes = new byte[size];
        int read = 0;
        while (read < size) {
            read += zis.read(bytes, read, (size - read));
        }

        System.out.println("File size: " + size);
        System.out.println("Bytes read: " + read);
    }
}
Brian Williams
  • 226
  • 1
  • 2