2010-08-05 77 views

回答

3

我已經創建了一個簡單的包裝類來解決這個問題。您應該可以直接將ChainedBlobstoreInputStream替換爲BlobstoreInputStream。我沒有測試mark(),markSupported()或reset()方法。

不管您希望如何,您都可以使用此代碼。 「從Blob存儲讀取數據時出錯」 我不是太在意的讀取文件到此刻一個ArrayList效率:

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

} 
0
while ((size = zis.read(buffer)) > 0) 
    contents.write(buffer, 0, size); 

但是,整個文件讀入內存的整個概念都有它的旋鈕。找到一種方式來處理它,當你閱讀它。

或者我得到一個錯誤。

什麼錯誤?

+0

我已經更新了我的問題與錯誤返回這是根本。除非處理它們,因爲我讀它們會得到1mb的錯誤,我認爲它不會。 – 2010-08-05 10:59:27

+0

我也不是。我關心它的可行性。什麼是例外? – EJP 2010-08-05 11:02:46

+0

它引發BlobstoreInputStream BlobstoreIOException:「Blob Fetch Size too too」併發生在while((entry = zis.getNextEntry())!= null)。 – 2010-08-05 12:11:24