为什么无法完成下载?下载几个字节后停止。为什么会这样呢?

import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Authenticator;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.PasswordAuthentication;
import java.net.Proxy;
import java.net.URL;
import java.util.Scanner;

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author prashanth
 */

public class downloadManager {

public static void main(String[] args) {
    String url;
    Proxy myproxy;
    HttpURLConnection uc;
    String downloadDir, file, filename;
    byte[] data;
    Scanner inp = new Scanner(System.in);
    System.out.println("Enter the URL of the file to be downloaded: ");
    url = inp.nextLine();
    if (url.isEmpty()) {
        System.out.println("URL is not provided, please enter the url and try again");
        System.exit(-1);
    }
    try {
        myproxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("172.31.102.14", 3128));
        Authenticator auth = new Authenticator() {
            @Override
            public PasswordAuthentication getPasswordAuthentication() {
                return (new PasswordAuthentication("edcguest", "edcguest".toCharArray()));
            }
        };
        Authenticator.setDefault(auth);
        URL u = new URL(url);
        uc = (HttpURLConnection) u.openConnection(myproxy);
        uc.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2");
        downloadDir = System.getProperty("user.home") + System.getProperty("file.separator") + "Downloads" + System.getProperty("file.separator");
        file = u.getFile();
        filename = file.substring(file.lastIndexOf('/') + 1);
        System.out.println("Waiting for connection...");
        if (uc.getResponseCode() == 200) {
            System.out.println("Connection OK!\nFile: " + filename + "\nFile Size: " + uc.getContentLength() + " bytes\nDownloading file...");
            data = new byte[uc.getContentLength()];
            int bytesRead = 0;
            int offset = 0;
            InputStream in = new BufferedInputStream(uc.getInputStream());
            while (offset < uc.getContentLength()) {
                bytesRead += in.read(data, offset, data.length - offset);
                if (bytesRead == -1) {
                    break;
                }
                offset += bytesRead;
                System.out.println("Finished downloading: " + bytesRead + " Bytes");
            }
            in.close();
            if (offset != uc.getContentLength()) {
                throw new IOException("Only read " + offset + " bytes. Expected " + uc.getContentLength() + " bytes");
            }
            System.out.println("Finishing Download...");

            FileOutputStream out = new FileOutputStream(downloadDir + filename);
            out.write(data);
            System.out.println("Download Completed! Find the file in your Downloads folder");
            out.flush();
            out.close();
        } else {
            System.out.println("Download failed! Error: " + uc.getResponseCode());
        }

    } catch (Exception e) {
        System.err.println("Exception: "+e.getMessage());
    }
}


}

我哪里做错了? while循环不会完全执行,并且代码执行将在那里停止,而不会继续进行。

编辑:
这是例子

Enter the URL of the file to be downloaded:
http://psthomas.com/solutions/Liar_Truth.pdf
Waiting for connection...
Connection OK!
File: Liar_Truth.pdf
File Size: 60326 bytes
Downloading file...
Finished downloading: 3709 Bytes
Finished downloading: 8053 Bytes
Finished downloading: 12397 Bytes
Finished downloading: 13845 Bytes
Finished downloading: 16741 Bytes
Finished downloading: 20093 Bytes
Exception: Only read 74838 bytes. Expected 60326 bytes


就是这样,我回到了提示。

最佳答案

看起来您的byteRead相互添加(使用+ =运算符)。

        while (offset < uc.getContentLength()) {
            bytesRead += in.read(data, offset, data.length - offset);
            if (bytesRead == -1) {
                break;
            }
            offset += bytesRead;
            System.out.println("Finished downloading: " + bytesRead + " Bytes");
        }


这是您的代码,这是每个循环的bytesRead和offset的实际值:

Loop count       bytesRead         offset
1                3709 Bytes        3709
2                8053 Bytes        11762
3                12397 Bytes       24159
4                13845 Bytes       38004
5                16741 Bytes       54745
6                20093 Bytes       74838


您可以看到偏移量在每个循环中都将bytesRead添加到其自身,这就是为什么看到大量数字跳跃的原因。

将while循环的第一行更改为:

bytesRead = in.read(data, offset, data.length - offset);


因此,bytesRead不再追加其自身,而offset为其自身添加了正确的值。

在当前的实现中,因为bytesRead是添加到自身中,所以当您处于EOF时,它将永远不会具有值-1。

关于java - HttpURLConnection在Java中意外断开连接,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32784434/

10-13 03:20