Скачать файл, используя Java Apache Commons?
Как я могу использовать библиотеку, чтобы загрузить файл и распечатать сохраненные байты? Я пытался с помощью
import static org.apache.commons.io.FileUtils.copyURLToFile;
public static void Download() {
URL dl = null;
File fl = null;
try {
fl = new File(System.getProperty("user.home").replace("\\", "/") + "/Desktop/Screenshots.zip");
dl = new URL("http://ds-forums.com/kyle-tests/uploads/Screenshots.zip");
copyURLToFile(dl, fl);
} catch (Exception e) {
System.out.println(e);
}
}
но я не могу отобразить байты или индикатор выполнения. Какой метод я должен использовать?
public class download {
public static void Download() {
URL dl = null;
File fl = null;
String x = null;
try {
fl = new File(System.getProperty("user.home").replace("\\", "/") + "/Desktop/Screenshots.zip");
dl = new URL("http://ds-forums.com/kyle-tests/uploads/Screenshots.zip");
OutputStream os = new FileOutputStream(fl);
InputStream is = dl.openStream();
CountingOutputStream count = new CountingOutputStream(os);
dl.openConnection().getHeaderField("Content-Length");
IOUtils.copy(is, os);//begin transfer
os.close();//close streams
is.close();//^
} catch (Exception e) {
System.out.println(e);
}
}
2 ответа
Если вы ищете способ получить общее количество байтов перед загрузкой, вы можете получить это значение из Content-Length
заголовок в ответе http.
Если вы просто хотите получить конечное число байтов после загрузки, проще всего проверить размер файла, в который вы просто записываете.
Однако, если вы хотите отобразить текущий прогресс в количестве загруженных байтов, вы можете расширить apache. CountingOutputStream
обернуть FileOutputStream
так что каждый раз write
вызываемые методы подсчитывают количество проходящих байтов и обновляют индикатор выполнения.
Обновить
Вот простая реализация DownloadCountingOutputStream
, Я не уверен, если вы знакомы с использованием ActionListener
или нет, но это полезный класс для реализации GUI.
public class DownloadCountingOutputStream extends CountingOutputStream {
private ActionListener listener = null;
public DownloadCountingOutputStream(OutputStream out) {
super(out);
}
public void setListener(ActionListener listener) {
this.listener = listener;
}
@Override
protected void afterWrite(int n) throws IOException {
super.afterWrite(n);
if (listener != null) {
listener.actionPerformed(new ActionEvent(this, 0, null));
}
}
}
Это пример использования:
public class Downloader {
private static class ProgressListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
// e.getSource() gives you the object of DownloadCountingOutputStream
// because you set it in the overriden method, afterWrite().
System.out.println("Downloaded bytes : " + ((DownloadCountingOutputStream) e.getSource()).getByteCount());
}
}
public static void main(String[] args) {
URL dl = null;
File fl = null;
String x = null;
OutputStream os = null;
InputStream is = null;
ProgressListener progressListener = new ProgressListener();
try {
fl = new File(System.getProperty("user.home").replace("\\", "/") + "/Desktop/Screenshots.zip");
dl = new URL("http://ds-forums.com/kyle-tests/uploads/Screenshots.zip");
os = new FileOutputStream(fl);
is = dl.openStream();
DownloadCountingOutputStream dcount = new DownloadCountingOutputStream(os);
dcount.setListener(progressListener);
// this line give you the total length of source stream as a String.
// you may want to convert to integer and store this value to
// calculate percentage of the progression.
dl.openConnection().getHeaderField("Content-Length");
// begin transfer by writing to dcount, not os.
IOUtils.copy(is, dcount);
} catch (Exception e) {
System.out.println(e);
} finally {
IOUtils.closeQuietly(os);
IOUtils.closeQuietly(is);
}
}
}
Commons-IO имеет IOUtils.copy(inputStream, outputStream)
, Так:
OutputStream os = new FileOutputStream(fl);
InputStream is = dl.openStream();
IOUtils.copy(is, os);
А также IOUtils.toByteArray(is)
может быть использован для получения байтов.
Получение общего количества байтов - это отдельная история. Потоки не дают вам всего - они могут дать вам только то, что в данный момент доступно в потоке. Но так как это поток, он может быть еще больше.
Вот почему http имеет свой особый способ указания общего количества байтов. Это в заголовке ответа Content-Length
, Так что вам нужно позвонить url.openConnection()
а затем позвоните getHeaderField("Content-Length")
на URLConnection
объект. Он вернет количество байтов в виде строки. Тогда используйте Integer.parseInt(bytesString)
и вы получите свою сумму.