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
ea31b59037
commit
d4c268ae3e
@ -132,15 +132,22 @@ public abstract class AbstractMemoryHttpData extends AbstractHttpData {
|
||||
}
|
||||
checkSize(newsize);
|
||||
RandomAccessFile accessFile = new RandomAccessFile(file, "r");
|
||||
FileChannel fileChannel = accessFile.getChannel();
|
||||
byte[] array = new byte[(int) newsize];
|
||||
ByteBuffer byteBuffer = ByteBuffer.wrap(array);
|
||||
int read = 0;
|
||||
while (read < newsize) {
|
||||
read += fileChannel.read(byteBuffer);
|
||||
ByteBuffer byteBuffer;
|
||||
try {
|
||||
FileChannel fileChannel = accessFile.getChannel();
|
||||
try {
|
||||
byte[] array = new byte[(int) newsize];
|
||||
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();
|
||||
if (byteBuf != null) {
|
||||
byteBuf.release();
|
||||
|
@ -19,22 +19,51 @@ import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufInputStream;
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.buffer.UnpooledByteBufAllocator;
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
import static io.netty.util.CharsetUtil.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/** {@link AbstractMemoryHttpData} test cases. */
|
||||
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];
|
||||
PlatformDependent.threadLocalRandom().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.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user