AIM :- TO build a multithreading application using Blocking IO in Java to download a file. Please don't suggest me to use Non-Blocking IO, I have been told to use this one.
Issue :- My code works fine on a client machine which downloads a file hosted on a server. But, the issue is my Server seeds the file using multiple threads. In all the cases, the file received is of exact length,but, the file appears corrupted. Like, when I download a PDF file, the file pages are halfway written to the last(means all pages are filled with partial content of the original). When I download a song, it is bursted throughout & plays till last with those noise bits.
Question 1 :- How should I maintain the perfect smooth downloading so that the file plays/opens/reads properly? What technique like issues because of multithreading should I resolve here?
My Code :-
Server Multi-threading code ::::
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class FileServer extends UnicastRemoteObject implements FileServerInitialise{
private String file="";
public FileServer() throws RemoteException{
super();
}
public void setFile(String f){
file=f;
//System.out.println("Length in setFile = "+f);
}
@Override
public boolean login(FileClientInitialise fci) throws RemoteException {
try {
InputStream is = new BufferedInputStream(new FileInputStream(file));
long len = new File(file).length();
System.out.println("Length of File = "+len);
WorkerThread wt1=new WorkerThread(0,len/2,fci,is,file);
wt1.setName("Worker Thread 1");
WorkerThread wt2=new WorkerThread(len/2+1,2*len/2,fci,is,file);
wt2.setName("Worker Thread 2");
//WorkerThread wt3=new WorkerThread(2*len/4+1,3*len/4,fci,is,file);
//wt3.setName("Worker Thread 3");
//WorkerThread wt4=new WorkerThread(3*len/4+1,len,fci,is,file);
//wt4.setName("Worker Thread 4");
wt1.start();
wt2.start();
//wt3.start();
//wt4.start();
wt1.join();
wt2.join();
//wt3.join();
//wt4.join();
return true;
}
catch (InterruptedException iex) {
iex.getMessage();
return false;
}
Client Downloading code ::::
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
public class FileClient implements FileClientInitialise {
public static int count = 1;
public static File f;
public static FileOutputStream fos;
public static RandomAccessFile raf;
public static long pointer;
public FileClient (String filename) throws RemoteException, IOException {
super();
FileClient.f= new File(filename);
FileClient.fos = new FileOutputStream(f, true);
//FileClient.raf= new RandomAccessFile(f,"rwd");
FileClient.pointer=0;
}
@Override
public boolean sendData(String filename, byte[] data, int len, String threadName) throws RemoteException{
try{
FileClient.fos.write(data,0,len);
FileClient.fos.flush();
//FileClient.raf.seek(FileClient.pointer);
//FileClient.raf.write(data,0, len);
//FileClient.pointer=raf.getFilePointer();
System.out.println("Done writing data...");
//fos.close();
return true;
}catch(Exception e){
e.getMessage();
return false;
}
}
}
Question 2 :- Also, should I use RandomAccessFile
to achieve the same? Would it be more better? I checked it and it works very slow(almost 10 times slower). And, if I were to use RandomAccessFile
, should I create a separate object for each thread? How should I use it, if advised in this case?
If code isn't possible, please give me a technical description, the code isn't necessary to be mentioned in the answer.