Строки в 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.
Вы можете использовать класс 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) {
}
}
}
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 для получения дополнительной информации
Я думаю, вы увидите трассировку стека корреспондентов при генерации zip-файла. Таким образом, вы, вероятно, не улучшите обработку исключений.
в моей реализации выглядит так. возможно, это поможет вам:
//[...]
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
Ваш код в основном в порядке, попробуйте выяснить, какой файл отвечает за поврежденный zip-файл. Проверьте, действительно ли функция digitalFile.getFile () возвращает действительный и доступный аргумент в FileInputStream. Просто добавьте бит в свой код, и вы узнаете, что не так.
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();
Я знаю, что прошло какое-то время, когда это было опубликовано, я использовал код, который вы указали, и придумал это. Это отлично работает для актуального вопроса. Проверка поврежденного файла 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;
}
}
}
Возможно, замените следующие две строки:;
fis.close();
zos.closeEntry();
Я могу представить, что closeEntry () все равно будет считывать некоторые данные из потока.