HADOOP-8614. IOUtils#skipFully hangs forever on EOF. Contributed by Colin Patrick McCabe

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1375216 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Eli Collins 2012-08-20 21:10:44 +00:00
parent df5e2b8352
commit f58941f2ac
3 changed files with 55 additions and 5 deletions

View File

@ -405,6 +405,9 @@ Branch-2 ( Unreleased changes )
HADOOP-8654. TextInputFormat delimiter bug (Gelesh and Jason Lowe via HADOOP-8654. TextInputFormat delimiter bug (Gelesh and Jason Lowe via
bobby) bobby)
HADOOP-8614. IOUtils#skipFully hangs forever on EOF.
(Colin Patrick McCabe via eli)
BREAKDOWN OF HDFS-3042 SUBTASKS BREAKDOWN OF HDFS-3042 SUBTASKS
HADOOP-8220. ZKFailoverController doesn't handle failure to become active HADOOP-8220. ZKFailoverController doesn't handle failure to become active

View File

@ -206,12 +206,20 @@ public class IOUtils {
* for any reason (including EOF) * for any reason (including EOF)
*/ */
public static void skipFully(InputStream in, long len) throws IOException { public static void skipFully(InputStream in, long len) throws IOException {
while (len > 0) { long amt = len;
long ret = in.skip(len); while (amt > 0) {
if (ret < 0) { long ret = in.skip(amt);
throw new IOException( "Premature EOF from inputStream"); if (ret == 0) {
// skip may return 0 even if we're not at EOF. Luckily, we can
// use the read() method to figure out if we're at the end.
int b = in.read();
if (b == -1) {
throw new EOFException( "Premature EOF from inputStream after " +
"skipping " + (len - amt) + " byte(s).");
}
ret = 1;
} }
len -= ret; amt -= ret;
} }
} }

View File

@ -21,6 +21,8 @@ package org.apache.hadoop.io;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import java.io.ByteArrayInputStream;
import java.io.EOFException;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -175,4 +177,41 @@ public class TestIOUtils {
"Error while reading compressed data", ioe); "Error while reading compressed data", ioe);
} }
} }
@Test
public void testSkipFully() throws IOException {
byte inArray[] = new byte[] {0, 1, 2, 3, 4};
ByteArrayInputStream in = new ByteArrayInputStream(inArray);
try {
in.mark(inArray.length);
IOUtils.skipFully(in, 2);
IOUtils.skipFully(in, 2);
try {
IOUtils.skipFully(in, 2);
fail("expected to get a PrematureEOFException");
} catch (EOFException e) {
assertEquals(e.getMessage(), "Premature EOF from inputStream " +
"after skipping 1 byte(s).");
}
in.reset();
try {
IOUtils.skipFully(in, 20);
fail("expected to get a PrematureEOFException");
} catch (EOFException e) {
assertEquals(e.getMessage(), "Premature EOF from inputStream " +
"after skipping 5 byte(s).");
}
in.reset();
IOUtils.skipFully(in, 5);
try {
IOUtils.skipFully(in, 10);
fail("expected to get a PrematureEOFException");
} catch (EOFException e) {
assertEquals(e.getMessage(), "Premature EOF from inputStream " +
"after skipping 0 byte(s).");
}
} finally {
in.close();
}
}
} }