读取BlobstoreInputStream

读取BlobstoreInputStream

本文介绍了读取BlobstoreInputStream> = 1MB大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从BlobstoreInputStream中读取超过1mb的数据将抛出一个IOExceptionBlob fetch size too large。

Reading more than 1mb of data from a BlobstoreInputStream will throw an IOException "Blob fetch size too large."

您可以在下面的答案中使用ChainedBlobstoreInputStream类来解决这个问题。

You can use the ChainedBlobstoreInputStream class in the answer below to solve this problem.

推荐答案

我已经创建了一个简单的包装类来解决这个问题。您应该可以直接将ChainedBlobstoreInputStream替换为BlobstoreInputStream。我没有测试mark(),markSupported()或reset()方法。

I've created a simple wrapper class that solves this problem. You should be able to directly swap ChainedBlobstoreInputStream for BlobstoreInputStream. I haven't tested the mark(), markSupported() or reset() methods.

您可以使用此代码。 b

You may use this code however you wish.

package net.magicscroll.server.blobstore;

import com.google.appengine.api.blobstore.BlobInfo;
import com.google.appengine.api.blobstore.BlobInfoFactory;
import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.blobstore.BlobstoreInputStream;

import java.io.IOException;
import java.io.InputStream;

/**
 * ChainedBlobstoreInputStream works exactly like BlobstoreInputStream but does
 * not throw an error if more than 1mb is read.
 *
 * @author Richard Wallis
 */
public class ChainedBlobstoreInputStream extends InputStream {
    /**
     * The maximum number of bytes that can be read by a single request.
     */
    private static final int MAX_READSIZE = 1015800;

    /**
     * The BlobKey of the blobstore item.
     */
    private BlobKey blobKey;
    /**
     * The current byte position of the reader.
     */
    private long offset;

    /**
     * The Total Size of the blob.
     */
    private long totalSize;
    /**
     * The current Input Stream being read.
     */
    private BlobstoreInputStream currentStream;
    /**
     * The next point at which a new InputStream will need to be initialized.
     */
    private long nextReadBreak;
    /**
     * The currentStream at the time of the last mark.
     */
    private BlobstoreInputStream markedStream;

    /**
     * Creates a new ChainedBlobstoreInputStream. This stream should behave
     * exactly the same as a BlobstoreInputStream and it should be possible to
     * interchange them.
     *
     * @param theBlobKey
     *            - The blobkey of the object to be read.
     * @throws IOException
     *             - Thrown if there is an error reading the current stream.
     */
    public ChainedBlobstoreInputStream(final BlobKey theBlobKey)
            throws IOException {
        this(theBlobKey, 0);
    }

    /**
     * Creates a new ChainedBlobstoreInputStream. This stream should behave
     * exactly the same as a BlobstoreInputStream and it should be possible to
     * interchange them.
     *
     * @param theBlobKey
     *            - The blobkey of the object to be read.
     * @param newOffset
     *            - The offset in the blob from where to read.
     * @throws IOException
     *             - Thrown if there is an error reading the current stream.
     */
    public ChainedBlobstoreInputStream(final BlobKey theBlobKey,
            final long newOffset) throws IOException {
        this.offset = newOffset;
        this.blobKey = theBlobKey;
        final BlobInfo blobInfo =
            new BlobInfoFactory().loadBlobInfo(this.blobKey);
        this.totalSize = blobInfo.getSize();
        this.currentStream =
            new BlobstoreInputStream(this.blobKey, this.offset);
        this.nextReadBreak =
            this.offset + ChainedBlobstoreInputStream.MAX_READSIZE;
    }

    /*
     * (non-Javadoc)
     * @see java.io.InputStream#read()
     */
    @Override
    public final int read() throws IOException {
        if (this.offset < this.totalSize) {
            if (this.offset == this.nextReadBreak) {
                this.currentStream.close();
                this.currentStream =
                    new BlobstoreInputStream(this.blobKey, this.offset);
                this.nextReadBreak = this.offset
                + ChainedBlobstoreInputStream.MAX_READSIZE;
            }
            this.offset += 1;
            return this.currentStream.read();
        } else {
            this.currentStream.close();
            return -1;
        }
    }

    /*
     * (non-Javadoc)
     * @see java.io.InputStream#close()
     */
    @Override
    public final void close() throws IOException {
        this.currentStream.close();
        super.close();
    }

    /*
     * (non-Javadoc)
     * @see java.io.InputStream#mark(int)
     */
    @Override
    public final void mark(final int readlimit) {
        this.currentStream.mark(readlimit);
        this.markedStream = this.currentStream;
    }

    /*
     * (non-Javadoc)
     * @see java.io.InputStream#markSupported()
     */
    @Override
    public final boolean markSupported() {
        return this.currentStream.markSupported();
    }

    /*
     * (non-Javadoc)
     * @see java.io.InputStream#reset()
     */
    @Override
    public final void reset() throws IOException {
        this.currentStream = this.markedStream;
        this.currentStream.reset();
    }

}

这篇关于读取BlobstoreInputStream&gt; = 1MB大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-21 01:06