0

I'm writing an small application like IDM in java. But this has has many Exceptions. This is the code of Downloader class which implements runnable and I want use it for multithreading.

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

and this is my main class

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

but when I run it this happens

It works: 0
null
null
null
null

What should I do now?

  • Try to run it single-threaded. – kukido Jan 10 '14 at 20:39
  • I think you are missing the fact that, as soon as the first Thread reads it's bytes, those bytes are removed from the byte buffer. It's a Stream, not a buffer. Just like with water streams, once something has gone by, it's gone forever. – CodeChimp Jan 10 '14 at 21:02

1 Answers1

1

There are 2 Problems in your code.

  1. At the current state you close() the InputStream from which all Thread try to read directly after you started them (-> while they are running). To solve this Problem you can call the join() Method of the Thread class. In your case your'd have to call it for all 4 Threads to make sure they are finished.

  2. If I understand it correctly you want to seperate the download File into 4 parts downloading at the same time.

To do this you need 4 independent InputStreams. (Currently you are using ONE [See also: Java Object Copying])

So to change this your code would look something like this:

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());
     }
     }
 }
Community
  • 1
  • 1
nZeloT
  • 63
  • 1
  • 2
  • 7