Question

I have an android tablet client that sends and receives a few files between it and a java server running on windows 7. everything works perfect except for one strange problem. one of the files, in this example, transfer.pdf that is received from the client android tablet can not be opened and shows a size of 0. when I try to open this file I get the error message from adobe reader "this file is already open or in use by another application."

the only way to fix this problem is to use System.exit(0) to kill the entire application, if I do this the file shows the correct size and opens without problems. however i would rather not use System.exit(0). I have tried everything and nothing else has worked.

a finally block is used to close out all the socket input and output, and I set the file variables and socket to null after closing.

has anyone else had this problem and how can I make this work without using System.exit(0)?

code for the server

public class MultiThreader implements Runnable {
Socket socket;
File fileDirectory;
File file;
public int fileSizeFromClient;
FileOutputStream fos = null;
FileInputStream fis = null;
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
DataInputStream dis = null;
DataOutputStream dos = null;
long length;

public MultiThreader(Socket socket){
    System.out.println("print out from multithreader class");
    this.socket = socket;

} // multiThreader

@Override
public void run() {

    System.out.println("multi threader started");

      //================================================================================================
    //==== action #1 read in transfer.pdf file from client ===========================================

    int bufferSize = 0;

    try {

     bis = new BufferedInputStream(socket.getInputStream());
     dis = new DataInputStream(bis);

     fileSizeFromClient = dis.readInt();
     System.out.println("file size for transfer.pdf from client is " + fileSizeFromClient);

      fileDirectory = new File("C:/DOWNLOAD/");
        if (!fileDirectory.exists()) {
            fileDirectory.mkdir();
      }
     file = new File("C:/DOWNLOAD/transfer.pdf");
      file.createNewFile();

       fos = new FileOutputStream(file);
       bos = new BufferedOutputStream(fos);
       dos = new DataOutputStream(bos);

       byte[] buffer = new byte[fileSizeFromClient];

      int totalBytesRead = 0;

        while(totalBytesRead < fileSizeFromClient){
            int bytesRemaining = fileSizeFromClient - totalBytesRead;
            int bytesRead = dis.read(buffer, 0, (int) Math.min(buffer.length, bytesRemaining));
            if(bytesRead == -1) {
                break;
            } else {
                dos.write(buffer, 0, bytesRead); 
                    totalBytesRead += bytesRead;
            }
        } // while

       // ===================================================================================================== 
       // === action #2 send transfer2.pdf file to client =====================================================

      file = new File("C:/DOWNLOAD/transfer2.pdf");
      file.createNewFile();

      fis = new FileInputStream(file);
      bis = new BufferedInputStream(fis);
      dis = new DataInputStream(bis);
      bos = new BufferedOutputStream(socket.getOutputStream());
      dos = new DataOutputStream(bos);

      length = file.length();

       System.out.println("file size for transfer2.pdf sent to client is " + length);

      dos.writeInt((int) length);

      int count = 0;

      buffer = new byte[(int)length];

      while((count = bis.read(buffer)) > 0){
          bos.write(buffer, 0, count);
      }

           //=====================================================================================
      //=== action #3 read in transferImage.jpg from client =================================

     bufferSize = 0;

     bis = new BufferedInputStream(socket.getInputStream());
     dis = new DataInputStream(bis);

     fileSizeFromClient = dis.readInt();
     System.out.println("file size for transferImage.jpg from client is " + fileSizeFromClient);

      file = new File("C:/DOWNLOAD/transferImage.jpg");
      file.createNewFile();

       fos = new FileOutputStream(file);
       bos = new BufferedOutputStream(fos);
       dos = new DataOutputStream(bos);

       buffer = new byte[fileSizeFromClient];

       totalBytesRead = 0;

        while(totalBytesRead < fileSizeFromClient){
            int bytesRemaining = fileSizeFromClient - totalBytesRead;
            int bytesRead = dis.read(buffer, 0, (int) Math.min(buffer.length, bytesRemaining));
            if(bytesRead == -1) {
                break;
            } else {
                dos.write(buffer, 0, bytesRead); 
                    totalBytesRead += bytesRead;
            }
        } // while

            //=====================================================================================

      } catch (IOException ex) {
        Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
      }  finally {

                        try {

                                   bis.close();
                                    fis.close();
                                    dis.close();
                                    fos.flush();
                                    fos.close();
                                    bos.flush();
                                    bos.close();
                                    dos.flush();
                                    dos.close();
                                    socket.close();
                                    file = null;
                                    fileDirectory = null;
                                   // System.exit(0);

                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }

        }


 } // run

  } // MultiThreader

 public class Server {
 ServerSocket serverSocket;
 Socket socket;
 boolean runner = true;

 Server() throws IOException{

    serverRunner();
    System.out.println("server constructor started");

 } // Server constructor

 public void serverRunner() throws IOException {

    System.out.println("serverrunner started");

     try {

      serverSocket = new ServerSocket(6789, 100);

      runner = true;

        while (runner) {

            socket = serverSocket.accept();

            MultiThreader multi = new MultiThreader(socket);
            Thread t = new Thread(multi);
            t.start();

        }  // while runner
       } catch (IOException ex) {

    }

 } // serverRunner  

 } // class Server
Was it helpful?

Solution

Don't use multiple streams. Create a single set of streams and use them for the life of the socket. At the moment you are losing data when you replace an old BufferedInputStream with a new one.

NB:

  1. You don't need a buffer the size of the entire file. 8192 would do. Your code will still work with any buffer size greater than zero.
  2. You don't need to call File.createNewFile() before new FileOutputStream(). It is entirely redundant.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top