java - 我的代码有什么问题吗?为什么压缩和解压速度比其他应用慢?

标签 java android performance compression xz

我正在创建使用 xz 压缩方法的压缩和解压缩应用程序。但是压缩和解压缩速度比另一个同样使用相同压缩方法的应用程序要慢。例如,我尝试将 15mb 的文件解压缩为 40mb 的文件,我的代码大约需要 18 秒,而在另一个应用程序上只需要大约 4 秒。

我正在使用来自 XZ for Java 的 XZInputStream和来自 Apache Common Compress 的 TarArchiveInputStream

public static void decompress(File file, String targetPath) {
    try {
        File outputFile = new File(targetPath);
        FileInputStream fileInputStream = new FileInputStream(file);
        XZInputStream xzInputStream = new XZInputStream(fileInputStream);
        TarArchiveInputStream tarInputStream = new TarArchiveInputStream(xzInputStream);
        TarArchiveEntry entry;
        while ((entry = tarInputStream.getNextTarEntry()) != null) {
            if (entry.isDirectory()) {
                continue;
            }
            File curFile = new File(outputFile, entry.getName());
            File parent = curFile.getParentFile();
            if (!parent.exists()) {
                parent.mkdirs();
            }
            IOUtils.copy(tarInputStream, new FileOutputStream(curFile));
        }
    } catch (FileNotFoundException e) {
        Log.e("Exception", Log.getStackTraceString(e));
    } catch (IOException e) {
        Log.e("Exception", Log.getStackTraceString(e));
    }
}

最佳答案

我不知道您正在使用的库的性能。但是,我可以在这里放弃我的建议,这可能会帮助您提高性能。

看起来您在 while 循环中使用这个大型操作阻塞了 UI 线程。我想建议您创建一个 AsyncTask,然后将代码放在 doInBackground 函数中,这样不会阻塞 UI 线程,操作将由后台线程。

谈到使用后台线程。您也可以考虑使用多线程来解压缩文件。我不确定如何做到这一点,但是,我可能会提出如下想法。

while ((entry = tarInputStream.getNextTarEntry()) != null) {
    if (entry.isDirectory()) continue;

    File curFile = new File(outputFile, entry.getName());
    File parent = curFile.getParentFile();
    if (!parent.exists()) {
        parent.mkdirs();
    }

    // Create a thread for each of these operations and do it in background. 
    // Thus you can take the advantage of using multiple threads to process your operations faster
    // Instead of passing the whole tarInputStream, just pass the entry and check if that works.
    IOUtils.copy(entry, new FileOutputStream(curFile));
}

希望对您有所帮助!

更新

我认为从 InputStream 复制会花费很多时间,因此您可以考虑将 BufferedInputStream 放在这些中间,如下所示。

FileInputStream fileInputStream = new FileInputStream(file);
BufferedInputStream bin = new BufferedInputStream(fileInputStream); 
XZInputStream xzInputStream = new XZInputStream(bin);

关于java - 我的代码有什么问题吗?为什么压缩和解压速度比其他应用慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55860331/

相关文章:

java - 为什么我使用 Android 的 Java 得到这个总和的奇怪结果?

java - 使用java获取 cucumber 中未定义的场景和步骤

Javascript 游戏 - IIFE 之间的废物管理

java - Clone() vs Copy constructor - 在java中推荐

java - Runtime.exec - 适合 'echo' '但不适用于猫...

android - 我可以以编程方式更改强调色 (AppCompat) 吗?

android - 如何将 widget.TextInputLayout 与 MaterialSpinner View 对齐?

android - 在 android 中获取 4.1 及更高版本的通知

c++ - 我应该在我的函数中使用静态变量来防止重新计算值吗?

java - 我的 SQLPreparedStatement 有什么问题?