2014-01-10 21 views
0

我正在編寫一個像Java中的IDM這樣的小應用程序。 但是這有很多例外。 這是Downloader類的代碼,它實現了runnable,我想將它用於多線程。在java中的IDM類似的應用程序

public class Downloader implements Runnable{ 
private DataInputStream inputStream; 
private byte[][] fileData; 
private int index; 
private int size; 

public Downloader(DataInputStream inputStream, byte[][] fileData, int index, int size) { 
    this.inputStream = inputStream; 
    this.fileData = fileData; 
    this.index = index; 
    this.size = size; 
} 

public synchronized void run() { 
    try{ 
     inputStream.skipBytes(index * size); 
     for(int i= 0;i<size;i++){ 
      fileData[index][i] = inputStream.readByte(); 
      System.out.println("It works : " + index); 
     } 
    } 
    catch(Exception e){ 
     System.out.println(e.getMessage()); 
    } 
}} 

,這是我的主類

public class Main { 

public static void main(String[] args) { 
    String s; 
    //Scanner input = new Scanner(System.in); 
    //System.out.print("Enter file destination : "); 
    //s = input.nextLine(); 
    s = "http://video.varzesh3.com/video/clip1/92/uclip/fun/gaf_6_borhani.mp4"; 
    URL url; 
    URLConnection connection; 
    DataInputStream inputStream; 
    FileOutputStream outStream; 
    byte[][] fileData; 
    try{ 
     url = new URL(s); 
     connection = url.openConnection(); 
     inputStream = new DataInputStream(connection.getInputStream()); 
     fileData = new byte[8][connection.getContentLength()/4]; 
     int size = connection.getContentLength()/4; 
     Runnable d0 = new Downloader(inputStream, fileData, 0, size); 
     Runnable d1 = new Downloader(inputStream, fileData, 1, size); 
     Runnable d2 = new Downloader(inputStream, fileData, 2, size); 
     Runnable d3 = new Downloader(inputStream, fileData, 3, size);    
     Thread thread0 = new Thread(d0); 
     Thread thread1 = new Thread(d1); 
     Thread thread2 = new Thread(d2); 
     Thread thread3 = new Thread(d3);    
     thread0.start(); 
     thread1.start(); 
     thread2.start(); 
     thread3.start();    
     inputStream.close(); 
     String path = "C:\\Users\\NetTest\\Desktop\\test.mp4"; 
     outStream = new FileOutputStream(new File(path)); 
     outStream.write(fileData[0]); 
     /*outStream.write(fileData[1]); 
     outStream.write(fileData[2]); 
     outStream.write(fileData[3]); 
     outStream.write(fileData[4]); 
     outStream.write(fileData[5]); 
     outStream.write(fileData[6]); 
     outStream.write(fileData[7]);*/ 
     outStream.close(); 
    } 
    catch(Exception e){ 
     System.out.println(e.getMessage()); 
    } 
}} 

但是當我運行它,這種情況

It works: 0 
null 
null 
null 
null 

我應該怎麼辦?

+0

嘗試運行它單線程的。 – kukido

+0

我想你錯過了這樣一個事實:只要第一個線程讀取它的字節,這些字節就會從字節緩衝區中移除。這是一個流,而不是緩衝區。就像水流一樣,一旦過去了,它就永遠消失了。 – CodeChimp

回答

1

代碼中有2個問題。

  1. 在當前狀態下,你close()InputStream使所有Thread嘗試讀取你開始與他們直接後( - >而他們正在運行)。爲了解決這個問題,你可以調用Thread類的join()方法。在你的情況下,你必須打電話給所有4 Threads以確保它們已完成。

  2. 如果我理解正確,你想單獨下載File分成4部分同時下載。

要做到這一點,你需要4個獨立的InputStreams。 (目前使用的是ONE [參見:Java Object Copying])

因此,要改變這種代碼會是這個樣子:

public class Downloader implements Runnable{ 
    private byte[][] fileData; 
    private int index; 
    private int size; 
    private URL url; 

    public Downloader(URL url, byte[][] fileData, int index, int size) { 
    this.fileData = fileData; 
    this.index = index; 
    this.size = size; 
    this.url = url; 
    } 

    public synchronized void run() { 
    try{ 
     URLConnection connection = url.openConnection(); 
     DataInputStream inputStream = new DataInputStream(connection.getInputStream()); 
     inputStream.skipBytes(index * size); 
     for(int i= 0;i<size;i++){ 
     fileData[index][i] = inputStream.readByte(); 
     System.out.println("It works : " + index); 
     } 
    }catch(Exception e){ 
     System.out.println(e.getMessage()); 
    } 
    } 
} 
相關問題