0

I need to return a big file from a Jetty server, and I founded 3 different ways in my company source-code to do that. I am now trying to understand the pros/cons of them performance-wise, memory and time.

Option A:

    Path path = <FilePath>;
    return path.toFile();

Easiest to write. However, does it cause the entire file to be loaded to the memory before it's being sent? or does jetty stream it?

Option B:

    Path path = <FilePath>;
    return new FileInputStream(path.toFile());

Is turning the file to stream here have any effect comparing to Option A?

Option C:

    Path path = <FilePath>;
    return new StreamingOutput() {
        @Override
        public void write(final OutputStream out) throws IOException {
            copy(path, out);
        }
    };

Is the copy here needed? isn't it redundant, in compare to Option B?

Option D:
Based on: Streaming Large Files In a Java Servlet

Path path = <FilePath>;
InputStream in = null;
OutputStream out = null;
try {
    in = new FileInputStream(path.toFile());
    out = response.getOutputStream();
    IOUtils.copy(in, out);
} finally {
    IOUtils.closeQuietly(in);
    IOUtils.closeQuietly(out);
}

If there are other/better options, please share them.

Roee Gavirel
  • 18,955
  • 12
  • 67
  • 94
  • Of course the code here is a snippets of the body of the function handling the requests. – Roee Gavirel Sep 10 '17 at 07:13
  • Maybe read here: https://stackoverflow.com/questions/55709/streaming-large-files-in-a-java-servlet – PeterMmm Sep 11 '17 at 08:03
  • @PeterMmm - Thanks, but that explain the need for streaming the data instead of loading the entire data to the memory and then send it. what I'm still confused is how Jetty internally handle the response when provided with a `File` or with a `InputStream`. Does it knows internally to stream it? – Roee Gavirel Sep 11 '17 at 08:17
  • For knowing this for shure: 1. read the doc, is there any reference to this ? 2. read the source https://github.com/eclipse/jetty.project – PeterMmm Sep 11 '17 at 08:25
  • If Jetty expects a `File` or `InputStream` then probably it won't buffer at all to give the user more control. – PeterMmm Sep 11 '17 at 08:26

1 Answers1

0

Option A:

Path path = <FilePath>;
return path.toFile();

Easiest to write. However, does it cause the entire file to be loaded to the memory before it's being sent?

No.

or does jetty stream it?

No. All this does is return a File object.

Option B:

Path path = <FilePath>;
return new FileInputStream(path.toFile());

Is turning the file to stream here have any effect comparing to Option A?

Yes, but not a useful effect. It returns a FileInputStream, which isn't any use at the other end of the connection.

Option C:

Path path = <FilePath>;
return new StreamingOutput() {
    @Override
    public void write(final OutputStream out) throws IOException {
        copy(path, out);
    }
};

Is the copy here needed?

Yes.

isn't it redundant, in compare to Option B?

No. Whether this actually works depends entirely on what StreamingOutput is, which you haven't told us.

Option D: Based on: Streaming Large Files In a Java Servlet

Path path = <FilePath>;
InputStream in = null;
OutputStream out = null;
try {
    in = new FileInputStream(path.toFile());
    out = response.getOutputStream();
    IOUtils.copy(in, out);
} finally {
    IOUtils.closeQuietly(in);
    IOUtils.closeQuietly(out);
}

This is the only option you've presented that actually appears to copy anything from the server to the client. There are other ways of accomplishing that, but returning a File or a FileInputStream aren't any of them.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • I'm sorry to tell you, and you can try it, but I've tried all the presented options and in all of them I received the `file` with its entire content at the client side. Regarding Option C, it uses `javax.ws.rs.core.StreamingOutput` – Roee Gavirel Sep 11 '17 at 12:05