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

Apache Camel文件下载异常:仅最后一个文件可下载,其余被遗漏

问题原因分析

你的代码存在三个核心问题导致仅最后一个URL被处理:

  1. 错误的字符串拆分逻辑
    输入文件中URL是每行一个,但你使用split(" ")按空格拆分。实际文件内容的分隔符是换行符(\n或\r\n),这会导致拆分结果不符合预期:要么整个文件内容被当成一个元素,要么拆分出包含换行的无效元素,进而影响后续处理。

  2. 用File处理URL字符串的错误用法
    直接将URL字符串传入new File(s)是错误的——URL是网络资源标识,不是本地文件路径。在Windows系统下,https://github.com/a.zip会被转换为https:\github.com\a.zip这种无效的File路径,不仅无法正确提取文件名,还可能触发IO异常。

  3. 异常被静默忽略
    catch块中仅调用e.getMessage()却未输出任何日志,导致第一个URL处理失败时无法察觉异常,误以为是被"遗漏"。

修复后的代码方案

方案1:修正Process内的处理逻辑(快速修复)

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Arrays;

import org.apache.camel.builder.RouteBuilder;
import org.springframework.stereotype.Component;

@Component
public class Download extends RouteBuilder{

    @Override
    public void configure() throws Exception {

        from("file:files/input")
            .routeId("downloadInitId")
            .to("direct:downloadFiles");
            
        from("direct:downloadFiles")
            .routeId("downloadProcessId")
            .process(p -> {
                String body = p.getIn().getBody(String.class);
                // 按任意空白字符(换行、空格、制表符等)拆分,适配不同换行格式
                Arrays.stream(body.split("\\s+"))
                      // 过滤空字符串(避免文件首尾空行导致的无效元素)
                      .filter(s -> !s.trim().isEmpty())
                      .forEach(s -> {
                    try {
                        URL url = new URL(s);
                        // 从URL路径直接提取文件名,无需使用File
                        String fileName = url.getPath().substring(url.getPath().lastIndexOf("/") + 1);
                        System.out.println(fileName);
                        System.out.println(s);
                        
                        try (InputStream in = url.openStream()) {
                            // 使用try-with-resources自动关闭输入流,避免资源泄漏
                            Files.copy(in, Paths.get(".\\files\\download\\output\\" + fileName), StandardCopyOption.REPLACE_EXISTING);
                        }
                    } catch (IOException e) {
                        // 打印异常日志,便于排查问题
                        System.err.println("处理URL失败: " + s);
                        e.printStackTrace();
                    }
                });
            });
    }
}

方案2:使用Camel Split组件(更符合Camel路由规范)

Camel提供了专门的Split组件来处理拆分逻辑,比手动循环更优雅且易于维护:

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;

import org.apache.camel.builder.RouteBuilder;
import org.springframework.stereotype.Component;

@Component
public class Download extends RouteBuilder{

    @Override
    public void configure() throws Exception {

        from("file:files/input")
            .routeId("downloadInitId")
            // 按换行符拆分每行,同时过滤空行
            .split(body().tokenize("\n")).streaming()
            .filter(body().isNotEmpty())
            .to("direct:downloadSingleFile");
            
        from("direct:downloadSingleFile")
            .routeId("downloadProcessId")
            .process(p -> {
                String urlStr = p.getIn().getBody(String.class).trim();
                URL url = new URL(urlStr);
                String fileName = url.getPath().substring(url.getPath().lastIndexOf("/") + 1);
                
                System.out.println("正在下载: " + fileName);
                try (InputStream in = url.openStream()) {
                    Files.copy(in, Paths.get(".\\files\\download\\output\\" + fileName), StandardCopyOption.REPLACE_EXISTING);
                }
            })
            .onException(IOException.class)
                .log("下载失败: ${body}")
                .handled(true);
    }
}
关键修复点说明
  • 改用split("\\s+")或Camel的tokenize("\n")拆分每行数据,适配换行符分隔的输入格式。
  • 通过URL.getPath()提取文件名,避免使用File处理URL的错误方式。
  • 使用try-with-resources自动关闭输入流,防止资源泄漏。
  • 添加异常日志打印,便于定位处理失败的URL。
  • 过滤空字符串/空行,避免无效的URL处理。

内容的提问来源于stack exchange,提问作者Ricky V.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 13:09:26