Reputation: 2560
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.
Upvotes: 2
Views: 3879
Reputation: 226
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);
}
}
Upvotes: 3
Reputation: 310980
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.
Upvotes: 3