Ограничение квоты в 1 МБ для объекта Blobstore в Google App Engine? - PullRequest
7 голосов
/ 02 апреля 2011

Я использую App Engine (версия 1.4.3) для прямой записи в blobstore для сохранения изображений.когда я пытаюсь сохранить изображение размером более 1 МБ, я получаю следующее исключение

com.google.apphosting.api.ApiProxy$RequestTooLargeException: The request to API call datastore_v3.Put() was too large.

Я думал, что предел для каждого объекта составляет 2 ГБ

код Java, в котором хранится изображение

private void putInBlobStore(final String mimeType, final byte[] data) throws IOException {
    final FileService fileService = FileServiceFactory.getFileService();
    final AppEngineFile file = fileService.createNewBlobFile(mimeType);
    final FileWriteChannel writeChannel = fileService.openWriteChannel(file, true);
    writeChannel.write(ByteBuffer.wrap(data));
    writeChannel.closeFinally();
}

Ответы [ 3 ]

5 голосов
/ 19 июня 2012

Вот как я читаю и пишу большие файлы:

public byte[] readImageData(BlobKey blobKey, long blobSize) {
    BlobstoreService blobStoreService = BlobstoreServiceFactory
            .getBlobstoreService();
    byte[] allTheBytes = new byte[0];
    long amountLeftToRead = blobSize;
    long startIndex = 0;
    while (amountLeftToRead > 0) {
        long amountToReadNow = Math.min(
                BlobstoreService.MAX_BLOB_FETCH_SIZE - 1, amountLeftToRead);

        byte[] chunkOfBytes = blobStoreService.fetchData(blobKey,
                startIndex, startIndex + amountToReadNow - 1);

        allTheBytes = ArrayUtils.addAll(allTheBytes, chunkOfBytes);

        amountLeftToRead -= amountToReadNow;
        startIndex += amountToReadNow;
    }

    return allTheBytes;
}

public BlobKey writeImageData(byte[] bytes) throws IOException {
    FileService fileService = FileServiceFactory.getFileService();

    AppEngineFile file = fileService.createNewBlobFile("image/jpeg");
    boolean lock = true;
    FileWriteChannel writeChannel = fileService
            .openWriteChannel(file, lock);

    writeChannel.write(ByteBuffer.wrap(bytes));
    writeChannel.closeFinally();

    return fileService.getBlobKey(file);
}
3 голосов
/ 16 июля 2011

Как предложил Brummo выше, если разделить его на куски <1MB, это работает. Вот некоторый код. </p>

public BlobKey putInBlobStoreString(String fileName, String contentType, byte[] filebytes) throws IOException {
    // Get a file service
    FileService fileService = FileServiceFactory.getFileService();
    AppEngineFile file = fileService.createNewBlobFile(contentType, fileName);
    // Open a channel to write to it
    boolean lock = true;
    FileWriteChannel writeChannel = null;
    writeChannel = fileService.openWriteChannel(file, lock);
    // lets buffer the bitch
    BufferedInputStream in = new BufferedInputStream(new ByteArrayInputStream(filebytes));
    byte[] buffer = new byte[524288]; // 0.5 MB buffers
    int read;
    while( (read = in.read(buffer)) > 0 ){ //-1 means EndOfStream
        ByteBuffer bb = ByteBuffer.wrap(buffer);
        writeChannel.write(bb);
    }
    writeChannel.closeFinally();
    return fileService.getBlobKey(file);
}
3 голосов
/ 02 апреля 2011

Максимальный размер объекта составляет 2 ГБ, но каждый вызов API может обрабатывать не более 1 МБ.По крайней мере, для чтения, но я предполагаю, что это может быть то же самое для письма.Поэтому вы можете попытаться разделить запись объекта на куски размером 1 МБ и посмотреть, поможет ли это.

...