2012-07-12 76 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