Экстрактинг Zip на SD-карту происходит очень медленно. Как я могу оптимизировать производительность?

Мое приложение загружает zip примерно с 350 файлами. Смесь JPG и HTML-файлов. Функция, которую я написал, чтобы делать это, работает отлично, но распаковка берет навсегда. Сначала я подумал, что причиной может быть то, что запись на SD-карту происходит медленно. Но когда я разархивирую один и тот же почтовый индекс с другим приложением на своем телефоне, он работает намного быстрее. Есть ли что-нибудь, что я мог бы сделать, чтобы его оптимизировать?

Вот код:

private void extract() { try { FileInputStream inStream = new FileInputStream(targetFilePath); ZipInputStream zipStream = new ZipInputStream(new BufferedInputStream(inStream)); ZipEntry entry; ZipFile zip = new ZipFile(targetFilePath); //i know the contents for the zip so i create the dirs i need in advance new File(targetFolder).mkdirs(); new File(targetFolder + "META-INF").mkdir(); new File(targetFolder + "content").mkdir(); int extracted = 0; while((entry = zipStream.getNextEntry()) != null) { if (entry.isDirectory()) { new File(targetFolder + entry.getName()).mkdirs(); } else { FileOutputStream outStream = new FileOutputStream(targetFolder + entry.getName()); for (int c = zipStream.read(); c != -1; c = zipStream.read()) { outStream.write(c); } zipStream.closeEntry(); outStream.close(); extracted ++; } publishProgress(""+(int)extracted*100/zip.size()); } zipStream.close(); inStream.close(); // new File(targetFilePath).delete(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } 

Благодаря CommonsWare я изменил свой код следующим образом:

  int size; byte[] buffer = new byte[2048]; FileOutputStream outStream = new FileOutputStream(targetFolder + 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(); 

Большой разница в производительности. Большое спасибо.

Solutions Collecting From Web of "Экстрактинг Zip на SD-карту происходит очень медленно. Как я могу оптимизировать производительность?"

Вы читаете и записываете байт за раз. Рассмотрите возможность чтения и записи большего блока за раз.

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

  public boolean rajDhaniSuperFastUnzip(String inputZipFile, String destinationDirectory) { try { int BUFFER = 2048; List<String> zipFiles = new ArrayList<String>(); File sourceZipFile = new File(inputZipFile); File unzipDestinationDirectory = new File(destinationDirectory); unzipDestinationDirectory.mkdir(); ZipFile zipFile; zipFile = new ZipFile(sourceZipFile, ZipFile.OPEN_READ); Enumeration<?> zipFileEntries = zipFile.entries(); while (zipFileEntries.hasMoreElements()) { ZipEntry entry = (ZipEntry) zipFileEntries.nextElement(); String currentEntry = entry.getName(); File destFile = new File(unzipDestinationDirectory, currentEntry); if (currentEntry.endsWith(".zip")) { zipFiles.add(destFile.getAbsolutePath()); } File destinationParent = destFile.getParentFile(); destinationParent.mkdirs(); try { if (!entry.isDirectory()) { BufferedInputStream is = new BufferedInputStream(zipFile.getInputStream(entry)); int currentByte; byte data[] = new byte[BUFFER]; FileOutputStream fos = new FileOutputStream(destFile); BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER); while ((currentByte = is.read(data, 0, BUFFER)) != -1) { dest.write(data, 0, currentByte); } dest.flush(); dest.close(); is.close(); } } catch (IOException ioe) { ioe.printStackTrace(); } } zipFile.close(); for (Iterator<String> iter = zipFiles.iterator(); iter.hasNext();) { String zipName = (String)iter.next(); doUnzip( zipName, destinationDirectory + File.separatorChar + zipName.substring(0,zipName.lastIndexOf(".zip")) ); } } catch (IOException e) { e.printStackTrace(); return false ; } return true; } -  public boolean rajDhaniSuperFastUnzip(String inputZipFile, String destinationDirectory) { try { int BUFFER = 2048; List<String> zipFiles = new ArrayList<String>(); File sourceZipFile = new File(inputZipFile); File unzipDestinationDirectory = new File(destinationDirectory); unzipDestinationDirectory.mkdir(); ZipFile zipFile; zipFile = new ZipFile(sourceZipFile, ZipFile.OPEN_READ); Enumeration<?> zipFileEntries = zipFile.entries(); while (zipFileEntries.hasMoreElements()) { ZipEntry entry = (ZipEntry) zipFileEntries.nextElement(); String currentEntry = entry.getName(); File destFile = new File(unzipDestinationDirectory, currentEntry); if (currentEntry.endsWith(".zip")) { zipFiles.add(destFile.getAbsolutePath()); } File destinationParent = destFile.getParentFile(); destinationParent.mkdirs(); try { if (!entry.isDirectory()) { BufferedInputStream is = new BufferedInputStream(zipFile.getInputStream(entry)); int currentByte; byte data[] = new byte[BUFFER]; FileOutputStream fos = new FileOutputStream(destFile); BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER); while ((currentByte = is.read(data, 0, BUFFER)) != -1) { dest.write(data, 0, currentByte); } dest.flush(); dest.close(); is.close(); } } catch (IOException ioe) { ioe.printStackTrace(); } } zipFile.close(); for (Iterator<String> iter = zipFiles.iterator(); iter.hasNext();) { String zipName = (String)iter.next(); doUnzip( zipName, destinationDirectory + File.separatorChar + zipName.substring(0,zipName.lastIndexOf(".zip")) ); } } catch (IOException e) { e.printStackTrace(); return false ; } return true; } 

Надеюсь, это поможет вам. Счастливое кодирование 🙂