0

I'm trying to copying a file given by the client into a temp file.

This given file is retrieved by my REST service into the InputStream.

Here is my code :

@POST
@Path("fileupload")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFile(
    @FormDataParam("uploadFormElement") InputStream uploadedInputStream,
    @FormDataParam("uploadFormElement") FormDataContentDisposition fileDetail)
    throws IOException {

Response.Status respStatus = Response.Status.OK;

if (fileDetail == null) {
    respStatus = Response.Status.INTERNAL_SERVER_ERROR;
} else {
    if (uploadedInputStream != null) {
    try {
        initPath();
        int size = 0;
        int bytesRead;
        boolean isStreamSizeCorrect = true;
        byte[] buffer = new byte[1024];
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        while ((bytesRead = uploadedInputStream.read(buffer)) != -1) {
        if (size > OntoWebStudioUtil.getUploadFileLimit()) {
            isStreamSizeCorrect = false;
            baos.close();
            while ((bytesRead = uploadedInputStream.read(buffer)) != -1) {
            size++;
            }
            break;
        } else {
            baos.write(buffer, 0, bytesRead);
        }
        size++;
        }
        if (!isStreamSizeCorrect) {
        respStatus = Response.Status.NOT_ACCEPTABLE;
        return Response
            .status(respStatus)
            .entity("Size of uploaded file exceeds the limit"
                + OWSConstants.UPLOAD_RESPONSE_VALUE_SEPARATOR
                + size).build();
        }
        byte[] outBuf = baos.toByteArray();

        String newFilePath = "C:\\Docs\\my_pic.png";
        FileOutputStream fos = null;
        try {
        fos = new FileOutputStream(newFilePath);
        fos.write(outBuf);
        }
        catch (IOException e) {
            e.printStackTrace(System.err);
        }
         finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
         }
    } catch (Exception e) {
        respStatus = Response.Status.INTERNAL_SERVER_ERROR;
        e.printStackTrace(System.out);
    }
    }
}
return Response
    .status(respStatus)
    .entity(tempFileName
        + OWSConstants.UPLOAD_RESPONSE_VALUE_SEPARATOR
        + currentFileName).build();
}
}

The problem I have is that the file created in my temp directory is empty. I have to test the size of the file before creating it. That is the reason why I read my InputStream. So I tried to make a kind of copy of it during its reading. But it doesn't work. What can I do ?

Thanks

user3249592
  • 383
  • 2
  • 3
  • 13
  • What is read value than? If it is -1 than it is a problem of the passed stream, not your code. – cerkiewny Apr 16 '14 at 14:15
  • Your explanation makes me think, that the _uploadedFileName_ is the file name of an uploaded and thus now existing file. If so, you are overwriting it (with 0 bytes) with the `new FileOutputStream(new File(uploadedFileName))` statement. Just a guess. – Seelenvirtuose Apr 16 '14 at 14:15
  • Hi, thanks for your answer. I just edited my post, so you can see what contains my InputStream. It seems there is a problem with it, but I don't know what can I do :( – user3249592 Apr 16 '14 at 14:17
  • You are providing an InputStream to your method. Show us the code that creates that InputStream (I assume, it will be a FileInputStream), and then calls this method. – Seelenvirtuose Apr 16 '14 at 14:19
  • Hi Seelenvirtuose and thanks for your time. I just edited my post and I added the method I use to create my InputStream. – user3249592 Apr 16 '14 at 14:26
  • Does this answer your question? [Is it possible to create a File object from InputStream](https://stackoverflow.com/questions/11501418/is-it-possible-to-create-a-file-object-from-inputstream) – Jasper de Vries Jul 13 '22 at 07:46

3 Answers3

4

If you're using Java SE 7 or greater, you could use Files.copy.

Puce
  • 37,247
  • 13
  • 80
  • 152
1

The code is basically correct. So the only conclusion is: is.read(bytes) was called, but returned -1, so the InputStream is was already read once to the end-of-stream.

There is a second possibility that the e.printStackTrace() is going to a place you did not see (System.err). If you did see Done!, try e.printStackTrace(System.out).

There being a -1 in the data is no problem.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
  • Hi, thank you for your answer. I don't see the Done! I get this error : java.lang.IllegalStateException: Stream already closed It shows the line of the while – user3249592 Apr 16 '14 at 14:42
  • So the input stream `is` was already read before coming to this method. Look backwards. – Joop Eggen Apr 16 '14 at 19:16
  • Hi, thank you for your answer. I am a beginner and I did not know that we could not read an InputStream twice. I edited my post to clean it up – user3249592 Apr 17 '14 at 08:06
0

SOLUTION: I found something that seems to work. Maybe it is not really good so other suggestions are welcome ! There it is : I declare

ByteArrayOutputStream baos = new ByteArrayOutputStream();

I write it while i'm reading my InputStream and checking the size

while ((bytesRead = uploadedInputStream.read(buffer)) != -1) {
if (size > OntoWebStudioUtil.getUploadFileLimit()) {
    isStreamSizeCorrect = false;
    baos.close();
    while ((bytesRead = uploadedInputStream.read(buffer)) != -1) {
        size++;
    }
        break;
} else {
    baos.write(buffer, 0, bytesRead);
}
size++;
}

And then I declare a ByteArrayInputStream to get what I wrote into my ByteArrayOutputStream. Finally I use the Apache commons-io copy method.

fos = new FileOutputStream(newFilePath);
ByteArrayInputStream newStream = new ByteArrayInputStream(baos.toByteArray());
IOUtils.copy(newStream, fos);

I declared my FileOutputStream before calling this method in order to close the FileOutputStream. We cannot read the file if it is not closed.

Hope it will help somebody else :) Thank you for your time !

user3249592
  • 383
  • 2
  • 3
  • 13