2014-01-07 3 views
0

У меня есть клиент планшета Android, который отправляет и получает несколько файлов между ним и java-сервером, работающим на Windows 7. Все работает отлично, за исключением одной странной проблемы. один из файлов, в этом примере, transfer.pdf, который получен от клиентского Android-планшета, не может быть открыт и показывает размер 0. Когда я пытаюсь открыть этот файл, я получаю сообщение об ошибке от adobe reader «этот файл уже открытые или используемые другим приложением ».Размер файла, отправленного сокетом, равен 0 и доступ заблокирован, если я не использую System.exit (0), как этого избежать?

Единственный способ устранить эту проблему - использовать System.exit (0), чтобы убить все приложение, если я сделаю это, файл отобразит правильный размер и откроется без проблем. однако я бы предпочел не использовать System.exit (0). Я пробовал все и ничего больше не работал.

блок finally используется для закрытия всех входов и выходов сокетов, и я устанавливаю переменные файла и сокет равным null после закрытия.

имеет ли кто-нибудь еще эту проблему и как я могу сделать эту работу без использования System.exit (0)?

код сервера

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 
+1

Почему вы создаете буферы поверх своего 'BufferedOutputStream'? –

+0

лучше не делать этого? – Kevik

+0

Это бессмысленно; «BufferedOutputStream» уже выполняет буферизацию ... просто пишите по одному байту за раз и позволяйте ему справляться с этим. –

ответ

0

Не следует использовать несколько потоков. Создайте один набор потоков и используйте их для жизни сокета. В настоящий момент вы теряете данные при замене старого BufferedInputStream на новый.

NB:

  1. Вам не нужен буфер размером всего файла. 8192. Ваш код будет работать с любым размером буфера, большим нуля.
  2. Вам не нужно звонить File.createNewFile() до new FileOutputStream(). Это полностью избыточно.
+0

это хороший обзор кода. – Kevik