1

I tried to upload a stream (restlet memoryfile) to gcs. But the file has another filesize and is a little different so that the file is marked as "broken".

I tried is local and on google app engine. While debugging to this part the stream looks good in size InputStream inputStream = item.getInputStream();

But the result in the store isn't that size. There are 4 Bits at the beginning: ’[NUL][ENQ]

Where are they from?

List<FileItem> items;
try {
    MemoryFileItemFactory factory = new MemoryFileItemFactory();
    RestletFileUpload restletFileUpload = new RestletFileUpload(factory);
    items = restletFileUpload.parseRequest(req);
    //items = restletFileUpload.parseRepresentation(entity);
    for (FileItem item : items) {
       if (!item.isFormField()) {
           MediaType type = MediaType.valueOf(item.getContentType());
            GcsFileOptions options = new GcsFileOptions.Builder().mimeType(type.getName()).acl("public-read").build();
            GcsOutputChannel outputChannel = gcsService.createOrReplace(fileName, options);
            ObjectOutputStream oout = new ObjectOutputStream(Channels.newOutputStream(outputChannel)); 

           InputStream inputStream = item.getInputStream();
           copy(inputStream, oout);
           //oout.close();
       }
   }
} catch (FileUploadException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

private void copy(InputStream input, OutputStream output) throws IOException {
    try {
      byte[] buffer = new byte[BUFFER_SIZE];
      int bytesRead = input.read(buffer);
      while (bytesRead != -1) {
        output.write(buffer, 0, bytesRead);
        bytesRead = input.read(buffer);
      }
    } finally {
      input.close();
      output.close();
    }
}

private final GcsService gcsService = GcsServiceFactory.createGcsService(new RetryParams.Builder()
  .initialRetryDelayMillis(10)
  .retryMaxAttempts(10)
  .totalRetryPeriodMillis(15000)
  .build());
4

1 回答 1

3

Remove the finally close statements from the copy-function and close the GcsOutputChannel instead. Further you don't need to do this: ObjectOutputStream oout = new ObjectOutputStream(Channels.newOutputStream(outputChannel)); Maybe that adds the extra-bits

Something like that:

GcsOutputChannel outputChannel = gcsService.createOrReplace(fileName, options);
InputStream inputStream = item.getInputStream();

try {
    copy(inputStream, Channels.newOutputStream(outputChannel));
} finally {
    outputChannel.close();
    inputStream.close();
}

private void copy(InputStream input, OutputStream output) throws IOException {
    byte[] buffer = new byte[BUFFER_SIZE];
    int bytesRead = input.read(buffer);
    while (bytesRead != -1) {
        output.write(buffer, 0, bytesRead);
        bytesRead = input.read(buffer);
    }
}
于 2013-08-14T06:31:51.413 回答