Skip to content

Commit

Permalink
Avoid creating FileInputStream and FileOutputStream for obtaining Fil… (
Browse files Browse the repository at this point in the history
netty#8110)

Motivation:

If all we need is the FileChannel we should better use RandomAccessFile as FileInputStream and FileOutputStream use a finalizer.

Modifications:

Replace FileInputStream and FileOutputStream with RandomAccessFile when possible.

Result:

Fixes netty#8078.
  • Loading branch information
normanmaurer authored Aug 17, 2019
1 parent 97361fa commit d8e59ca
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,8 @@

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.ReadOnlyBufferException;
import java.nio.channels.FileChannel;
Expand Down Expand Up @@ -307,12 +306,12 @@ public void testWrapMemoryMapped() throws Exception {
ByteBuf b2 = null;

try {
output = new FileOutputStream(file).getChannel();
output = new RandomAccessFile(file, "rw").getChannel();
byte[] bytes = new byte[1024];
PlatformDependent.threadLocalRandom().nextBytes(bytes);
output.write(ByteBuffer.wrap(bytes));

input = new FileInputStream(file).getChannel();
input = new RandomAccessFile(file, "r").getChannel();
ByteBuffer m = input.map(FileChannel.MapMode.READ_ONLY, 0, input.size());

b1 = buffer(m);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,9 @@
import io.netty.util.internal.logging.InternalLoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
Expand Down Expand Up @@ -125,9 +124,10 @@ public void setContent(ByteBuf buffer) throws IOException {
}
return;
}
FileOutputStream outputStream = new FileOutputStream(file);
RandomAccessFile accessFile = new RandomAccessFile(file, "rw");
accessFile.setLength(0);
try {
FileChannel localfileChannel = outputStream.getChannel();
FileChannel localfileChannel = accessFile.getChannel();
ByteBuffer byteBuffer = buffer.nioBuffer();
int written = 0;
while (written < size) {
Expand All @@ -136,7 +136,7 @@ public void setContent(ByteBuf buffer) throws IOException {
buffer.readerIndex(buffer.readerIndex() + written);
localfileChannel.force(false);
} finally {
outputStream.close();
accessFile.close();
}
setCompleted();
} finally {
Expand All @@ -163,8 +163,8 @@ public void addContent(ByteBuf buffer, boolean last)
file = tempFile();
}
if (fileChannel == null) {
FileOutputStream outputStream = new FileOutputStream(file);
fileChannel = outputStream.getChannel();
RandomAccessFile accessFile = new RandomAccessFile(file, "rw");
fileChannel = accessFile.getChannel();
}
while (written < localsize) {
written += fileChannel.write(byteBuffer);
Expand All @@ -182,8 +182,8 @@ public void addContent(ByteBuf buffer, boolean last)
file = tempFile();
}
if (fileChannel == null) {
FileOutputStream outputStream = new FileOutputStream(file);
fileChannel = outputStream.getChannel();
RandomAccessFile accessFile = new RandomAccessFile(file, "rw");
fileChannel = accessFile.getChannel();
}
fileChannel.force(false);
fileChannel.close();
Expand Down Expand Up @@ -217,10 +217,11 @@ public void setContent(InputStream inputStream) throws IOException {
delete();
}
file = tempFile();
FileOutputStream outputStream = new FileOutputStream(file);
RandomAccessFile accessFile = new RandomAccessFile(file, "rw");
accessFile.setLength(0);
int written = 0;
try {
FileChannel localfileChannel = outputStream.getChannel();
FileChannel localfileChannel = accessFile.getChannel();
byte[] bytes = new byte[4096 * 4];
ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
int read = inputStream.read(bytes);
Expand All @@ -232,7 +233,7 @@ public void setContent(InputStream inputStream) throws IOException {
}
localfileChannel.force(false);
} finally {
outputStream.close();
accessFile.close();
}
size = written;
if (definedSize > 0 && definedSize < size) {
Expand Down Expand Up @@ -290,8 +291,8 @@ public ByteBuf getChunk(int length) throws IOException {
return EMPTY_BUFFER;
}
if (fileChannel == null) {
FileInputStream inputStream = new FileInputStream(file);
fileChannel = inputStream.getChannel();
RandomAccessFile accessFile = new RandomAccessFile(file, "r");
fileChannel = accessFile.getChannel();
}
int read = 0;
ByteBuffer byteBuffer = ByteBuffer.allocate(length);
Expand Down Expand Up @@ -349,15 +350,15 @@ public boolean renameTo(File dest) throws IOException {
if (!file.renameTo(dest)) {
// must copy
IOException exception = null;
FileInputStream inputStream = null;
FileOutputStream outputStream = null;
RandomAccessFile inputAccessFile = null;
RandomAccessFile outputAccessFile = null;
long chunkSize = 8196;
long position = 0;
try {
inputStream = new FileInputStream(file);
outputStream = new FileOutputStream(dest);
FileChannel in = inputStream.getChannel();
FileChannel out = outputStream.getChannel();
inputAccessFile = new RandomAccessFile(file, "r");
outputAccessFile = new RandomAccessFile(dest, "rw");
FileChannel in = inputAccessFile.getChannel();
FileChannel out = outputAccessFile.getChannel();
while (position < size) {
if (chunkSize < size - position) {
chunkSize = size - position;
Expand All @@ -367,9 +368,9 @@ public boolean renameTo(File dest) throws IOException {
} catch (IOException e) {
exception = e;
} finally {
if (inputStream != null) {
if (inputAccessFile != null) {
try {
inputStream.close();
inputAccessFile.close();
} catch (IOException e) {
if (exception == null) { // Choose to report the first exception
exception = e;
Expand All @@ -378,9 +379,9 @@ public boolean renameTo(File dest) throws IOException {
}
}
}
if (outputStream != null) {
if (outputAccessFile != null) {
try {
outputStream.close();
outputAccessFile.close();
} catch (IOException e) {
if (exception == null) { // Choose to report the first exception
exception = e;
Expand Down Expand Up @@ -422,17 +423,17 @@ private static byte[] readFrom(File src) throws IOException {
throw new IllegalArgumentException(
"File too big to be loaded in memory");
}
FileInputStream inputStream = new FileInputStream(src);
RandomAccessFile accessFile = new RandomAccessFile(src, "r");
byte[] array = new byte[(int) srcsize];
try {
FileChannel fileChannel = inputStream.getChannel();
FileChannel fileChannel = accessFile.getChannel();
ByteBuffer byteBuffer = ByteBuffer.wrap(array);
int read = 0;
while (read < srcsize) {
read += fileChannel.read(byteBuffer);
}
} finally {
inputStream.close();
accessFile.close();
}
return array;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@
import io.netty.handler.codec.http.HttpConstants;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
Expand Down Expand Up @@ -131,16 +130,16 @@ public void setContent(File file) throws IOException {
throw new IllegalArgumentException("File too big to be loaded in memory");
}
checkSize(newsize);
FileInputStream inputStream = new FileInputStream(file);
FileChannel fileChannel = inputStream.getChannel();
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);
}
fileChannel.close();
inputStream.close();
accessFile.close();
byteBuffer.flip();
if (byteBuf != null) {
byteBuf.release();
Expand Down Expand Up @@ -232,8 +231,8 @@ public boolean renameTo(File dest) throws IOException {
return true;
}
int length = byteBuf.readableBytes();
FileOutputStream outputStream = new FileOutputStream(dest);
FileChannel fileChannel = outputStream.getChannel();
RandomAccessFile accessFile = new RandomAccessFile(dest, "rw");
FileChannel fileChannel = accessFile.getChannel();
int written = 0;
if (byteBuf.nioBufferCount() == 1) {
ByteBuffer byteBuffer = byteBuf.nioBuffer();
Expand All @@ -249,7 +248,7 @@ public boolean renameTo(File dest) throws IOException {

fileChannel.force(false);
fileChannel.close();
outputStream.close();
accessFile.close();
return written == length;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
import io.netty.channel.FileRegion;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;

/**
Expand All @@ -45,7 +45,7 @@ public class ChunkedNioFile implements ChunkedInput<ByteBuf> {
* Creates a new instance that fetches data from the specified file.
*/
public ChunkedNioFile(File in) throws IOException {
this(new FileInputStream(in).getChannel());
this(new RandomAccessFile(in, "r").getChannel());
}

/**
Expand All @@ -55,7 +55,7 @@ public ChunkedNioFile(File in) throws IOException {
* {@link #readChunk(ChannelHandlerContext)} call
*/
public ChunkedNioFile(File in, int chunkSize) throws IOException {
this(new FileInputStream(in).getChannel(), chunkSize);
this(new RandomAccessFile(in, "r").getChannel(), chunkSize);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@
import org.junit.Test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.WritableByteChannel;
import java.util.Random;
import java.util.concurrent.atomic.AtomicReference;
Expand Down Expand Up @@ -121,7 +121,7 @@ protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) {

// Request file region which is bigger then the underlying file.
FileRegion region = new DefaultFileRegion(
new FileInputStream(file).getChannel(), 0, data.length + 1024);
new RandomAccessFile(file, "r").getChannel(), 0, data.length + 1024);

assertThat(cc.writeAndFlush(region).await().cause(), CoreMatchers.<Throwable>instanceOf(IOException.class));
cc.close().sync();
Expand Down Expand Up @@ -183,8 +183,8 @@ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws E

Channel cc = cb.connect(sc.localAddress()).sync().channel();
FileRegion region = new DefaultFileRegion(
new FileInputStream(file).getChannel(), startOffset, data.length - bufferSize);
FileRegion emptyRegion = new DefaultFileRegion(new FileInputStream(file).getChannel(), 0, 0);
new RandomAccessFile(file, "r").getChannel(), startOffset, data.length - bufferSize);
FileRegion emptyRegion = new DefaultFileRegion(new RandomAccessFile(file, "r").getChannel(), 0, 0);

if (!defaultFileRegion) {
region = new FileRegionWrapper(region);
Expand Down

0 comments on commit d8e59ca

Please sign in to comment.