Приблизительно сжатый размер перед добавлением файла в ZIP [дубликат]

В то время как , что вызывает NullReferenceExceptions и подходит к avoid / fix , такое исключение было рассмотрено в других ответах, что многие программисты не имеют " t узнал еще, как независимо отлаживать такие исключения во время разработки.

В Visual Studio это обычно легко благодаря Visual Studio Debugger .


Во-первых, убедитесь, что правильная ошибка будет обнаружена - см. . Как разрешить нарушение «Исключение System.NullReferenceException» в VS2010? Примечание1

Затем либо Начать с отладки (F5) , либо Приложить [отладчик VS] к запуску процесса . Иногда может быть полезно использовать Debugger.Break , в котором будет предложено запустить отладчик.

Теперь, когда NullReferenceException выбрано (или необработанно), отладчик остановится ( помните правило, указанное выше?) в строке, на которой произошло исключение. Иногда ошибка может быть легко обнаружена.

Например, в следующей строке единственный код, который может , вызывает исключение, если myString имеет значение null. Это можно проверить, посмотрев окно Watch или выполнив выражения в окне Immediate Window .

var x = myString.Trim();

В более сложных случаях, таких как следуя ниже, вам нужно будет использовать один из методов выше (Watch или Immediate Windows) для проверки выражений, чтобы определить, было ли str1 пустым или если str2 имеет значение null.

var x = str1.Trim() + str2.Trim();

Once , где было выбрано исключение, это обычно тривиально по отношению к разуму назад, чтобы выяснить, где введенное значение null было [неправильно] -

. Найдите время, необходимое для понимания причина исключения. Проверьте нулевые выражения. Проверьте предыдущие выражения, которые могли бы привести к таким нулевым выражениям. Добавьте контрольные точки и, по мере необходимости, пройдите через программу. Используйте отладчик.


1 Если Break on Throws слишком агрессивен и отладчик останавливается на NPE в библиотеке .NET или сторонних разработчиков, Break на User-Unhandled можно использовать для ограничения выловленных исключений. Кроме того, VS2012 представляет Just My Code , который я рекомендую также включить.

Если вы отлаживаете с включенным Just My Code, поведение немного отличается. При включенном Just My Code отладчик игнорирует исключения, связанные с привилегиями обычного языка (CLR) первого шанса, которые выходят за пределы My Code и не проходят через My Code

blockquote>

12
задан Vignesh 26 August 2010 в 07:05
поделиться

7 ответов

Возможно, вы могли бы добавлять файл каждый раз, пока не достигнете предела 5 МБ, а затем отбросьте последний файл. Как и @Gopi, я не думаю, что есть какой-либо способ оценить его без фактического сжатия файла.

Конечно, размер файла не будет увеличиваться (или, может быть, немного из-за zip-заголовка?) , так что по крайней мере у вас есть оценка «наихудшего случая».

1
ответ дан AJPerez 28 August 2018 в 04:18
поделиться

просто хотел поделиться, как мы реализовали ручной способ

            int maxSizeForAllFiles = 70000; // Read from property
        int sizePerFile = 22000; // Red from property
        /**
         * Iterate all attachment list to verify if ZIP is required
         */
        for (String attachFile : inputAttachmentList) {
            File file = new File(attachFile);
            totalFileSize += file.length();
            /**
             * if ZIP required ??? based on the size
             */
            if (file.length() >= sizePerFile) {
                toBeZipped = true;
                logger.info("File: "
                            + attachFile
                                + " Size: "
                                + file.length()
                                + " File required to be zipped, MAX allowed per file: "
                                + sizePerFile);
                break;
            }
        }
        /**
         * Check if all attachments put together cross MAX_SIZE_FOR_ALL_FILES
         */
        if (totalFileSize >= maxSizeForAllFiles) {
            toBeZipped = true;
        }
        if (toBeZipped) {
            // Zip Here iterating all attachments
        }
0
ответ дан Anand 28 August 2018 в 04:18
поделиться

+1 для Колина Герберта: добавьте файлы один за другим, либо создайте резервную копию предыдущего шага, либо удалите последний файл, если архив большой. Я просто хочу добавить некоторые подробности:

Прогноз слишком ненадежный. Например. PDF может содержать несжатый текст и сжимать до 30% оригинала или содержать уже сжатый текст и изображения, сжимающий до 80%. Вам нужно будет проверить весь PDF для сжимаемости, в основном, чтобы сжать их.

Вы можете попробовать статистическое предсказание, но это может уменьшить количество неудачных попыток, но вам все равно придется выполнить вышеприведенную рекомендацию. Идите с более простой реализацией, и посмотрите, достаточно ли этого.

Кроме того, сжимайте файлы по отдельности, а затем выбирайте файлы, которые не превышают 5 МБ, если они связаны друг с другом. Если распаковка также автоматизирована, вы можете связать zip-файлы с одним несжатым zip-файлом.

1
ответ дан Asaph 28 August 2018 в 04:18
поделиться

Оберните свой ZipOutputStream в персонализированный OutputStream, названный здесь YourOutputStream.

  • Конструктор YourOutputStream создаст еще один ZipOutputStream (zos2), который обертывает новый ByteArrayOutputStream (baos) public YourOutputStream(ZipOutputStream zos, int maxSizeInBytes)
  • Если вы хотите записать файл с YourOutputStream, он сначала напишет его на zos2 public void writeFile(File file) throws ZipFileFullException public void writeFile(String path) throws ZipFileFullException и т. д. .
  • , если baos.size() находится под maxSizeInBytes Записать файл в zos1
  • else закрыть zos1, baos, zos2 сделать исключение. Для исключения я не могу думать о уже существовавшем, если есть, использовать его, иначе создать собственное исключение IOException ZipFileFullException.

Вам нужно два ZipOutputStream, один из которых должен быть записан на вашем диске, чтобы проверить, превышает ли ваше содержимое более 5 МБ.

EDIT: Фактически я проверил, вы не можете легко удалить ZipEntry .

http://download.oracle.com/javase/6/docs/api/java/io/ByteArrayOutputStream.html# размер ()

8
ответ дан Colin Hebert 28 August 2018 в 04:18
поделиться

Я не думаю, что есть способ оценить размер zip, который будет создан, потому что почтовые индексы обрабатываются как потоки. Кроме того, технически невозможно предсказать размер созданного сжатого формата, если вы фактически не сжимаете его.

0
ответ дан Gopi 28 August 2018 в 04:18
поделиться

Есть лучший вариант. Создайте манекен LengthOutputStream, который просто учитывает записанные байты:

public class LengthOutputStream extends OutputStream {

    private long length = 0L;

    @Override
    public void write(int b) throws IOException {
        length++;
    }

    public long getLength() {
        return length;
    }
}

Вы можете просто подключить LengthOutputStream к ZipOutputStream:

public static long sizeOfZippedDirectory(File dir) throws FileNotFoundException, IOException {
        try (LengthOutputStream sos = new LengthOutputStream();
            ZipOutputStream zos = new ZipOutputStream(sos);) {
            ... // Add ZIP entries to the stream
            return sos.getLength();
        }
    }

Кнопка LengthOutputStream подсчитывает байты заархивированного потока, но ничего не сохраняет, поэтому ограничение размера файла отсутствует. Этот метод дает точную оценку размера, но почти так же медленно, как создание ZIP-файла.

0
ответ дан JHead 28 August 2018 в 04:18
поделиться

Я сделал это один раз в проекте с известными типами ввода. Мы знали, что общие слова наши данные сжаты около 5: 1 (это был весь текст.) Итак, я бы проверил размер файла и разделил его на 5 ...

В этом случае цель так что нужно было проверить, что файлы, вероятно, будут ниже определенного размера. Нам понадобилась только приблизительная оценка.

Все, что сказал, я заметил, что zip-приложения, такие как 7zip, будут создавать zip-файл определенного размера (например, CD), а затем разделить zip на новый файл один раз он достигает предела. Вы можете посмотреть на этот исходный код. Раньше я использовал версию командной строки этого приложения в коде. У них есть библиотека, которую вы можете использовать. Не знаю, насколько хорошо это будет интегрироваться с Java.

Для чего это стоит, я также использовал библиотеку SharpZipLib. Это было очень хорошо. Интересно, есть ли для него порт Java.

0
ответ дан Nate 28 August 2018 в 04:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: