2011-04-02 30 views
7

Tôi đang sử dụng App Engine (version 1.4.3) direct write the blobstore để lưu hình ảnh. khi tôi cố gắng để lưu trữ hình ảnh đó là lớn hơn 1MB tôi nhận được ngoại lệ sauGiới hạn hạn ngạch 1MB cho đối tượng blobstore trong Google App Engine?

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

Tôi nghĩ rằng limit for each object is 2GB

Đây là mã Java chứa ảnh của

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

trông giống như tách dữ liệu thành nhiều phần nhỏ hơn khiến các trick. Tôi vẫn có ngoại lệ khi tôi cố gắng lưu trữ dữ liệu lớnBản ghi lưu trữ (có giới hạn cứng là 1MB). vì dấu vết ngăn xếp ngoại lệ nằm trong một chủ đề khác, tôi nghĩ đó là blobStore gây ra sự cố. Google: bạn nợ tôi vài giờ gỡ lỗi –

+0

Nếu bạn đã bao gồm stacktrace (hoặc xem xét kỹ), chúng tôi có thể đã giúp. –

+0

* CẬP NHẬT * mã trên dường như hoạt động đối với tôi. Dường như không còn giới hạn 1 mb nữa ... – itgiawa

Trả lời

3

Kích thước đối tượng tối đa là 2 GB nhưng mỗi lệnh gọi API chỉ có thể xử lý tối đa 1 MB. Ít nhất là để đọc, nhưng tôi cho rằng nó có thể giống nhau cho việc viết. Vì vậy, bạn có thể cố gắng để chia văn bản của bạn của đối tượng thành khối 1 MB và xem nếu điều đó giúp.

+0

Tôi đã cố gắng chia văn bản thành nhiều lời gọi writeChannel.write nhưng có cùng kết quả –

+0

"Mỗi cuộc gọi API chỉ có thể xử lý tối đa 1 MB" có nghĩa là gì? API nào? có nghĩa là 1MB cho mỗi (ứng dụng của tôi) yêu cầu? –

+0

Không, tôi đoán rằng điều đó có nghĩa là mỗi lần gọi hàm ít nhiều, không phải yêu cầu web kích hoạt bạn đang viết mã (nếu không sẽ không có cách nào xử lý nhiều hơn 1 MB). – Brummo

3

Như Brummo đã đề xuất ở trên nếu bạn chia thành các đoạn < 1MB, nó hoạt động. Đây là một số mã.

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); 
} 
+1

Có hằng số cho kích thước tìm nạp tối đa trong BlobstoreService.MAX_BLOB_FETCH_SIZE = 1015808. Tôi đã thử nghiệm điều này trong một bài kiểm tra đơn vị cục bộ và nó hoạt động cho cả đọc và viết. – bigspotteddog

5

Dưới đây là cách tôi đọc và ghi các file lớn:

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); 
} 
Các vấn đề liên quan