All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.biojava.nbio.structure.io.util.FileDownloadUtils Maven / Gradle / Ivy

There is a newer version: 7.2.2
Show newest version
/**
 * BioJava development code
 *
 * This code may be freely distributed and modified under the terms of the GNU
 * Lesser General Public Licence. This should be distributed with the code. If
 * you do not have a copy, see:
 *
 * http://www.gnu.org/copyleft/lesser.html
 *
 * Copyright for this code is held jointly by the individual authors. These
 * should be listed in @author doc comments.
 *
 * For more information on the BioJava project and its aims, or to join the
 * biojava-l mailing list, visit the home page at:
 *
 * http://www.biojava.org/
 *
 * Created on Feb 23, 2012 Created by Andreas Prlic
 *
 * @since 3.0.2
 */
package org.biojava.nbio.structure.io.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;

public class FileDownloadUtils {

	private static final Logger logger = LoggerFactory.getLogger(FileDownloadUtils.class);

	/**
	 * Copy the content of file src to dst TODO since java 1.7 this is provided
	 * in java.nio.file.Files
	 *
	 * @param src
	 * @param dst
	 * @throws IOException
	 */
	@SuppressWarnings("resource")
	public static void copy(File src, File dst) throws IOException {

		// Took following recipe from
		// http://stackoverflow.com/questions/106770/standard-concise-way-to-copy-a-file-in-java
		// The nio package seems to be the most efficient way to copy a file
		FileChannel source = null;
		FileChannel destination = null;

		try {
			// we need the supress warnings here (the warning that the stream is not closed is harmless)
			// see http://stackoverflow.com/questions/12970407/does-filechannel-close-close-the-underlying-stream
			source = new FileInputStream(src).getChannel();
			destination = new FileOutputStream(dst).getChannel();
			destination.transferFrom(source, 0, source.size());
		} finally {
			if (source != null) {
				source.close();
			}
			if (destination != null) {
				destination.close();
			}
		}
	}

	public static String getFileExtension(File f) {
		String fileName = f.getName();
		String ext = "";
		int mid = fileName.lastIndexOf(".");
		ext = fileName.substring(mid + 1, fileName.length());
		return ext;
	}

	public static String getFilePrefix(File f) {
		String fileName = f.getName();
		String fname = "";

		int mid = fileName.indexOf(".");
		fname = fileName.substring(0, mid);

		return fname;
	}

	/**
	 * Download the content provided at URL url and store the result to a local
	 * file, using a temp file to cache the content in case something goes wrong
	 * in download
	 *
	 * @param url
	 * @param destination
	 * @throws IOException
	 */
	public static void downloadFile(URL url, File destination) throws IOException {
		int count = 0;
		int maxTries = 10;
		int timeout = 60000; //60 sec

		File tempFile = File.createTempFile(getFilePrefix(destination), "." + getFileExtension(destination));

		// Took following recipe from stackoverflow:
		// http://stackoverflow.com/questions/921262/how-to-download-and-save-a-file-from-internet-using-java
		// It seems to be the most efficient way to transfer a file
		// See: http://docs.oracle.com/javase/7/docs/api/java/nio/channels/FileChannel.html
		ReadableByteChannel rbc = null;
		FileOutputStream fos = null;
		while (true) {
			try {
				URLConnection connection = prepareURLConnection(url.toString(), timeout);
				connection.connect();
				InputStream inputStream = connection.getInputStream();

				rbc = Channels.newChannel(inputStream);
				fos = new FileOutputStream(tempFile);
				fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
				break;
			} catch (SocketTimeoutException e) {
				if (++count == maxTries) throw e;
			} finally {
				if (rbc != null) {
					rbc.close();
				}
				if (fos != null) {
					fos.close();
				}
			}
		}

		logger.debug("Copying temp file {} to final location {}", tempFile, destination);
		copy(tempFile, destination);

		// delete the tmp file
		tempFile.delete();

	}

	/**
	 * Converts path to Unix convention and adds a terminating slash if it was
	 * omitted
	 *
	 * @param path original platform dependent path
	 * @return path in Unix convention
	 * @author Peter Rose
	 * @since 3.2
	 */
	public static String toUnixPath(String path) {
		String uPath = path;
		if (uPath.contains("\\")) {
			uPath = uPath.replaceAll("\\\\", "/");
		}
		// this should be removed, it's need since "\" is added AtomCache code
		if (uPath.endsWith("//")) {
			uPath = uPath.substring(0, uPath.length() - 1);
		}
		if (!uPath.endsWith("/")) {
			uPath = uPath + "/";
		}
		return uPath;
	}

	/**
	 * Expands ~ in paths to the user's home directory.
	 *
	 * 

* This does not work for some special cases for paths: Other users' homes * (~user/...), and Tilde expansion within the path (/.../~/...) * * @param file * @return */ public static String expandUserHome(String file) { if (file.startsWith("~" + File.separator)) { file = System.getProperty("user.home") + file.substring(1); } return file; } /** * Pings a HTTP URL. This effectively sends a HEAD request and returns * true if the response code is in the 200-399 range. * * @param url The HTTP URL to be pinged. * @param timeout The timeout in millis for both the connection timeout and * the response read timeout. Note that the total timeout is effectively two * times the given timeout. * @return true if the given HTTP URL has returned response * code 200-399 on a HEAD request within the given timeout, otherwise * false. * @author BalusC, * http://stackoverflow.com/questions/3584210/preferred-java-way-to-ping-a-http-url-for-availability */ public static boolean ping(String url, int timeout) { //url = url.replaceFirst("https", "http"); // Otherwise an exception may be thrown on invalid SSL certificates. try { HttpURLConnection connection = (HttpURLConnection) prepareURLConnection(url, timeout); connection.setRequestMethod("HEAD"); int responseCode = connection.getResponseCode(); return (200 <= responseCode && responseCode <= 399); } catch (IOException exception) { return false; } } /** * Prepare {@link URLConnection} with customised timeouts. * * @param url The URL * @param timeout The timeout in millis for both the connection timeout and * the response read timeout. Note that the total timeout is effectively two * times the given timeout. * *

* Example of code. * UrlConnection conn = prepareURLConnection("http://www.google.com/", 20000); * conn.connect(); * conn.getInputStream(); * *

* * NB. User should execute connect() method before getting input * stream. * @return * @throws IOException * @author Jacek Grzebyta */ public static URLConnection prepareURLConnection(String url, int timeout) throws IOException { URLConnection connection = new URL(url).openConnection(); connection.setReadTimeout(timeout); connection.setConnectTimeout(timeout); return connection; } public static void main(String[] args) { String url; url = "http://scop.mrc-lmb.cam.ac.uk/scop/parse/"; System.out.format("%s\t%s%n", ping(url, 200), url); url = "http://scop.mrc-lmb.cam.ac.uk/scop/parse/foo"; System.out.format("%s\t%s%n", ping(url, 200), url); url = "http://scopzzz.mrc-lmb.cam.ac.uk/scop/parse/"; System.out.format("%s\t%s%n", ping(url, 200), url); url = "scop.mrc-lmb.cam.ac.uk"; System.out.format("%s\t%s%n", ping(url, 200), url); url = "http://scop.mrc-lmb.cam.ac.uk"; System.out.format("%s\t%s%n", ping(url, 200), url); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy