我没加注释,主要是最后的异常是怎么引起的,编译运行一下import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;public class Main {
public static final int MAXSIZE = 2048;
URL url = null;
HttpURLConnection httpURLConnection = null;
RandomAccessFile raf = null; public Main(String url) {
try {
this.url = new URL(url);
} catch (MalformedURLException e) {
e.printStackTrace();
}
} public void launch() {
String urlName = url.toString();
String fileName = urlName.substring(urlName.lastIndexOf("/"));
fileName = "D:\\" + fileName;
File file = new File(fileName);

try {
file.createNewFile();
raf = new RandomAccessFile(file, "rw");
httpURLConnection = (HttpURLConnection) url.openConnection();
//httpURLConnection.connect();
int contentSize = httpURLConnection.getContentLength();
raf.setLength(contentSize);
System.out.println(contentSize);
//httpURLConnection.disconnect();
boolean flag = true;
int count = 0;
int recent = 0;
count = contentSize / MAXSIZE;

for (int i = 0; i < count; i++) {
new MyThread(raf, urlName, i).start();
} } catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Main main = new Main("http://www.programfan.com/down/2005/masm5.zip");
main.launch();
}
}
import java.io.DataInputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;public class MyThread extends Thread {
RandomAccessFile raf = null;
URL url = null;
HttpURLConnection httpURLConnection = null;
int i = 0;
int recent = 0; public MyThread(RandomAccessFile raf, String urlName, int i) {
this.raf = raf;
try {
url = new URL(urlName);
this.i = i;
} catch (MalformedURLException e) {
e.printStackTrace();
}
} public void run() {
try {
httpURLConnection = (HttpURLConnection) url.openConnection();

System.out.println(httpURLConnection.getResponseCode()); int num = httpURLConnection.getContentLength() - (i + 1)
* Main.MAXSIZE;
System.out.println(num);
byte[] bytes;
if (num > 0 && num < Main.MAXSIZE) {
bytes = new byte[num];
httpURLConnection.setRequestProperty("Range", "bytes="
+ (i * Main.MAXSIZE) + "-" + (i * Main.MAXSIZE + num));
httpURLConnection.connect();
} else {
bytes = new byte[Main.MAXSIZE];
httpURLConnection.setRequestProperty("Range", "bytes="
+ (i * Main.MAXSIZE) + "-" + (i + 1) *Main.MAXSIZE);
httpURLConnection.connect();
} DataInputStream dis = new DataInputStream(httpURLConnection
.getInputStream());
dis.read(bytes);
httpURLConnection.disconnect();
raf.seek(i * Main.MAXSIZE);
raf.write(bytes);
raf.close();
System.out.println("草"); } catch (IOException e) {

} }}

解决方案 »

  1.   


    Exception in thread "Thread-38" java.lang.IllegalStateException: Already connected
    at sun.net.www.protocol.http.HttpURLConnection.setRequestProperty(Unknown Source)
      

  2.   

    你在run()里连接了两次httpURLConnection = (HttpURLConnection) url.openConnection();和httpURLConnection.connect();
    把httpURLConnection.connect();注释了试试
    if (num > 0 && num < Main.MAXSIZE) {
                    bytes = new byte[num];
                    httpURLConnection.setRequestProperty("Range", "bytes="
                            + (i * Main.MAXSIZE) + "-" + (i * Main.MAXSIZE + num));
                    //httpURLConnection.connect();
                } else {
                    bytes = new byte[Main.MAXSIZE];
                    httpURLConnection.setRequestProperty("Range", "bytes="
                            + (i * Main.MAXSIZE) + "-" + (i + 1) *Main.MAXSIZE);
                    //httpURLConnection.connect();
                }
      

  3.   

    哦,你在run()里一开始就调用了url.openConnection(),但是setRequestProperty这个方法在已经连接的时候就抛IllegalStateException。
    setRequestProperty
    Throws: 
    IllegalStateException - if already connected
    NullPointerException - if key is null
      

  4.   

    答:很简单,在:
    MyThread类的run()方法的System.out.println(num);之后加上
    httpURLConnection.disconnect();就行了。保证你成功
      

  5.   

    还有异常
    把最后那个try catch后加上
             httpURLConnection.disconnect();
                raf.seek(i * Main.MAXSIZE);
                raf.write(bytes);
                raf.close();
                System.out.println("草");        } catch (IOException e) {
               e.printStackTrace();
            }
    抛出java.io.IOException: 句柄无效。
    at java.io.RandomAccessFile.seek(Native Method)
      

  6.   

    java.io.IOException: 句柄无效。
    这个异常 在哪行抛出的
      

  7.   

    调试了下,MS到了httpURLConnection.setRequestProperty(.............);就过不去了。继续。
      

  8.   

    哦,发现一点,当已连接时,setRequestProperty()会触发IllegalStateException异常。故修改MyThread如下,public void run() {
    try {
    httpURLConnection = (HttpURLConnection) url.openConnection(); int num = httpURLConnection.getContentLength() - (i + 1) * Main.MAXSIZE;
    httpURLConnection.disconnect(); //先暂时关闭
    byte[] bytes;
    if (num > 0 && num < Main.MAXSIZE) {
                                         。
    //httpURLConnection.connect();

    } else {
                                。
    //httpURLConnection.connect();
    }
    httpURLConnection.connect();//设置完请求属性后,再打开。不过虽然不报异常了,但是文件的分割下载还是有点问题。
    继续
      

  9.   

    答:你看,我也上当了.以后写程序,抓到IOException后,不能是是一条空语句,什么都不做啊.要及时打印出错误信息啊.
    程序有三处要改:
    1)将MyThread类中的raf.close();去掉.就是它引起那个IO异常的.
    此时:程序运行时再没有异常了.但问题很严重:多线程下载的masm5.zip文件是受损的(不正确的)
    因此:我又在
    2)在launch();方法中加上:当所有的下载线程都结束时,才调用raf.close();
    此时:运行时没有异常了,但多线程下载的masm5.zip文件仍是受损的.
    因此:显然raf是多个下载线程同时共用的一个资源,它要synchronized啊.否则:masm5.zip文件将是受损的
    3)请你将多个下载线程同时共用的那个raf操作,进行synchronized.这个我就不做了,请楼主做吧.
      

  10.   

    他是抛的IllegalStateException这个异常,建议你捕捉下这个异常
      

  11.   

    是啊,还有个IOException。顶20楼!去掉raf.close();简单,关键是文件下载的不正确。
    主要是raf.write(bytes); 的问题。楼主应该在写个类保存一个RandomAccessFile对象,避免每个线程都有自己的RandomAccessFile对象(当然RandomAccessFile里的文件指针还是各用各的)。
    这样可以把raf.write(bytes);封装成一个新的方法是这个方法同步(synchronized),这样所有线程都调用这个方法就不会出错误了。
      

  12.   

    我终于知道了
    openConnection(),只是创建对象,并不会打开连接。
    之所以会有Already connected这个异常,是因为你在调用setRequestProperty方法设置请求的属性前,
    调用了getResponseCode()以及getContentLength()方法,这些方法都会隐式的打开连接,
    所以此时再想调用setRequestProperty来设置请求属性就已经晚了,导致异常。
      

  13.   

    http://bbs.langsin.com/forum-51-1.html
      

  14.   

    这是修改后的,但是还是压缩文件受损import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.RandomAccessFile;
    import java.net.HttpURLConnection;
    import java.net.MalformedURLException;
    import java.net.URL;public class Main {
    public static final int MAXSIZE = 1000;
    URL url = null;
    HttpURLConnection httpURLConnection = null;
    RandomAccessFile raf = null; public Main(String url) {
    try {
    this.url = new URL(url);
    } catch (MalformedURLException e) {
    e.printStackTrace();
    }
    } public void launch() {
    String urlName = url.toString();
    String fileName = urlName.substring(urlName.lastIndexOf("/"));
    fileName = "D:\\" + fileName;
    File file = new File(fileName); try {
    file.createNewFile();
    raf = new RandomAccessFile(file, "rw");
    httpURLConnection = (HttpURLConnection) url.openConnection();
    int contentSize = httpURLConnection.getContentLength();
    System.out.println(contentSize);
    boolean flag = true;
    int count = 0;
    int recent = 0;
    count = contentSize / MAXSIZE; for (int i = 0; i < count; i++) {
    new MyThread(raf, urlName, i).start();
    }
    Runtime.getRuntime().addShutdownHook(new Thread() { public void run() {
    try {
    System.out.println(raf.length());
    raf.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    });
    } catch (FileNotFoundException e) {
    e.printStackTrace();
    } catch (IOException e) {
    e.printStackTrace();
    }
    } public static void main(String[] args) {
                                     Main main = new Main("http://www.programfan.com/down/2005/masm5.zip"); main.launch();
    }
    }
    import java.io.DataInputStream;
    import java.io.IOException;
    import java.io.RandomAccessFile;
    import java.net.HttpURLConnection;
    import java.net.MalformedURLException;
    import java.net.URL;public class MyThread extends Thread {
    public static int ountSize = 0;
    RandomAccessFile raf = null;
    URL url = null;
    HttpURLConnection httpURLConnection = null;
    int i = 0;
    int recent = 0; public MyThread(RandomAccessFile raf, String urlName, int i) {
    this.raf = raf;
    try {
    url = new URL(urlName);
    this.i = i;
    } catch (MalformedURLException e) {
    e.printStackTrace();
    }
    } public synchronized void run() { try {
    httpURLConnection = (HttpURLConnection) url.openConnection(); //System.out.println(httpURLConnection.getResponseCode()); int num = httpURLConnection.getContentLength() - (i + 1)
    * Main.MAXSIZE;
    // System.out.println(num);
    httpURLConnection.disconnect();
    byte[] bytes;
    if (num > 0 && num < Main.MAXSIZE) {
    bytes = new byte[num];
    httpURLConnection.setRequestProperty("Range", "bytes="
    + (i * Main.MAXSIZE) + "-" + (i * Main.MAXSIZE + num)); } else {
    bytes = new byte[Main.MAXSIZE];
    httpURLConnection.setRequestProperty("Range", "bytes="
    + (i * Main.MAXSIZE) + "-" + (i + 1) * Main.MAXSIZE); } DataInputStream dis = new DataInputStream(httpURLConnection
    .getInputStream());
    dis.read(bytes);
    httpURLConnection.disconnect(); raf.seek(i * Main.MAXSIZE);
    raf.write(bytes);
    } catch (IOException e) {
    e.printStackTrace();
    } }}