в моем приложении мне нужно сделать следующее:
1. ZIP-файл с изображениями (только в формате jpgs) и другими материалами загружается в BlobStore.
2. серверная часть движка приложения должна прочитать записи из загруженного zip-файла и сохранить все изображения, найденные внутри, в BlobStore как отдельные файлы.
Я успешно загружаю, распаковываю и сохраняю файлы @ blobstore, но изображения, кажется, повреждены.
когда я загружаю их из BlobStore (просто blobstoreService.serve их), изображения имеют неправильные цвета, или отображаются частично, или ломаются другими способами. попытка использовать ImagesService также вызывает исключение. я проверил размер изображений перед их упаковкой и размер файлов, распакованных при записи в blobstore, и они выглядят одинаково. вот мой код:
ZipInputStream zis = ...;
ZipEntry entry;
while ((entry =zis.getNextEntry()) !=null)
{
String fileName = entry.getName().toLowerCase();
if(fileName.indexOf(".jpg") != -1 || fileName.indexOf(".jpeg") != -1)
{
FileService fileService = FileServiceFactory.getFileService();
String mime = ctx.getMimeType(fileName);//getting mime from servlet context
AppEngineFile file = fileService.createNewBlobFile(mime, fileName);
boolean lock = true;
FileWriteChannel writeChannel = fileService.openWriteChannel(file, lock);
byte[] buffer = new byte[BlobstoreService.MAX_BLOB_FETCH_SIZE];
while(zis.read(buffer) >= 0)
{
ByteBuffer bb = ByteBuffer.wrap(buffer);
writeChannel.write(bb);
}
writeChannel.closeFinally();
BlobKey coverKey = fileService.getBlobKey(file);
....
}
}
Большое спасибо за ваше время!
UPD: я нашел обходной путь, который работает, но я все еще не понимаю, почему не удалось первое решение.
int read;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while((read = zis.read()) >= 0)
{
baos.write(read);
if(baos.size() == BlobstoreService.MAX_BLOB_FETCH_SIZE)
{
ByteBuffer bb = ByteBuffer.wrap(baos.toByteArray());
writeChannel.write(bb);
baos = new ByteArrayOutputStream();
}
}
if(baos.size() > 0)
{
ByteBuffer bb = ByteBuffer.wrap(baos.toByteArray());
writeChannel.write(bb);
}