0

I was trying to make a java program to copy a file with the reader in one thread and the writer in another thread. The program works without showing any errors but the copied file has a different checksum from the original file. I am not able to find the mistake i made in the program. The program copies text files and they dont seem to be having any problems. When i try copying a zip file, copying finishes successfully, but when i try to extract the copied zip, it shows that the zip file is corrupted. Can someone help me in finding the mistake.

import java.io.*;
import java.util.concurrent.*;
import java.util.*;

class qu{
qu(byte[] b,int s){
    this.b=b;
    this.s=s;
} 
  byte[] b;
  int s;
 public String toString(){
     return s+"";
 }
}

class reader implements Runnable{
public byte[] b = new byte[1048576];
String inf;
int s;
long max;
private  BlockingQueue<qu> blockingQueue;
public reader(String inf,BlockingQueue<qu> blockingQueue,long max){
    this.inf=inf;
    this.max=max;
    this.blockingQueue=blockingQueue;
}

public void run(){
        RandomAccessFile in=null;
        try{
            in = new RandomAccessFile(inf,"rw");
            while((s=in.read(b))!=-1){
               blockingQueue.put(new qu(b,s));
            }

        }catch(Exception e){System.out.println(e);}
        finally{
            try{
                in.close();
            }catch(Exception e){System.out.println(e);}

        }


}
}

class writer implements Runnable{
public byte[] b = new byte[1048576];
String outf;
int s=0;
long max=0;
private  BlockingQueue<qu> blockingQueue;
public writer(String outf,BlockingQueue<qu> blockingQueue,long max){
    this.outf=outf;
    this.max=max;
    this.blockingQueue=blockingQueue;
}

public void run(){
        RandomAccessFile out;
        qu asd;
        System.out.println("Copying..");
        try{
            out = new RandomAccessFile(outf,"rw");
            while(out.getFilePointer()!=max){
                    asd=blockingQueue.take();
                    //System.out.println(new String(asd.b));
                    out.write(asd.b,0,asd.s);

            }
            out.close();
        }catch(Exception e){System.out.println(e);}

    }
}



class mul {

public static void main(String[] args) {
    String inf = args[0];
    String outf = args[1];
    File file =new File(inf);
    long max = file.length();
    BlockingQueue<qu> blockingQueue = new ArrayBlockingQueue<>(64);
    if(file.exists()){
        long start_time = System.nanoTime();
        Thread t1=new Thread(new reader(inf,blockingQueue,max));
        t1.start();
        Thread t2=new Thread(new writer(outf,blockingQueue,max));
        t2.start();
        try{
            t1.join();
            t2.join();
        }catch(Exception ex){System.out.println(ex);}
        long end_time = System.nanoTime();
        double difference = (end_time - start_time) / 1e6;
        System.out.println("Time taken: "+difference+"ms");
        System.out.println("Copy Completed..");

    }else{System.out.println("File not Found");}

}
}
3
  • As a side note, class names in Java should always begin with a capital letter. Take a look at the Java Naming Conventions here. Commented Jun 5, 2018 at 20:03
  • I'm a noob in java and I'm learning the concepts now. Thanks for pointing it out . It's really appreciated. Commented Jun 6, 2018 at 7:17
  • You’re welcome! Have fun learning more! Commented Jun 6, 2018 at 7:18

1 Answer 1

2

You need to copy your byte array e.g.

public class Qu {
    private final byte[] b;
    private final int s;

    public Qu(byte[] b,int s) {
        this.b = Arrays.copyOf(b, b.length);
        this.s = s;
    } 

    public String toString(){
        return s+"";
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you. The problem is solved. Can you please explain why there is a need to use a copy of b and not b itself?
Because you were writing to and reading from the same buffer concurrently. In one thread you were writing data and in another you were reading it without any synchronization. (Btw I think you could use Arrays.copyOf(b, s) as this copies only the read data instead of one buffer)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.