我编写了一个代码,将来自其他服务器的字节流式传输到我的服务器,然后将这些内容写入我的本地文件。当我使用不缓冲数据的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 :(得分:1)
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方法返回的字节数,以便知道写入多少