Oganesson118
Oganesson118

Reputation: 48

Wait for completion of file attachment download

I tried downloading a file attachment using a variant of the example code given by the official JDA documentation. Afterwards, the downloaded file should be moved to another place.

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

File downloadFile;
if (attachments != null && !attachments.isEmpty()) {
   Message.Attachment attachment = attachments.get(0);
   downloadFile = new File("./tmp/testfile");
   downloadFile.getParentFile().mkdirs();
   attachment.downloadToFile(downloadFile)
             .thenAccept(file -> System.out.println("Saved attachment"))
             .exceptionally(t -> {
                                     t.printStackTrace();
                                     return null;
                                 });
}

...

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

I already tried to add .complete(Void) after .exceptionally(...) and .complete(File) after .downloadToFile(File). None of these worked.

Most of the time, the moved file has a size of 0 bytes or does not exist at all and the original is still present in the old directory (sometimes the size of the downloaded one is also 0 bytes).

Is there a way to wait for completion of the download and closure after writing to prevent file corruption while moving or is the problem caused by my file system (I'm using an aarch64 GNU/Linux system)?

Upvotes: 0

Views: 421

Answers (1)

moeux
moeux

Reputation: 197

Message.Attachment#downloadToFile() returns a CompletableFuture. You can use CompletableFuture#join() to wait until it finishes but IIRC this is a blocking action. Better use CompletableFuture#thenAccept() or CompletableFuture#thenCompose().

attachment.downloadToFile(downloadFile)
              .thenAccept(file -> {
              // Here goes the code which decides what to do after downloading the file
                         })
              .exceptionally(e -> {
                                e.printStackTrace();
                                return null;
                         });

Upvotes: 1

Related Questions