Close the file in case of an IOException in AbstractMemoryHttpData.renameTo. (#10163)
Motivation: An `IOException` may be thrown from `FileChannel.write` or `FileChannel.force`, and cause the fd leak. Modification: Close the file in a finally block. Result: Avoid fd leak.
This commit is contained in:
parent
7402a3a55a
commit
3808777c32
@ -235,24 +235,29 @@ public abstract class AbstractMemoryHttpData extends AbstractHttpData {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
int length = byteBuf.readableBytes();
|
int length = byteBuf.readableBytes();
|
||||||
RandomAccessFile accessFile = new RandomAccessFile(dest, "rw");
|
|
||||||
FileChannel fileChannel = accessFile.getChannel();
|
|
||||||
int written = 0;
|
int written = 0;
|
||||||
if (byteBuf.nioBufferCount() == 1) {
|
RandomAccessFile accessFile = new RandomAccessFile(dest, "rw");
|
||||||
ByteBuffer byteBuffer = byteBuf.nioBuffer();
|
try {
|
||||||
while (written < length) {
|
FileChannel fileChannel = accessFile.getChannel();
|
||||||
written += fileChannel.write(byteBuffer);
|
try {
|
||||||
}
|
if (byteBuf.nioBufferCount() == 1) {
|
||||||
} else {
|
ByteBuffer byteBuffer = byteBuf.nioBuffer();
|
||||||
ByteBuffer[] byteBuffers = byteBuf.nioBuffers();
|
while (written < length) {
|
||||||
while (written < length) {
|
written += fileChannel.write(byteBuffer);
|
||||||
written += fileChannel.write(byteBuffers);
|
}
|
||||||
|
} else {
|
||||||
|
ByteBuffer[] byteBuffers = byteBuf.nioBuffers();
|
||||||
|
while (written < length) {
|
||||||
|
written += fileChannel.write(byteBuffers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fileChannel.force(false);
|
||||||
|
} finally {
|
||||||
|
fileChannel.close();
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
accessFile.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
fileChannel.force(false);
|
|
||||||
fileChannel.close();
|
|
||||||
accessFile.close();
|
|
||||||
return written == length;
|
return written == length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ import org.junit.Test;
|
|||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
@ -64,6 +65,43 @@ public class AbstractMemoryHttpDataTest {
|
|||||||
test.delete();
|
test.delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRenameTo() throws Exception {
|
||||||
|
TestHttpData test = new TestHttpData("test", UTF_8, 0);
|
||||||
|
try {
|
||||||
|
File tmpFile = File.createTempFile(UUID.randomUUID().toString(), ".tmp");
|
||||||
|
tmpFile.deleteOnExit();
|
||||||
|
final int totalByteCount = 4096;
|
||||||
|
byte[] bytes = new byte[totalByteCount];
|
||||||
|
ThreadLocalRandom.current().nextBytes(bytes);
|
||||||
|
ByteBuf content = Unpooled.wrappedBuffer(bytes);
|
||||||
|
test.setContent(content);
|
||||||
|
boolean succ = test.renameTo(tmpFile);
|
||||||
|
assertTrue(succ);
|
||||||
|
FileInputStream fis = new FileInputStream(tmpFile);
|
||||||
|
try {
|
||||||
|
byte[] buf = new byte[totalByteCount];
|
||||||
|
int count = 0;
|
||||||
|
int offset = 0;
|
||||||
|
int size = totalByteCount;
|
||||||
|
while ((count = fis.read(buf, offset, size)) > 0) {
|
||||||
|
offset += count;
|
||||||
|
size -= count;
|
||||||
|
if (offset >= totalByteCount || size <= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertArrayEquals(bytes, buf);
|
||||||
|
assertEquals(0, fis.available());
|
||||||
|
} finally {
|
||||||
|
fis.close();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
//release the ByteBuf in AbstractMemoryHttpData
|
||||||
|
test.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Provide content into HTTP data with input stream.
|
* Provide content into HTTP data with input stream.
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user