распаковка изображений в интернет-магазин - PullRequest
4 голосов
/ 07 декабря 2011

в моем приложении мне нужно сделать следующее: 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);
            }

1 Ответ

1 голос
/ 13 апреля 2012

Из-за zis.read (buffer) может не заполнить весь буфер.

Вместо этого используйте следующее

int len;
while((len = zis.read(buffer)) >= 0){
  ByteBuffer bb = ByteBuffer.wrap(buffer, 0, len);
  writeChannel.write(bb);
}

Надеюсь, что эта помощь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...