1

将文件上传到 Google Cloud Storage 时,存储文件的大小与原始上传文件的大小不同。存储文件的大小比原始大小要小得多。我的上传servlet如下图所示,

public class UploadServlet extends HttpServlet{
    private static final long serialVersionUID = 1L;
    private StorageService storage = new StorageService();
    private static int BUFFER_SIZE =1024 * 1024* 10;
    DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
    @Override
    public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        ServletFileUpload upload = new ServletFileUpload();
        boolean isMultipart = ServletFileUpload.isMultipartContent(req);
        if (!isMultipart) {
            resp.getWriter().println("File cannot be uploaded !");
            return;
        }
        FileItemIterator iter;
        try {
            iter = upload.getItemIterator(req);
            while (iter.hasNext()) {
                FileItemStream item = iter.next();
                String fileName = item.getName();
                String fieldName = item.getFieldName();
                String mime = item.getContentType();
                if (fieldName.equals("file")) {  // the name of input field in html
                    InputStream is1 = item.openStream();
                    try {
                        FileService fileService = FileServiceFactory.getFileService();
                        AppEngineFile file = fileService.createNewBlobFile(mime, fileName);
                        boolean lock = true;
                        FileWriteChannel writeChannel = fileService.openWriteChannel(file, lock);
                        byte[] b1 = new byte[BUFFER_SIZE];
                        int readBytes1;
                        while ((readBytes1 = is1.read(b1)) != -1) {
                            writeChannel.write(ByteBuffer.wrap(b1, 0, readBytes1));
                            storage.init(fileName, mime);
                            storage.storeFile(b1, readBytes1);
                        }
                        writeChannel.closeFinally();
                        String blobKey = fileService.getBlobKey(file).getKeyString();
                        Entity input = new Entity("Input");
                        input.setProperty("Input File", blobKey);
                        datastore.put(input);
                        is1.close();
                        storage.destroy();
                    } catch (Exception e) {
                        e.printStackTrace(resp.getWriter());
                    }
                }
            }
        } catch (FileUploadException e) {
            // log error here
        }
    }
}

我的存储代码如下所示,

public class StorageService {
    public static final String BUCKET_NAME = "MyBucket";
    private FileWriteChannel writeChannel = null;
    FileService fileService = FileServiceFactory.getFileService();
    private BufferedOutputStream bos = null;
    private static final Logger log = Logger.getLogger(StorageService.class.getName());
    private BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
    public void init(String fileName, String mime) throws Exception {
        System.out.println("Storage service:init() method:  file name:"+fileName+" and mime:"+mime);
        log.info("Storage service:init() method:  file name:"+fileName+" and mime:"+mime);
        GSFileOptionsBuilder builder = new GSFileOptionsBuilder()
            .setAcl("public_read")
            .setBucket(BUCKET_NAME)
            .setKey(fileName)
            .setMimeType(mime);
        AppEngineFile writableFile = fileService.createNewGSFile(builder.build());
        boolean lock = true;
        writeChannel = fileService.openWriteChannel(writableFile, lock);
        bos = new BufferedOutputStream(Channels.newOutputStream(writeChannel));
    }
    public void storeFile(byte[] b, int readSize) throws Exception {
        bos.write(b,0,readSize);
        System.out.println(readSize);
        bos.flush();
    }
    public void destroy() throws Exception {
        log.info("Storage service: destroy() method");
        bos.close();
        writeChannel.closeFinally();
    }
    public BlobKey getBlobkey (String filename) {
        BlobKey bk = blobstoreService.createGsBlobKey("/gs/MyBucket/"+filename);
        return bk;
    }
}

当我上传一个 2 MB 的文件时,它只存储 155 个字节。我不明白哪里出错了。

请给我一个想法,

感谢您的帮助。

4

1 回答 1

4

在您的 UploadServlet 类中,您对每个文件调用 storage.init(...) 多次,总是重新创建文件。这不应该发生:

while ((readBytes1 = is1.read(b1)) != -1) {
    writeChannel.write(ByteBuffer.wrap(b1, 0, readBytes1));
    storage.init(fileName, mime);                          // <- HERE
    storage.storeFile(b1, readBytes1);
}

您需要将 init 语句移出循环,放在它前面。

于 2013-01-03T13:12:52.213 回答