Tuesday, May 28, 2013

Download a file from http URL using Java FileChannel - an efficient NIO implementation using Java 7

Java's Channel should always be preferred for IO related stuff because Channel can utilize OS specific optimization while dealing with the files. An input stream can easily be converted to a FileChannel using Channels.newChannel() static factory method.

package org.shunya.power.interview.design14;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URI;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.EnumSet;

public class RealHttpDownloader implements HttpDownloader {
    @Override
    public File download(URI uri, String fileName) throws IOException {
        Path path = Paths.get(fileName);
        long totalBytesRead = 0L;
        HttpURLConnection con = (HttpURLConnection) uri.resolve(fileName).toURL().openConnection();
        con.setReadTimeout(10000);
        con.setConnectTimeout(10000);
        try (ReadableByteChannel rbc = Channels.newChannel(con.getInputStream());
             FileChannel fileChannel = FileChannel.open(path, EnumSet.of(StandardOpenOption.CREATE, StandardOpenOption.WRITE));) {
            totalBytesRead = fileChannel.transferFrom(rbc, 0, 1 << 22); // download file with max size 4MB
            System.out.println("totalBytesRead = " + totalBytesRead);
            fileChannel.close();
            rbc.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return path.toFile();
    }
}


package org.shunya.power.interview.design14;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;

public interface HttpDownloader {
    public File download(URI uri, String fileName) throws IOException;
}


FileChannel ustilizes OS specific optimization and hence should provide better performance in general compared to any buffered streams.

No comments:

Post a Comment

Your comment will be published after review from moderator