android ZipArchiveEntry дает java.nio.charset.MalformedInputException
Я могу разархивировать 1-ю и 2-ю запись zip-файла, который я читаю из Интернета, но затем я получаю ошибку MalformedInputException. Zip-файл состоит из имен файлов Unicode mp3-файлов. Я создал zip-файл, который я разместил в Интернете с помощью Winzip (я пробовал как v11, так и V18).
Все mp3-файлы находятся на уровне "root" в zip-файле, то есть не хранятся в подпапках.
Я попробовал сначала с ZipInputStream. Последняя попытка (ниже) - с ArchiveInputStream. (Я заметил, что ArchiveInputStream не имеет метода closeEntry(), такого как ZipInputStream - не то чтобы это имело значение).
Ошибка всегда возникает в строке, которая получает следующую запись.while ((entry = (ZipArchiveEntry)zipStream.getNextEntry()) != null)
Код
private void unizpMediaFile(String mediaDirectory, String zipFileURL) {
InputStream inputStream = null;
ArchiveInputStream zipStream = null;
ArchiveEntry entry = null;
try {
// make sure can write to (probably) sd card
File mediaFileDirectory = createMediaDirectory(mediaDirectory);
if (mediaFileDirectory == null)
return;
inputStream = getHttpInputStream(zipFileURL);
if (inputStream == null) {
return;
}
zipStream = new ArchiveStreamFactory().createArchiveInputStream(ArchiveStreamFactory.ZIP,new BufferedInputStream(
inputStream) );
while ((entry = (ZipArchiveEntry)zipStream.getNextEntry()) != null) {
Log.i(TAG,"Entry:" + entry.getName());
if (entry.isDirectory()) {
if (false == new File( mediaFileDirectory.getAbsoluteFile()
+ File.separator + entry.getName()).mkdirs()) {
return;
}
} else {
OutputStream out = new FileOutputStream(mediaFileDirectory.getAbsoluteFile()
+ File.separator + entry.getName());
int size;
byte[] buffer = new byte[4096];
FileOutputStream outStream = new FileOutputStream(
mediaFileDirectory.getAbsoluteFile()
+ File.separator + entry.getName());
BufferedOutputStream bufferOut = new BufferedOutputStream(
outStream, buffer.length);
while ((size = zipStream.read(buffer, 0, buffer.length)) != -1) {
bufferOut.write(buffer, 0, size);
}
bufferOut.flush();
bufferOut.close();
out.close();
Log.i(TAG,"Entry:" + entry.getName() + " closed.");
}
}
maintOpDetails.append(res.getString(R.string.load_complete));
updateLoadDetails(maintOpDetails.toString() );
} catch (FileNotFoundException e) {
Log.e(TAG, "unizpMediaFile" + e.toString());
storeErrorMessage(res.getString(R.string.error_reading_media_zip_file,
zipFileURL, e.toString()));
} catch (IOException e) {
Log.e(TAG, "unizpMediaFile" + e.toString());
storeErrorMessage(res.getString(R.string.error_reading_media_zip_file,
zipFileURL, e.toString()));
} catch (ArchiveException e) {
Log.e(TAG, "unizpMediaFile" + e.toString());
storeErrorMessage(res.getString(R.string.error_reading_media_zip_file,
zipFileURL, e.toString()));
}
finally {
if (inputStream != null){ try {inputStream.close();} catch (Exception e){} }
if (zipStream != null){ try {zipStream.close();} catch (Exception e){} }
}
}
private InputStream getHttpInputStream(String url) {
HttpResponse response;
InputStream is = null;
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httppost = new HttpGet("http://" + url);
try {
response = httpClient.execute(httppost);
HttpEntity ht = response.getEntity();
BufferedHttpEntity buf;
buf = new BufferedHttpEntity(ht);
is = buf.getContent();
} catch (ClientProtocolException e) {
Log.e(TAG, "getHttpInputStream" + e.toString());
storeErrorMessage(res.getString(R.string.error_reading_file_at_url,
url, e.toString()));
} catch (ConnectTimeoutException cte) {
Log.e(TAG, "getHttpInputStream" + cte.toString());
storeErrorMessage(res.getString(R.string.connect_timetout_error, url));
} catch (IOException e) {
Log.e(TAG, "getHttpInputStream" + e.toString());
storeErrorMessage(res.getString(R.string.error_reading_file_at_url,
url, e.toString()));
}
return is;
}
Из журнала я получаю
I/LoadLanguageLessonService(3102): Entry:evet.mp3
I/LoadLanguageLessonService(3102): Entry:evet.mp3 closed.
I/LoadLanguageLessonService(3102): Entry:hay?r.mp3
I/LoadLanguageLessonService(3102): Entry:hay?r.mp3 closed.
E/LoadLanguageLessonService(3102): unizpMediaFilejava.nio.charset.MalformedInputException: Length: 1
(Вырезание / вставка из журнала сюда привела к тому, что значения имени файла в юникоде были преобразованы в "?", Который вы видите выше.)
Я проверил различные SO сообщения без удачи.
Есть идеи?
Некоторое продолжение
Я изменил свой код, чтобы сначала загрузить файл zip на телефон, а затем распаковать его оттуда. Не повезло, если ты так поступишь.
Я также использовал следующий код
ZipFile zipFile = null;
try {
zipFile = new ZipFile(zipFilename);
Enumeration<?> enu = zipFile.entries();
while (enu.hasMoreElements()) {
ZipEntry zipEntry = (ZipEntry) enu.nextElement();
String name = zipEntry.getName();
long size = zipEntry.getSize();
long compressedSize = zipEntry.getCompressedSize();
Log.e(TAG, String.format("name: %-20s | size: %6d | compressed size: %6d\n",
name, size, compressedSize));
}
} catch (IOException e) {
e.printStackTrace();
throw e;
}
перечислить все записи в zip-файле и обнаружить, что все символы Юникода отображаются в виде маленького черного ромба с вопросительным знаком внутри (после вырезания / вставки в SO символы отображаются только со знаком?).
Я также скачал AndroZip и WinZip для Android и просматривал zip-файл в обоих приложениях на своем телефоне. Снова имена файлов Unicode были повреждены.
На данный момент я застрял. Я думаю, что я переключу передачи и посмотрю о загрузке файлов один за другим.