Java 正在读取BlobstoreInputStream>;=1MB大小

Java 正在读取BlobstoreInputStream>;=1MB大小,java,google-cloud-datastore,Java,Google Cloud Datastore,从BlobstoreInputStream读取超过1mb的数据将引发IOException“Blob fetch size To large” 您可以在下面的答案中使用ChainedBlobstoreInputStream类来解决此问题 while ((size = zis.read(buffer)) > 0) contents.write(buffer, 0, size); 但是,将整个文件读入内存的整个概念都有其局限性。在阅读时找到一种处理方法 否则我会出错 什么错误?我创建了一

从BlobstoreInputStream读取超过1mb的数据将引发IOException“Blob fetch size To large”

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

while ((size = zis.read(buffer)) > 0)
  contents.write(buffer, 0, size);
但是,将整个文件读入内存的整个概念都有其局限性。在阅读时找到一种处理方法

否则我会出错


什么错误?

我创建了一个简单的包装器类来解决这个问题。您应该能够直接将ChainedBlobstoreInputStream交换为BlobstoreInputStream。我还没有测试mark()、markSupported()或reset()方法

您可以随意使用此代码

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();
    }

}
package net.magicscroll.server.blobstore;
导入com.google.appengine.api.blobstore.BlobInfo;
导入com.google.appengine.api.blobstore.BlobInfoFactory;
导入com.google.appengine.api.blobstore.BlobKey;
导入com.google.appengine.api.blobstore.BlobstoreInputStream;
导入java.io.IOException;
导入java.io.InputStream;
/**
*ChainedBlobstoreInputStream的工作原理与BlobstoreInputStream完全相同,但确实如此
*如果读取超过1mb,则不会引发错误。
* 
*@作者理查德·沃利斯
*/
公共类ChainedBlobstoreInputStream扩展InputStream{
/**
*单个请求可以读取的最大字节数。
*/
私有静态最终int MAX_READSIZE=1015800;
/**
*blobstore项的BlobKey。
*/
私人BlobKey-BlobKey;
/**
*读卡器的当前字节位置。
*/
私人长偏移量;
/**
*水滴的总大小。
*/
私人长期总规模;
/**
*正在读取的当前输入流。
*/
私有BlobstoreInputStream currentStream;
/**
*下一个需要初始化新InputStream的点。
*/
私人长假;
/**
*上次标记时的当前流。
*/
私有BlobstoreInputStream标记为Stream;
/**
*创建一个新的ChainedBlobstoreInputStream。此流应正常工作
*与BlobstoreInputStream完全相同,应该可以
*交换它们。
* 
*@param theBlobKey
*-要读取的对象的blobkey。
*@抛出异常
*-如果读取当前流时出错,则引发。
*/
公共链接BlobStoreInputStream(最终BlobKey theBlobKey)
抛出IOException{
这(theBlobKey,0);
}
/**
*创建一个新的ChainedBlobstoreInputStream。此流应正常工作
*与BlobstoreInputStream完全相同,应该可以
*交换它们。
* 
*@param theBlobKey
*-要读取的对象的blobkey。
*@param newOffset
*-blob中从读取位置的偏移量。
*@抛出异常
*-如果读取当前流时出错,则引发。
*/
公共链接BlobStoreInputStream(最终BlobKey the BlobKey,
最后一个长(newOffset)抛出IOException{
this.offset=newOffset;
this.blobKey=theBlobKey;
最终BlobInfo BlobInfo=
新建BlobInfoFactory().loadBlobInfo(this.blobKey);
this.totalSize=blobInfo.getSize();
此.currentStream=
新的BlobstoreInputStream(this.blobKey,this.offset);
this.nextradebreak=
this.offset+ChainedBlobstoreInputStream.MAX\u READSIZE;
}
/*
*(非Javadoc)
*@see java.io.InputStream#read()
*/
@凌驾
public final int read()引发IOException{
如果(此偏移量<此总尺寸){
if(this.offset==this.nextradebreak){
this.currentStream.close();
此.currentStream=
新的BlobstoreInputStream(this.blobKey,this.offset);
this.nextradebreak=this.offset
+ChainedBlobstoreInputStream.MAX_READSIZE;
}
该偏移量+=1;
返回此.currentStream.read();
}否则{
this.currentStream.close();
返回-1;
}
}
/*
*(非Javadoc)
*@see java.io.InputStream#close()
*/
@凌驾
public final void close()引发IOException{
this.currentStream.close();
super.close();
}
/*
*(非Javadoc)
*@see java.io.InputStream#mark(int)
*/
@凌驾
公共最终无效标记(最终整型读取限制){
this.currentStream.mark(readlimit);
this.markedStream=this.currentStream;
}
/*
*(非Javadoc)
*@see java.io.InputStream#markSupported()
*/
@凌驾
支持的公共最终布尔标记(){
返回此.currentStream.markSupported();
}
/*
*(非Javadoc)
*@see java.io.InputStream#reset()
*/
@凌驾
公共最终无效重置()引发IOException{
this.currentStream=this.markedStream;
这个.currentStream.reset();
}
}

我更新了我的问题,返回的错误很简单:“从Blobstore读取数据时出错”目前我不太关心将文件读入arraylist的效率。除非在我阅读时处理它们,否则它们将绕过1mb错误,我认为不会。我也不会。我担心它的可行性。异常是什么?它抛出BlobstoreInputStream BlobstoreIOException:“Blob Fetch Size To large”并在while((entry=zis.getNextEntry())!=null)发生。