Close the file when IOException occurs in AbstractMemoryHttpData. (#10157)
Motivation: An IOException may be thrown from FileChannel.read, and cause the fd leak. Modification: Close the file when IOException occurs. Result: Avoid fd leak.
This commit is contained in:
parent
dc69c04434
commit
a2a10b9931
@ -130,15 +130,22 @@ public abstract class AbstractMemoryHttpData extends AbstractHttpData {
|
|||||||
}
|
}
|
||||||
checkSize(newsize);
|
checkSize(newsize);
|
||||||
RandomAccessFile accessFile = new RandomAccessFile(file, "r");
|
RandomAccessFile accessFile = new RandomAccessFile(file, "r");
|
||||||
FileChannel fileChannel = accessFile.getChannel();
|
ByteBuffer byteBuffer;
|
||||||
byte[] array = new byte[(int) newsize];
|
try {
|
||||||
ByteBuffer byteBuffer = ByteBuffer.wrap(array);
|
FileChannel fileChannel = accessFile.getChannel();
|
||||||
int read = 0;
|
try {
|
||||||
while (read < newsize) {
|
byte[] array = new byte[(int) newsize];
|
||||||
read += fileChannel.read(byteBuffer);
|
byteBuffer = ByteBuffer.wrap(array);
|
||||||
|
int read = 0;
|
||||||
|
while (read < newsize) {
|
||||||
|
read += fileChannel.read(byteBuffer);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
fileChannel.close();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
accessFile.close();
|
||||||
}
|
}
|
||||||
fileChannel.close();
|
|
||||||
accessFile.close();
|
|
||||||
byteBuffer.flip();
|
byteBuffer.flip();
|
||||||
if (byteBuf != null) {
|
if (byteBuf != null) {
|
||||||
byteBuf.release();
|
byteBuf.release();
|
||||||
|
@ -23,16 +23,47 @@ import io.netty.buffer.Unpooled;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
import static io.netty.util.CharsetUtil.*;
|
import static io.netty.util.CharsetUtil.*;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
/** {@link AbstractMemoryHttpData} test cases. */
|
/** {@link AbstractMemoryHttpData} test cases. */
|
||||||
public class AbstractMemoryHttpDataTest {
|
public class AbstractMemoryHttpDataTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetContentFromFile() throws Exception {
|
||||||
|
TestHttpData test = new TestHttpData("test", UTF_8, 0);
|
||||||
|
try {
|
||||||
|
File tmpFile = File.createTempFile(UUID.randomUUID().toString(), ".tmp");
|
||||||
|
tmpFile.deleteOnExit();
|
||||||
|
FileOutputStream fos = new FileOutputStream(tmpFile);
|
||||||
|
byte[] bytes = new byte[4096];
|
||||||
|
ThreadLocalRandom.current().nextBytes(bytes);
|
||||||
|
try {
|
||||||
|
fos.write(bytes);
|
||||||
|
fos.flush();
|
||||||
|
} finally {
|
||||||
|
fos.close();
|
||||||
|
}
|
||||||
|
test.setContent(tmpFile);
|
||||||
|
ByteBuf buf = test.getByteBuf();
|
||||||
|
assertEquals(buf.readerIndex(), 0);
|
||||||
|
assertEquals(buf.writerIndex(), bytes.length);
|
||||||
|
assertArrayEquals(bytes, test.get());
|
||||||
|
assertArrayEquals(bytes, ByteBufUtil.getBytes(buf));
|
||||||
|
} finally {
|
||||||
|
//release the ByteBuf
|
||||||
|
test.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Provide content into HTTP data with input stream.
|
* Provide content into HTTP data with input stream.
|
||||||
*
|
*
|
||||||
@ -45,15 +76,13 @@ public class AbstractMemoryHttpDataTest {
|
|||||||
String contentStr = "foo_test";
|
String contentStr = "foo_test";
|
||||||
ByteBuf buf = Unpooled.wrappedBuffer(contentStr.getBytes(UTF_8));
|
ByteBuf buf = Unpooled.wrappedBuffer(contentStr.getBytes(UTF_8));
|
||||||
int readerIndex = buf.readerIndex();
|
int readerIndex = buf.readerIndex();
|
||||||
ByteBufInputStream is = new ByteBufInputStream(buf);
|
|
||||||
try {
|
try (ByteBufInputStream is = new ByteBufInputStream(buf)) {
|
||||||
test.setContent(is);
|
test.setContent(is);
|
||||||
assertFalse(buf.isReadable());
|
assertFalse(buf.isReadable());
|
||||||
assertEquals(test.getString(UTF_8), contentStr);
|
assertEquals(test.getString(UTF_8), contentStr);
|
||||||
buf.readerIndex(readerIndex);
|
buf.readerIndex(readerIndex);
|
||||||
assertTrue(ByteBufUtil.equals(buf, test.getByteBuf()));
|
assertTrue(ByteBufUtil.equals(buf, test.getByteBuf()));
|
||||||
} finally {
|
|
||||||
is.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Random random = new SecureRandom();
|
Random random = new SecureRandom();
|
||||||
|
Loading…
Reference in New Issue
Block a user