Указывая, что ZIP-файл поврежден / запрещен в Java [duplicate]

Строки в Python являются неизменяемыми (не могут быть изменены). Из-за этого эффект line.replace(...) заключается в том, чтобы создать новую строку, а не изменять старую. Вам нужно переустановить (назначить) его line, чтобы эта переменная приняла новое значение, при этом эти символы были удалены.

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

Начиная с Python 2.6 и более нового Python 2.x версии *, вы можете вместо этого использовать str.translate (но читать для различий Python 3):

line = line.translate(None, '!@#$')

или замещение регулярного выражения с помощью re.sub

import re
line = re.sub('[!@#$]', '', line)

Символы, заключенные в скобки, представляют собой класс символов . Любые символы из line, которые находятся в этом классе, заменяются вторым параметром на sub: пустая строка.

В Python 3 строки являются Unicode. Вам придется переводить немного по-другому. kevpie упоминает это в комментарии по одному из ответов, и это отмечено в документации для str.translate .

При вызове translate метод строки Unicode, вы не можете передать второй параметр, который мы использовали выше. Вы также не можете передать None в качестве первого параметра или даже таблицу переводов из string.maketrans. Вместо этого вы передаете словарь как единственный параметр. Этот словарь отображает порядковые значения символов символов (т. Е. Результат вызова ord на них) на порядковые значения символов, которые должны их заменить, или - полезно us- None, чтобы указать, что они должны быть удалены.

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

translation_table = dict.fromkeys(map(ord, '!@#$'), None)
unicode_line = unicode_line.translate(translation_table)

Здесь dict.fromkeys и map используются для краткого создания словаря, содержащего

{ord('!'): None, ord('@'): None, ...}

. Еще проще, поскольку другой ответ ставит его , создайте словарь на месте:

unicode_line = unicode_line.translate({ord(c): None for c in '!@#$'})

* для совместимости с более ранними Pythons, вы можете создать таблицу перевода «null», чтобы перейти вместо None:

import string
line = line.translate(string.maketrans('', ''), '!@#$')

Здесь string.maketrans используется для создания таблицы перевода , которая представляет собой просто строку, содержащую символы с порядковыми значениями от 0 до 255.

22
задан Bobby 21 December 2012 в 15:00
поделиться

8 ответов

Вы можете использовать класс ZipFile для проверки вашего файла:

 static boolean isValid(final File file) {
    ZipFile zipfile = null;
    try {
        zipfile = new ZipFile(file);
        return true;
    } catch (IOException e) {
        return false;
    } finally {
        try {
            if (zipfile != null) {
                zipfile.close();
                zipfile = null;
            }
        } catch (IOException e) {
        }
    }
}
27
ответ дан Jean-François Savard 25 August 2018 в 08:33
поделиться
new ZipFile(file) 

снова сжимает файл, поэтому дублируйте усилия, и это не то, что вы ищете. Несмотря на то, что проверяют только один файл и вопрос сжимают n-файлы.

Взгляните на это: http://www.kodejava.org/examples/336.html

Создайте контрольную сумму для вашего zip:

CheckedOutputStream checksum = new CheckedOutputStream(fos, new CRC32());
ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(checksum));
...

И когда вы закончите показ компрессии

System.out.println("Checksum   : " + checksum.getChecksum().getValue());

Вы должны сделать то же самое чтение zip с java или другими инструментами, проверяющими соответствие совпадений.

см. https://stackoverflow.com/a/10689488/848072 для получения дополнительной информации

1
ответ дан Community 25 August 2018 в 08:33
поделиться

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

3
ответ дан John Doe 25 August 2018 в 08:33
поделиться

в моей реализации выглядит так. возможно, это поможет вам:

//[...]

try {
    FileInputStream fis = new FileInputStream(file);
    BufferedInputStream bis = new BufferedInputStream(fis);

    zos.putNextEntry(new ZipEntry(file.getName()));

    try {
        final byte[] buf = new byte[BUFFER_SIZE];
        while (true) {
            final int len = bis.read(buf);
            if (len == -1) {
                break;
            }
            zos.write(buf, 0, len);
        }
        zos.flush();
        zos.closeEntry();
    } finally {
        try {
            bis.close();
        } catch (IOException e) {
            LOG.debug("Buffered Stream closing failed");
        } finally {
            fis.close();
        }
    }
} catch (IOException e) {
    throw new Exception(e);
}

//[...]
zos.close
2
ответ дан Sören 25 August 2018 в 08:33
поделиться

Ваш код в основном в порядке, попробуйте выяснить, какой файл отвечает за поврежденный zip-файл. Проверьте, действительно ли функция digitalFile.getFile () возвращает действительный и доступный аргумент в FileInputStream. Просто добавьте бит в свой код, и вы узнаете, что не так.

1
ответ дан stacker 25 August 2018 в 08:33
поделиться

ZipOutputStream не закрывает базовый поток.

Что вам нужно сделать:

FileOutputStream fos = new FileOutputStream(...);
ZipOutputStream zos = new ZipOutputStream(fos);

Затем в вашем закрывающем блоке:

zos.close();
fos.flush(); // Can't remember whether this is necessary off the top of my head!
fos.close();
0
ответ дан user 25 August 2018 в 08:33
поделиться

Я знаю, что прошло какое-то время, когда это было опубликовано, я использовал код, который вы указали, и придумал это. Это отлично работает для актуального вопроса. Проверка поврежденного файла zip или нет

private boolean isValid(File file) {
    ZipFile zipfile = null;
    ZipInputStream zis = null;
    try {
        zipfile = new ZipFile(file);
        zis = new ZipInputStream(new FileInputStream(file));
        ZipEntry ze = zis.getNextEntry();
        if(ze == null) {
            return false;
        }
        while(ze != null) {
            // if it throws an exception fetching any of the following then we know the file is corrupted.
            zipfile.getInputStream(ze);
            ze.getCrc();
            ze.getCompressedSize();
            ze.getName();
            ze = zis.getNextEntry();
        } 
        return true;
    } catch (ZipException e) {
        return false;
    } catch (IOException e) {
        return false;
    } finally {
        try {
            if (zipfile != null) {
                zipfile.close();
                zipfile = null;
            }
        } catch (IOException e) {
            return false;
        } try {
            if (zis != null) {
                zis.close();
                zis = null;
            }
        } catch (IOException e) {
            return false;
        }

    }
}
8
ответ дан user1707141 25 August 2018 в 08:33
поделиться

Возможно, замените следующие две строки:;

fis.close();
zos.closeEntry();

Я могу представить, что closeEntry () все равно будет считывать некоторые данные из потока.

1
ответ дан Waverick 25 August 2018 в 08:33
поделиться
Другие вопросы по тегам:

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