簡體   English   中英

文件在沒有緩沖的情況下可以很好地流式傳輸,但是在緩沖時可以部分流式傳輸

[英]File Streamed well without buffering but gets streamed partially while buffering

我編寫了一個代碼,將字節從另一台服務器流傳輸到我的服務器,然后將這些內容寫入本地文件。 當我使用不緩沖數據的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();    

A1。 您丟棄讀取的字節數,告訴輸出流寫入byteRead緩沖區的全部內容,其中可能包含前一次讀取的數據

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

更新基本上,您的所有示例都遇到相同的問題。 您的緩沖區長為n個字節,但是讀取可以返回緩沖區中的0到n個字節,您需要注意read方法返回的字節數才能知道要寫入多少

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM