You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从URL直接提取tar文件?Java实现方案咨询

直接从URL提取tar.xz文件的问题及解决方案

问题描述

需要直接从远程URL流式提取tar文件,目标示例文件为freedict-deu-eng-1.9-fd1.dictd.tar.xz。尝试用JDK自带的GZIPInputStream结合URLConnection实现,代码如下:

URL url = new URL(zipFileUrl);
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
InputStream inputStream = connection.getInputStream();
GZIPInputStream gzipInputStream = new GZIPInputStream(inputStream);

运行后触发错误:java.util.zip.ZipException: Not in GZIP format。

目前可以通过先下载文件到本地、提取后删除的方式解决,但这种方案用户体验差,希望找到类似ZipInputStream遍历ZipEntry的流式处理方案。

解决方案

JDK自带的GZIPInputStream仅支持gzip压缩格式,而目标文件采用的是xz压缩算法,需要借助第三方库实现流式解压:

方案1:使用Apache Commons Compress(推荐)

这是Java生态中处理压缩归档的常用库,支持多种格式,API稳定且公开。

  1. 引入Maven依赖:
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-compress</artifactId>
    <version>1.24.0</version>
</dependency>
  1. 流式解压并处理tar条目:
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.compressors.xz.XZCompressorInputStream;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

public class TarXzStreamHandler {
    public static void main(String[] args) throws IOException {
        String targetUrl = "https://download.freedict.org/dictionaries/deu-eng/1.9-fd1/freedict-deu-eng-1.9-fd1.dictd.tar.xz";
        URL url = new URL(targetUrl);
        URLConnection connection = url.openConnection();
        
        try (InputStream rawStream = connection.getInputStream();
             XZCompressorInputStream xzStream = new XZCompressorInputStream(rawStream);
             TarArchiveInputStream tarStream = new TarArchiveInputStream(xzStream)) {
            
            TarArchiveEntry entry;
            while ((entry = tarStream.getNextTarEntry()) != null) {
                if (!entry.isDirectory()) {
                    System.out.println("处理文件:" + entry.getName());
                    // 读取文件内容并处理,示例:写入本地或内存处理
                    byte[] buffer = new byte[1024];
                    int readBytes;
                    while ((readBytes = tarStream.read(buffer)) != -1) {
                        // 这里添加自定义处理逻辑,比如写入输出流
                    }
                }
            }
        }
    }
}

方案2:使用单独的XZ压缩库

如果不想引入完整的Commons Compress,可以使用专门的XZ Java库:

  1. 引入Maven依赖:
<dependency>
    <groupId>org.tukaani</groupId>
    <artifactId>xz</artifactId>
    <version>1.9</version>
</dependency>
  1. 结合JDK非公开API的TarInputStream(注意:该API属于Sun/Oracle私有实现,可能在不同JDK版本中存在兼容性问题):
import org.tukaani.xz.XZInputStream;
import com.sun.tools.tar.TarInputStream;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

public class XzTarStreamHandler {
    public static void main(String[] args) throws IOException {
        String targetUrl = "https://download.freedict.org/dictionaries/deu-eng/1.9-fd1/freedict-deu-eng-1.9-fd1.dictd.tar.xz";
        URL url = new URL(targetUrl);
        URLConnection connection = url.openConnection();
        
        try (InputStream rawStream = connection.getInputStream();
             XZInputStream xzStream = new XZInputStream(rawStream);
             TarInputStream tarStream = new TarInputStream(xzStream)) {
            
            com.sun.tools.tar.TarEntry entry;
            while ((entry = tarStream.getNextEntry()) != null) {
                if (!entry.isDirectory()) {
                    System.out.println("处理文件:" + entry.getName());
                    byte[] buffer = new byte[1024];
                    int readBytes;
                    while ((readBytes = tarStream.read(buffer)) != -1) {
                        // 自定义处理逻辑
                    }
                }
            }
        }
    }
}

关键说明

  • 报错根源:GZIPInputStream仅能解析gzip格式(.gz),而目标文件是xz压缩格式(.xz),两种压缩算法不兼容,因此抛出格式错误。
  • 流式处理优势:无需下载完整文件到本地,边下载边解压处理,节省磁盘空间同时提升响应效率。

内容的提问来源于stack exchange,提问作者Lasnik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 08:09:57