2012-07-12 104 views
0

我寫了一個代碼,從另一個服務器流到我的服務器的字節,然後我寫這些內容到我的本地文件。當我使用不緩衝數據的read()方法時,它工作正常。但是,當我使用緩衝(我的意圖是,我認爲對於大文件流式傳輸會更快),我使用read(byte [])方法,並在流式傳輸時只獲取部分數據。我張貼代碼。任何人都可以指出我錯過的錯誤或概念。文件流沒有緩衝,但部分流緩衝

以下代碼正常工作。 (無流媒體)

private void doViewDocument(HttpServletRequest request, 
      HttpServletResponse response, DocumentServletService servletService) throws GEMException, MalformedURLException, ProtocolException, IOException { 

     final String objectID = request.getParameter(PARAM_OBJECT_ID); 

     LOGGER.info("For Viewing Document objectID received from Request == " + objectID); 

     if (GEMSharedUtil.isValidObjectId(objectID)) { 

      String ebesDocDownloadURL = servletService.getDocumentDownloadUrl(objectID); 

      if (!GEMSharedUtil.isValidString(ebesDocDownloadURL)) {    
       //response.setStatus(HttpServletResponse.SC_NOT_ACCEPTABLE); 
       response.setHeader("ResponseStatus", "Not_OK"); 
       throw new GEMException(); 
      } else { 
       HttpURLConnection con = null; 
       BufferedInputStream bin = null; 
       BufferedOutputStream bout = null; 

       try { 
        con = (HttpURLConnection) new URL(ebesDocDownloadURL).openConnection(); 

        WASSecurity.preauthenticateWithLTPACookie(con); 
        con.setRequestMethod(REQUEST_METHOD_GET); 
        con.setDoOutput(true); // Triggers POST but since we have set request method so it will override it 
        con.setDoInput(true); 
        con.setUseCaches(false); 
        con.setRequestProperty("Connection", "Keep-Alive"); 
        con.setAllowUserInteraction(false); 
       // con.setRequestProperty("Content-Type", 
       // "application/octet-stream"); 

        response.setBufferSize(1024); 
        response.setContentType(con.getContentType()); 
        response.setContentLength(con.getContentLength()); 
        response.setHeader("ResponseStatus", "OK"); 
        response.setHeader("Content-Disposition", con 
          .getHeaderField("Content-Disposition")); 

        bin = new BufferedInputStream((InputStream) 
          con.getInputStream(), 1024); 

        bout = new BufferedOutputStream(
          response.getOutputStream(), 1024); 

        byte[] byteRead = new byte[1024]; 


        File file = new File("C:\\Documents and Settings\\weakStudent\\Desktop\\streamed\\testStream.pdf"); 

        FileOutputStream fos = new FileOutputStream(file); 

        if(file.length() > 0) { 
         file.delete(); 
        } 
        file.createNewFile(); 

        BufferedOutputStream fbout = new BufferedOutputStream((OutputStream) fos); 
        int c; 
        while((c= bin.read()) != -1) { 
         bout.write(c); 
         fbout.write(c); 
        } 
fos.close(); 
        bout.flush(); 
        fbout.flush(); 
        fbout.close(); 
        LOGGER.info("con.getResponseCode():" + con.getResponseCode()); 

       } finally { 
        try { 
         if (bout != null) { 
          bout.close(); 
         } 
        } catch (IOException e) { 
         LOGGER.log(Level.SEVERE, e.getMessage(), e); 
         throw new RuntimeException(e); 
        } finally { 
         try { 
          if (bin != null) { 
           bin.close(); 
          } 
         } catch (IOException e) { 
          LOGGER.log(Level.SEVERE, e.getMessage(), e); 
          throw new RuntimeException(e); 
         } finally { 
          if (con != null) { 
           con.disconnect(); 
          } 
         } 
        } 
       } 
      } 

     } //if ends 

    } 

現在如果我有以下while循環它不能正常工作。

   while(bin.read(byteRead) != -1) { 
        bout.write(byteRead); 
        fbout.write(byteRead); 
       } 

Q2) 也想知道是強制使用的BufferedInputStream /的BufferedOutputStream流媒體。對於例如,如果我使用下面的代碼它的工作原理

BufferedInputStream bin = null; 

    try { 
     //in = request.getInputStream();   

     bin = new BufferedInputStream((InputStream) request 
       .getInputStream(), 1024); 

     int respcode = HttpURLConnection.HTTP_OK; 
     con = createConnection(uploadURL, REQUEST_METHOD_POST); 
     con.setRequestProperty("X-File-Name",fileName); 

     conOut = con.getOutputStream(); 
     bout = new BufferedOutputStream(conOut); 
     byte[] byteRead = new byte[1024];  

     while (bin.read(byteRead) != -1) { 
      bout.write(byteRead); 
     } 
     bout.flush(); 
     respcode = con.getResponseCode();  

但下面再次部分流(這裏沒有使用的BufferedInputStream)

ServletInputStream in = null; 

    try { 
     in = request.getInputStream();  

     int respcode = HttpURLConnection.HTTP_OK; 
     con = createConnection(uploadURL, REQUEST_METHOD_POST); 
     con.setRequestProperty("X-File-Name",fileName); 

     conOut = con.getOutputStream(); 
     bout = new BufferedOutputStream(conOut); 
     byte[] byteRead = new byte[1024];  

     while (in.read(byteRead) != -1) { 
      bout.write(byteRead); 
     } 
     bout.flush(); 
     respcode = con.getResponseCode();  
+0

close()你正在開放。你沒有關閉「福斯」 – rizzz86 2012-07-12 09:31:55

+0

做到了。一樣的。 – abhihello123 2012-07-12 09:34:31

回答

1

A1。你丟棄被讀取的字節數,告訴輸出流寫入byteRead緩衝區中的全部內容,這可能從先前包含數據讀取

int bytesIn = -1; 
while((bytesIn = bin.read(byteRead)) != -1) { 
    bout.write(byteRead, 0, bytesIn); 
    fbout.write(byteRead, 0, bytesIn); 
} 

UPDATE 基本上,所有的例子都患一樣的問題。您的緩衝區長度爲n個字節,但讀取可以在緩衝區中返回0到n個字節,您需要注意讀取方法返回的字節數,以便知道要寫入多少字節。

+0

嗨@ user99,你說的是絕對正確的。我錯過了。所以這意味着如果我流式傳輸2048字節的文檔,它甚至可以正確運行我的錯誤代碼。由於整個字節數組將被寫入,並沒有以前的字節會在那裏會導致文件損壞..我是嗎? – abhihello123 2012-07-12 09:57:11

+0

你不需要初始化'bytesIn'。 – EJP 2012-07-12 10:07:31

+0

@weakstudent這是用Java複製流的規範方法。記住它。它始終有效。 – EJP 2012-07-12 10:08:02