Browse Source

Don't use java.nio channel for file size determination

Java NIO has some problems (like files closing unexpectedly because the
thread was interrupted). To avoid those problems, don't use a NIO
channel to determine the size of a file, but rather ask the File itself.

We have to be prepared to handle wrong/outdated information in this case
too, as the inode of the File may change between opening and determining
file size.

Change-Id: Ic7aa6c3337480879efcce4a3058b548cd0e2cef0
stable-2.0
Markus Duft 13 years ago
parent
commit
2ba67bedae
  1. 32
      org.eclipse.jgit/src/org/eclipse/jgit/util/IO.java

32
org.eclipse.jgit/src/org/eclipse/jgit/util/IO.java

@ -137,12 +137,38 @@ public class IO {
throws FileNotFoundException, IOException { throws FileNotFoundException, IOException {
final FileInputStream in = new FileInputStream(path); final FileInputStream in = new FileInputStream(path);
try { try {
final long sz = in.getChannel().size(); long sz = Math.max(path.length(), 1);
if (sz > max) if (sz > max)
throw new IOException(MessageFormat.format( throw new IOException(MessageFormat.format(
JGitText.get().fileIsTooLarge, path)); JGitText.get().fileIsTooLarge, path));
final byte[] buf = new byte[(int) sz];
IO.readFully(in, buf, 0); byte[] buf = new byte[(int) sz];
int valid = 0;
for (;;) {
if (buf.length == valid) {
if (buf.length == max) {
int next = in.read();
if (next < 0)
break;
throw new IOException(MessageFormat.format(
JGitText.get().fileIsTooLarge, path));
}
byte[] nb = new byte[Math.min(buf.length * 2, max)];
System.arraycopy(buf, 0, nb, 0, valid);
buf = nb;
}
int n = in.read(buf, valid, buf.length - valid);
if (n < 0)
break;
valid += n;
}
if (valid < buf.length) {
byte[] nb = new byte[valid];
System.arraycopy(buf, 0, nb, 0, valid);
buf = nb;
}
return buf; return buf;
} finally { } finally {
try { try {

Loading…
Cancel
Save