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

Java环境下MP3文件下载不完整问题求助

问题:提取MP3下载链接后,仅能下载1.13MB文件即中断

我需要通过下述API获取MP3下载链接并完成下载:

https://api.vevioz.com/@api/button/mp3/AKX91G0qNFM

我用Jsoup解析页面提取下载URL,但无论用Java IO、NIO、AsyncHttpClient还是Apache Commons IO方式下载,都只能得到1.13MB的文件,之后程序就会退出,找不到解决办法。

我的代码如下:

Jsoup 提取链接代码

Document doc = Jsoup.connect("https://api.vevioz.com/@api/button/mp3/AKX91G0qNFM").get();
Element body=doc.body();
Elements elements=body.getElementsByClass("download flex flex-wrap sm:inline-flex text-center items-center justify-center");
elements=elements.get(0).children();
String FILE_URL=elements.get(0).attributes().get("href");
String FILE_NAME="./downloads/1.mp3";

Java IO 下载代码

try (BufferedInputStream in = new BufferedInputStream(new URL(FILE_URL).openStream());
     FileOutputStream fileOutputStream = new FileOutputStream(FILE_NAME)) {
    byte[] dataBuffer = new byte[1024];
    int bytesRead;
    while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
        fileOutputStream.write(dataBuffer, 0, bytesRead);
    }
} catch (IOException e) {
    // handle exception
}

NIO 下载代码

ReadableByteChannel readableByteChannel = Channels.newChannel(new URL(FILE_URL).openStream());
FileOutputStream fileOutputStream = new FileOutputStream(FILE_NAME);
FileChannel fileChannel = fileOutputStream.getChannel();
fileOutputStream.getChannel()
        .transferFrom(readableByteChannel, 0, Long.MAX_VALUE);

AsyncHttpClient 下载代码

AsyncHttpClient client = Dsl.asyncHttpClient();
FileOutputStream stream = new FileOutputStream(FILE_NAME);

client.prepareGet(link).execute(new AsyncCompletionHandler<FileOutputStream>() {

    @Override
    public State onBodyPartReceived(HttpResponseBodyPart bodyPart)
            throws Exception {
        stream.getChannel().write(bodyPart.getBodyByteBuffer());
        return State.CONTINUE;
    }

    @Override
    public FileOutputStream onCompleted(org.asynchttpclient.Response response) throws Exception {
        return stream;
    }
});

Apache Commons IO 下载代码

FileUtils.copyURLToFile(new URL(FILE_URL),new File(FILE_NAME));

可能的原因及解决方案

1. 服务器拦截无请求头的下载请求

多数文件托管服务会校验请求的User-Agent和Referer字段,拒绝非浏览器发起的直接下载请求,导致仅返回部分数据就断开连接。

解决办法:添加模拟浏览器的请求头

  • Java IO 方式修改:
URL url = new URL(FILE_URL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// 模拟Chrome浏览器请求头
connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36");
// 添加来源页Referer
connection.setRequestProperty("Referer", "https://api.vevioz.com/@api/button/mp3/AKX91G0qNFM");
// 开启重定向跟随
connection.setInstanceFollowRedirects(true);

try (BufferedInputStream in = new BufferedInputStream(connection.getInputStream());
     FileOutputStream fileOutputStream = new FileOutputStream(FILE_NAME)) {
    byte[] dataBuffer = new byte[4096]; // 增大缓冲区提升下载效率
    int bytesRead;
    while ((bytesRead = in.read(dataBuffer, 0, 4096)) != -1) {
        fileOutputStream.write(dataBuffer, 0, bytesRead);
    }
} catch (IOException e) {
    e.printStackTrace();
}
  • NIO 方式修改:
URL url = new URL(FILE_URL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36");
connection.setRequestProperty("Referer", "https://api.vevioz.com/@api/button/mp3/AKX91G0qNFM");

try (ReadableByteChannel readableByteChannel = Channels.newChannel(connection.getInputStream());
     FileOutputStream fileOutputStream = new FileOutputStream(FILE_NAME);
     FileChannel fileChannel = fileOutputStream.getChannel()) {
    fileChannel.transferFrom(readableByteChannel, 0, Long.MAX_VALUE);
} catch (IOException e) {
    e.printStackTrace();
}
  • AsyncHttpClient 方式修改:
AsyncHttpClient client = Dsl.asyncHttpClient();
FileOutputStream stream = new FileOutputStream(FILE_NAME);

client.prepareGet(FILE_URL)
        .setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36")
        .setHeader("Referer", "https://api.vevioz.com/@api/button/mp3/AKX91G0qNFM")
        .execute(new AsyncCompletionHandler<FileOutputStream>() {

            @Override
            public State onBodyPartReceived(HttpResponseBodyPart bodyPart) throws Exception {
                stream.getChannel().write(bodyPart.getBodyByteBuffer());
                return State.CONTINUE;
            }

            @Override
            public FileOutputStream onCompleted(org.asynchttpclient.Response response) throws Exception {
                stream.close(); // 必须显式关闭流
                return stream;
            }

            @Override
            public void onThrowable(Throwable t) {
                try {
                    stream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                t.printStackTrace();
            }
        });

2. 流未正确关闭导致文件截断

部分代码未用try-with-resources包裹流,或未在完成/异常时关闭输出流,导致文件未完全写入就被截断。确保所有流都通过try-with-resources自动管理,或在finally块中手动关闭。

3. 未正确跟随重定向

部分下载链接是临时跳转地址,需确保请求开启重定向跟随。HttpURLConnection默认开启,但显式设置connection.setInstanceFollowRedirects(true)更稳妥。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 07:50:57