有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java输入流无限循环

我正在尝试将一个文件从Android上传到运行Jersey的Tomcat服务器。我把它包装在一个Post请求中

这就是我在Android中所做的:

protected String doInBackground(String... params) {
    String url = params[0];
    String pathToFile = params[1];
    HttpClient httpClient = new DefaultHttpClient();
    HttpContext localContext = new BasicHttpContext();
    HttpPost httpPost = new HttpPost();
    HttpResponse response = null;
    httpPost.addHeader("Cookie", "sessionToken=~session");
    try {
        httpPost.setURI(new URI(url));
        httpPost.setHeader("Accept", "application/json");
        MultipartEntity entity = new MultipartEntity(
                HttpMultipartMode.BROWSER_COMPATIBLE);
        File file = new File(pathToFile);
        if(!file.exists())
            return null;
        FileBody fileBody = new FileBody(file);
        entity.addPart("file", fileBody);
        httpPost.setEntity(entity);

        response = httpClient.execute(httpPost);
        HttpEntity result = response.getEntity();
    } catch (ClientProtocolException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (URISyntaxException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch(Exception e){
        e.printStackTrace();
    }
    return response.getStatusLine().toString();

在服务器中,我有以下内容:

我收到一个类型为“org.jvnet.mimepull.DataHead$ReadMultiStream”的InputStream,在读取时,在到达文件末尾后,读取返回到1024

@POST
@Consumes({ MediaType.MULTIPART_FORM_DATA })
@Produces({ MediaType.APPLICATION_JSON })
public Response uploadStorageFile(@Context UriInfo ui, @Context HttpHeaders hh, @FormDataParam("file") 
InputStream uploadedInputStream, @FormDataParam("file") FormDataContentDisposition fileDetail){
    System.out.println(uploadedInputStream.getClass().getName());
    String uploadedFileLocation = fileDetail.getFileName();
    long size = fileDetail.getSize();
    // save it
    writeToFile(uploadedInputStream);

    String output = "File uploaded to : ";

    return Response.status(200).entity(output).build();

}
private void writeToFile(InputStream uploadedInputStream) {

        try {
            OutputStream out = new FileOutputStream(new File("test.jpg"));
            int read = 0;
            byte[] bytes = new byte[1024];
            while ((read = uploadedInputStream.read(bytes)) > 0) {
                out.write(bytes, 0, read);
            }
            out.flush();
            out.close();
        } catch (IOException e) {

            e.printStackTrace();
        }

    }

如果文件长度为8192,则循环如下: 102420483072409651206144716881921024->;为什么?

注意:我已尝试使用-1条件

有人知道发生了什么事吗


共 (2) 个答案

  1. # 1 楼答案

    既然这帮你解决了问题,你最近的评论表明this bug was responsible.

    Both methods "read" on ReadMultiStream class violate contract of the implemented interface java.io.InputStream. Javadoc states, that -1 should be returned at the end of the stream, but ReadMultiStream class returns -1 only for the first call (at the end of the stream), all subsequent calls throw an exception instead. This problem could be simulated by sending a stream of characters over web service and wrapping it to the java.io.BufferedReader on the client side. When the stream doesn't end with a new line character, then the usual usage of method readLine fails.

    Fix Version/s: 2.2.6

  2. # 2 楼答案

    多亏了@Jonathan Drapeau,@boxed|才发现了问题。ReadMultiStream违反了java规范。伊奥。输入流接口

    解决方案非常简单,服务器端:

    @POST
    @Consumes({ MediaType.MULTIPART_FORM_DATA })
    @Produces({ MediaType.APPLICATION_JSON })
    public Response uploadStorageFile(@Context UriInfo ui, @Context HttpHeaders hh,     @FormDataParam("file") 
    InputStream uploadedInputStream, @FormDataParam("file") FormDataContentDisposition fileDetail){
    System.out.println(uploadedInputStream.getClass().getName());
    String uploadedFileLocation = fileDetail.getFileName();
    long size = fileDetail.getSize();
    // save it
    try {
                //test.jpg for test purposes
        OutputStream out = new FileOutputStream(new File("test.jpg")); 
        IOUtils.copy(uploadedInputStream, out);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    
    String output = "File uploaded to : ";
    
    return Response.status(200).entity(output).build();
    
    }
    

    正如我在问题中提供的那样,多个教程都在教授如何使用inputstream(服务器端),因此我不知道这是否是最近出现的错误