2012-02-25 5 views
1

Tomcat7上で動作するSpringサーバーにファイルをアップロードしようとしています。それは、単純なPOSTリクエストですが、コードは以下の通りです: ファイルのみを部分的にサーバーにアップロードしました

@RequestMapping(method = RequestMethod.POST) 
    public void saveFile(HttpServletRequest request, @RequestParam("file_name") String fileName) { 
     Logger.getLogger(FileRestAction.class).info("saving file with name " + fileName); 
     try { 
      byte[] buf = readFromRequest(request); 
      String filePath = writeToFile(buf, fileName); 
      File_ file = new File_(filePath, request.getContentType()); 
      Logger.getLogger(FileRestAction.class).info(request.getContentType() + " " + request.getContentLength()); 
      fService.save(file); 
     } catch (IOException e) { 
      Logger.getLogger(FileRestAction.class).error("Failed to upload file. " + 
        "Exception is: " + e.getMessage()); 
     } 
    } 

    private String writeToFile(byte[] buf, String fileName) throws IOException { 
     String fileBasePath = ConfigurationProvider.getConfig().getString(Const.FILE_SAVE_PATH); 
     File file = new File(fileBasePath + fileName); 
     FileOutputStream fos = new FileOutputStream(file); 
     fos.write(buf); 
     fos.close(); 
     Logger.getLogger(FileRestAction.class).info("filepath: " + file.getAbsolutePath()); 
     return file.getAbsolutePath(); 
    } 

    private byte[] readFromRequest(HttpServletRequest request) throws IOException { 
     InputStream is = request.getInputStream(); 
     byte[] buf = new byte[request.getContentLength()]; 
     is.read(buf); 
     is.close(); 
     return buf; 
    } 

は、今の問題は、それがすべてのバイトが存在しないかのようだが、サーバー上のファイルのみが「半済」であるということです。たとえば、サイズが54kBの256x256 .pngファイルを送信すると、サーバーに書き込まれたファイルのサイズも54kBと256x256になりますが、実際の画像は最初の部分(ブランク)になります。例外はスローされません。

少しのテストの後、私は、カットオフが約15-20Kbであることを知りました(その下の画像は完全にアップロードされています)。

何が原因なのでしょうか?

EDIT: GreyBeardedGeekが提案した方法に従ってreadFromRequestメソッドを変更しました。これは次のようになります。

private byte[] readFromRequest(HttpServletRequest request) throws IOException { 
     InputStream is = request.getInputStream(); 
     int fileLength = (int) request.getContentLength(); 
     byte[] buf = new byte[fileLength]; 
     int bytesRead = 0; 
     while (true) { 
      bytesRead += is.read(buf, bytesRead, fileLength - bytesRead); 
      Logger.getLogger(FileRestAction.class).info("reading file: " + bytesRead + " bytes read"); 
      if (bytesRead == fileLength) break; 
     } 
     is.close(); 
     return buf; 
    } 

答えて

2

InputStream.readは、要求されたデータの量を読み取ることが保証されていません。 要求するサイズは、読み込む最大バイト数です。

これは、read()メソッドが実際に読み取られたバイト数を返す理由です。 http://docs.oracle.com/javase/6/docs/api/java/io/InputStream.html#read(byte [])

したがって、答えは複数回読み取るまでです()は-1を返します

関連する問題