HttpURLConnection在java中意外断开连接

HttpURLConnection在java中意外断开连接,java,swing,Java,Swing,为什么它没有完成下载?它在下载几个字节后停止。为什么会这样 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.InetSocketAdd

为什么它没有完成下载?它在下载几个字节后停止。为什么会这样

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());
    }
}

就这样,我回到提示符处。

你能用这种方法试试吗

int bytesRead = -1;
byte[] buffer = new byte[4098]; // you can change it
while ((bytesRead = inputStream.read(buffer)) != -1) {
    outputStream.write(buffer, 0, bytesRead);
}
outputStream.close();
inputStream.close();

看一下这个

你能用这种方法试试吗

int bytesRead = -1;
byte[] buffer = new byte[4098]; // you can change it
while ((bytesRead = inputStream.read(buffer)) != -1) {
    outputStream.write(buffer, 0, bytesRead);
}
outputStream.close();
inputStream.close();

看一次这个

不确定这是否有用。我可以通过以下方式读取您的文件:

/*
    From the command line use:

    a) java UFile http://forum.java.sun.com ForumsHomePage.html
    b) java UFile someFile.java someOtherFile.java

    or create your own input and output streams and invoke the
    copy(InputStream, OutputStream) method directly
*/
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;

public class UFile
{
    public static void main(String arg[])
     throws IOException
    {
        InputStream is = getInputStream( arg[0] );
        OutputStream os = getOutputStream( arg[1] );
        long start = System.currentTimeMillis();
        System.out.println( UFile.copy(is, os) + " bytes copied" );
        System.out.println( System.currentTimeMillis() - start );

//      new java.io.File(arg[0]).delete();

        System.exit(0);
    }

    public static InputStream getInputStream(String fileName)
        throws IOException
    {
        InputStream input;

        if (fileName.startsWith("http:"))
        {
            URL url = new URL( fileName );
            URLConnection connection = url.openConnection();
            input = connection.getInputStream();
        }
        else
        {
            input = new FileInputStream( fileName );
        }

        return input;
    }

    public static OutputStream getOutputStream(String fileName)
        throws IOException
    {
        return new FileOutputStream( fileName );
    }

    public static int copy(InputStream in, OutputStream out)
        throws IOException
    {
        int bytesCopied = 0;
        byte[] buffer = new byte[4 * 1024];
        int bytes;

        try
        {
            while ( (bytes = in.read( buffer )) != -1 )
            {
                out.write( buffer, 0, bytes );
                bytesCopied += bytes;
            }
        }
        finally
        {
            in.close();
            out.close();
        }

        return bytesCopied;
    }
}
它不使用代理,因此代码很简单

我得到了以下输出:

C:\Java>java UFile http://psthomas.com/solutions/Liar_Truth.pdf test.pdf
60326 bytes copied

无论如何,这个想法是从工作代码开始,然后进行更改。如果它不起作用,那么你至少知道你改变了什么,并且可以在你的问题中提供更具体的信息。

不确定这是否有帮助。我可以通过以下方式读取您的文件:

/*
    From the command line use:

    a) java UFile http://forum.java.sun.com ForumsHomePage.html
    b) java UFile someFile.java someOtherFile.java

    or create your own input and output streams and invoke the
    copy(InputStream, OutputStream) method directly
*/
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;

public class UFile
{
    public static void main(String arg[])
     throws IOException
    {
        InputStream is = getInputStream( arg[0] );
        OutputStream os = getOutputStream( arg[1] );
        long start = System.currentTimeMillis();
        System.out.println( UFile.copy(is, os) + " bytes copied" );
        System.out.println( System.currentTimeMillis() - start );

//      new java.io.File(arg[0]).delete();

        System.exit(0);
    }

    public static InputStream getInputStream(String fileName)
        throws IOException
    {
        InputStream input;

        if (fileName.startsWith("http:"))
        {
            URL url = new URL( fileName );
            URLConnection connection = url.openConnection();
            input = connection.getInputStream();
        }
        else
        {
            input = new FileInputStream( fileName );
        }

        return input;
    }

    public static OutputStream getOutputStream(String fileName)
        throws IOException
    {
        return new FileOutputStream( fileName );
    }

    public static int copy(InputStream in, OutputStream out)
        throws IOException
    {
        int bytesCopied = 0;
        byte[] buffer = new byte[4 * 1024];
        int bytes;

        try
        {
            while ( (bytes = in.read( buffer )) != -1 )
            {
                out.write( buffer, 0, bytes );
                bytesCopied += bytes;
            }
        }
        finally
        {
            in.close();
            out.close();
        }

        return bytesCopied;
    }
}
它不使用代理,因此代码很简单

我得到了以下输出:

C:\Java>java UFile http://psthomas.com/solutions/Liar_Truth.pdf test.pdf
60326 bytes copied

无论如何,这个想法是从工作代码开始,然后进行更改。如果它不起作用,那么您至少知道您更改了什么,并且可以在问题中提供更具体的信息。

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

您可以看到,偏移量将字节读取添加到每个循环中,这就是为什么您会看到大数字跳跃的原因

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

bytesRead = in.read(data, offset, data.length - offset);
所以ByteRead不再附加到自身,而offset正在向自身添加正确的值


在当前的实现中,由于byteRead正在向自身添加,因此当您处于EOF时,它将永远不会具有-1的值。

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

您可以看到,偏移量将字节读取添加到每个循环中,这就是为什么您会看到大数字跳跃的原因

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

bytesRead = in.read(data, offset, data.length - offset);
所以ByteRead不再附加到自身,而offset正在向自身添加正确的值


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

“代码执行会在那里停止,而不会进一步执行”-您的意思是它挂起,还是其他什么?当你捕捉到异常时,你正在请求消息,但没有记录任何东西,这一事实可能对你没有帮助…@Jon Skeet我编辑了我的答案。我已经提供了一个示例。好的,您应该做的第一件事是修复
catch
块以实际打印异常,而不是调用
getMessage()
并忽略结果。完全有可能抛出异常,但我们无法判断,因为您正在吞咽它。@Prashanth您的byteRead正在为每个循环添加自身。这意味着你的偏移量几乎是相乘的。不要使用byteRead的+=运算符,只需使用=。您可以将大部分下载代码替换为
文件.copy(in,path.get(downloadDir,filename))
。参见方法。这将极大地简化将来的调试。“代码执行将停止在那里而不再继续”-您的意思是挂起还是其他什么?当你捕捉到异常时,你正在请求消息,但没有记录任何东西,这一事实可能对你没有帮助…@Jon Skeet我编辑了我的答案。我已经提供了一个示例。好的,您应该做的第一件事是修复
catch
块以实际打印异常,而不是调用
getMessage()
并忽略结果。完全有可能抛出异常,但我们无法判断,因为您正在吞咽它。@Prashanth您的byteRead正在为每个循环添加自身。这意味着你的偏移量几乎是相乘的。不要使用byteRead的+=运算符,只需使用=。您可以将大部分下载代码替换为
文件.copy(in,path.get(downloadDir,filename))
。参见方法。这将大大简化将来的调试。谢谢!那太傻了。我非常喜欢计算读取的字节数,我做了两次
+=
操作。谢谢!那太傻了。我非常喜欢计算读取的字节数,我做了两次
+=
操作。