【问题标题】:cannot download data files using Java无法使用 Java 下载数据文件
【发布时间】:2012-02-15 16:19:55
【问题描述】:

我需要使用 Java 下载文件。我可以使用此代码下载文本文件。但我在下载图像 [数据] 文件时遇到问题。它们被写入损坏的磁盘。我在这里做错了什么?

FileOutputStream fileOutputStream = new FileOutputStream(url
                .getPath().substring(url.getPath().lastIndexOf("/") + 1));
BufferedReader bufferedReader = new BufferedReader(
                new InputStreamReader(socket.getInputStream()));
String line = "";
long l = 0;
while (!(line = bufferedReader.readLine()).isEmpty()) {
    System.out.println(line);
    if (line.contains("Content-Length:")) {
        l = Long.parseLong(line.substring(
                "Content-Length:".length()).trim());
    }
}

byte[] bytes = new byte[socket.getSendBufferSize()];
BufferedWriter bufferedWriter = new BufferedWriter(
        new OutputStreamWriter(fileOutputStream));
int x = 0;
long fullLength = 0;
int length = 0;
DataInputStream dataInputStream = new DataInputStream(
        socket.getInputStream());
DataOutputStream dataOutputStream = new DataOutputStream(
        fileOutputStream);
while (fullLength < l
        && (length = dataInputStream.read(bytes)) != -1) {
    dataOutputStream.write(bytes, 0, length);

    System.out.print(length + " ");
    bufferedWriter.flush();
    fullLength += length;
}

fileOutputStream.flush();
bufferedWriter.close();
socket.close();

【问题讨论】:

  • 嗯,混合使用 Readers(尤其是可能提前读取的缓冲)和底层 Streams 感觉可能是您的问题。

标签: java file sockets stream


【解决方案1】:

您似乎正在尝试使用 HTTP 协议下载二进制文件。这实际上可以以更简单的方式完成:

final URL url = new URL("http://upload.wikimedia.org/wikipedia/commons/9/94/Giewont_and_Wielka_Turnia.jpg");  //1
final InputStream input = url.openStream();  //2
final OutputStream output = new BufferedOutputStream(new FileOutputStream("giewont.jpg")); //3
IOUtils.copy(input, output);  //4
input.close();  //5
output.close();

分步:

  1. 创建URL 指向您要下载的资源。
  2. openStream() 逐字节读取文件。底层的URL 实现处理套接字、Content-length 等。
  3. 创建一个空文件来保存数据。
  4. input的内容复制到output。我正在使用来自 Apache commons-ioIOUtils,以避免在循环中进行无聊且容易出错的复制。
  5. 关闭两个流。您需要关闭 input 以关闭实际的套接字(也许它会在流结束后隐式发生?)和 output 以刷新缓冲区。
  6. ...就是这样!

请注意,由于您基本上是逐字节复制数据,因此文本文件(与编码无关)和二进制文件都可以正确传输。

【讨论】:

  • 谢谢。逐字节复制解决了这个问题。我认为缓冲总是最好的选择。再次感谢。
猜你喜欢
  • 2012-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-16
  • 2013-09-10
  • 2017-08-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多