如何等待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
相关产品推荐
相关产品推荐

