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

如何等待JDA附件下载完成后再移动,避免文件0字节或损坏?

问题根源

你遇到的文件异常和aarch64架构的Linux文件系统无关,核心是JDA的downloadToFile方法返回的是CompletableFuture类型,属于异步非阻塞操作:调用该方法后会立刻返回,下载、写入磁盘的逻辑在后台线程执行,你原来的代码没有做任何等待就直接执行移动文件的逻辑,大部分时候移动操作执行时下载还没开始、或者只写入了部分内容,自然就会出现0字节文件、移动失败的问题。
你之前尝试调用的complete方法是用来主动给CompletableFuture设置返回结果的,不是用来等待任务执行完成的,所以不会生效。

解决方案

有两种常用实现方式可以保证下载完成后再执行移动逻辑:

方式1:异步回调内执行移动(推荐,不会阻塞当前线程)

把移动文件的逻辑直接放到thenAccept回调中,下载成功后会自动触发执行:

List<Message.Attachment> attachments = null;
try {
   attachments = event.getMessage().getAttachments();
} catch (UnsupportedOperationException ignore) {}

if (attachments != null && !attachments.isEmpty()) {
   Message.Attachment attachment = attachments.get(0);
   File downloadFile = new File("./tmp/testfile");
   downloadFile.getParentFile().mkdirs();
   File renamedFile = new File("./files/movedfiled");
   renamedFile.getParentFile().mkdirs();

   attachment.downloadToFile(downloadFile)
             .thenAccept(file -> {
                 System.out.println("Saved attachment");
                 // 下载完成后再执行移动
                 try {
                     Files.move(file.toPath(), renamedFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
                 } catch (IOException e) {
                     e.printStackTrace();
                 }
             })
             .exceptionally(t -> {
                 t.printStackTrace();
                 return null;
             });
}

方式2:同步阻塞等待下载完成

如果业务逻辑需要同步等待下载结果,可以调用CompletableFuture的join()方法阻塞当前线程直到下载完成:

List<Message.Attachment> attachments = null;
try {
   attachments = event.getMessage().getAttachments();
} catch (UnsupportedOperationException ignore) {}

File downloadFile = null;
if (attachments != null && !attachments.isEmpty()) {
   Message.Attachment attachment = attachments.get(0);
   downloadFile = new File("./tmp/testfile");
   downloadFile.getParentFile().mkdirs();
   // 阻塞等待下载完成,注意会抛出运行时异常,建议做异常捕获
   attachment.downloadToFile(downloadFile)
             .exceptionally(t -> {
                 t.printStackTrace();
                 return null;
             })
             .join();
}

if (downloadFile != null && downloadFile.exists()) {
   File renamedFile = new File("./files/movedfiled");
   renamedFile.getParentFile().mkdirs();
   try {
      Files.move(downloadFile.toPath(), renamedFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
   } catch (IOException e) {
      e.printStackTrace();
   }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 17:06:03