Загрузка большого двоичного объекта в блоке хранилища Azure из примера Android

#java #android #azure-blob-storage #azure-storage

#java #Android #azure-blob-хранилище #azure-хранилище

Вопрос:

Я использую следующий код из приложения Android для загрузки большого двоичного объекта в хранилище больших двоичных объектов Azure. Примечание: sasUrl приведенный ниже параметр представляет собой подписанный URL-адрес, полученный из моей веб-службы :

     // upload file to azure blob storage
    private static Boolean upload(String sasUrl, String filePath, String mimeType) {
        try {
            // Get the file data
            File file = new File(filePath);
            if (!file.exists()) {           
                    return false;
            }

            String absoluteFilePath = file.getAbsolutePath();

            FileInputStream fis = new FileInputStream(absoluteFilePath);
            int bytesRead = 0;
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            while ((bytesRead = fis.read(b)) != -1) {
                bos.write(b, 0, bytesRead);
            }
            fis.close();
            byte[] bytes = bos.toByteArray();
            // Post our image data (byte array) to the server
            URL url = new URL(sasUrl.replace(""", ""));
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setDoOutput(true);
            urlConnection.setConnectTimeout(15000);
            urlConnection.setReadTimeout(15000);
            urlConnection.setRequestMethod("PUT");
            urlConnection.addRequestProperty("Content-Type", mimeType);
            urlConnection.setRequestProperty("Content-Length", ""   bytes.length);
            urlConnection.setRequestProperty("x-ms-blob-type", "BlockBlob");
            // Write file data to server
            DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream());
            wr.write(bytes);
            wr.flush();
            wr.close();
            int response = urlConnection.getResponseCode();
            if (response == 201 amp;amp; urlConnection.getResponseMessage().equals("Created")) {
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
 

Код отлично работает для небольших больших двоичных объектов, но когда большой двоичный объект достигает определенного размера в зависимости от телефона, с которым я тестирую, я начинаю получать исключения из памяти. Я хотел бы разделить большие двоичные объекты и загружать их по блокам. Однако все примеры, которые я нахожу в Интернете, основаны на C # и используют клиентскую библиотеку хранилища. Я ищу пример Java / Android, который загружает большой двоичный объект блоками, используя Azure Storage Rest API.

Ответ №1:

Здесь опубликована библиотека Azure Storage для Android. Базовый пример хранилища больших двоичных объектов находится в папке samples. Метод, который вы, вероятно, хотели бы использовать, — это uploadFromFile в классе blob. По умолчанию будет предпринята попытка поместить большой двоичный объект в один put, если его размер меньше 64 МБ, и в противном случае отправить большой двоичный объект блоками по 4 МБ. Если вы хотите уменьшить ограничение в 64 МБ, вы можете установить свойство singleBlobPutThresholdInBytes для объекта BlobRequestOptions либо CloudBlobClient (которое повлияет на все запросы), либо передать методу uploadFromFile (чтобы повлиять только на этот запрос).). Библиотека хранилища включает в себя множество удобных функций, таких как автоматические повторные попытки и максимальное время ожидания выполнения для запросов ввода блоков, которые все настраиваются.

Если вы все еще хотите использовать более ручной подход, ссылки на API PutBlock и Put Block List находятся здесь и предоставляют общую межъязыковую документацию. У них есть приятные оболочки в классе CloudBlockBlob библиотеки Azure Storage Android, называемые uploadBlock и commitBlockList, которые могут сэкономить вам много времени при построении запроса вручную и могут предоставить некоторые из вышеупомянутых удобств.

Комментарии:

1. Спасибо! Я не могу поверить, что не сталкивался с этой библиотекой и каким-то образом продолжал возвращаться к клиентской библиотеке мобильных служб. Однако, большинство методов в классе CloudBlockBlob ожидают, что я предоставлю имя и ключ своей учетной записи хранилища. Я не уверен, что распространять их с помощью моего приложения — хорошая идея.

2. Определенно не распространяйте учетную запись / ключ! Используйте либо политику общего доступа, либо подпись общего доступа. Дополнительная информация о SAS здесь и здесь . Более подробно здесь обсуждается общедоступный доступ. Подходящими API, на которые следует обратить внимание, являются container uploadPermissions, blob / container generateSharedAccessSignature, а также классы BlobContainerPermissions и SharedAccessBlobPolicy.

3. Очень полезно. но я не могу найти какую-либо функцию, связанную с уведомлением о завершении загрузки или загрузки, как я могу это сделать?

4. @EmilyGerner, спасибо за ссылку. Поддерживается ли проект на Github? Я вижу, что последний коммит был 3 года назад. Можем ли мы по-прежнему использовать эту библиотеку? Спасибо за ваше время.

5. Я думаю, что новейший доступный для java / Android this:docs.microsoft.com/en-us/java/api/overview/azure /…