Skip to main content

Download file

Download file

When downloading files from the Internet via RPA, there is often a problem: It is necessary to understand when the download is complete. Here is an example of how such functionality can be implemented.


Below is the code of the waitFile() method from the task class. This method, using the NIO2 API, waits for the file to be created in the directory for downloading. The complete code of the class, as well as other classes required to test its work are given below.

waitFile method
private String waitFile(int timeoutSeconds) throws IOException {

	Path directory = Paths.get(filePath);

	try (WatchService service = directory.getFileSystem().newWatchService()) {
		directory.register(service, StandardWatchEventKinds.ENTRY_CREATE);

		long timeout = TimeUnit.NANOSECONDS.convert(timeoutSeconds, TimeUnit.SECONDS);
		while (timeout > 0L) {
			final long start = System.nanoTime();
			WatchKey key = service.poll(timeout, TimeUnit.NANOSECONDS);
			if (key != null) {
				for (WatchEvent<?> event : key.pollEvents()) {
					Path path = (Path) event.context();

					if (path.toString().toLowerCase().endsWith(FILE_EXTENSION)) {
						return path.getFileName().toString();
					}
				}
				key.reset();
				timeout -= System.nanoTime() - start;
			} else {
				break;
			}
		}
	} catch (InterruptedException ignore) {
	}
	return null;
}


Using the ChromeOptions class, we pass parameters that allow you to start downloading to the specified directory without a dialog window appearing. An example of interaction with such a window can be found in the Upload file article.

DownloadFile.java
package eu.ibagroup.easyrpa.filedownload.task;

import eu.ibagroup.easyrpa.engine.annotation.ApTaskEntry;
import eu.ibagroup.easyrpa.engine.annotation.Configuration;
import eu.ibagroup.easyrpa.engine.annotation.Driver;
import eu.ibagroup.easyrpa.engine.annotation.DriverParameter;
import eu.ibagroup.easyrpa.engine.apflow.ApTask;
import eu.ibagroup.easyrpa.engine.rpa.driver.BrowserDriver;
import eu.ibagroup.easyrpa.engine.rpa.driver.DriverParams;
import eu.ibagroup.easyrpa.filedownload.WebApplication;
import eu.ibagroup.easyrpa.filedownload.page.MainPage;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.chrome.ChromeOptions;

import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

@ApTaskEntry(name = "Download file")
@Slf4j
public class DownloadFile extends ApTask {

	private static final String FILE_EXTENSION = ".bin";

	@Driver(param = { @DriverParameter(key = DriverParams.Browser.SELENIUM_NODE_CAPABILITIES, initializerName = DriverParams.BrowserCapabilities.CHROME) })
	private BrowserDriver browserDriver;

	@Configuration(value = "hetzner.app.url", defaultValue = "https://speed.hetzner.de/")
	private String url;

	private static final String filePath = System.getProperty("user.home") + "\\Downloads"; // hetzner.file.path

	public static final class ChromeInitializer implements Supplier<Capabilities> {

		@Override
		public Capabilities get() {
			ChromeOptions chromeOptions = new ChromeOptions();

			HashMap<String, Object> chromePrefs = new HashMap<>();
			chromePrefs.put("profile.default_content_settings.popups", 0);
			chromePrefs.put("download.default_directory", filePath);

			chromeOptions.setExperimentalOption("prefs", chromePrefs);
			return chromeOptions;
		}
	}

	@Override
	public void execute() {

		WebApplication webApplication = new WebApplication(browserDriver);
		MainPage mainPage = webApplication.open(url);

		mainPage.dovnloadTestFile();

		String downloadedFileName = null;

		try {
			downloadedFileName = waitFile(500);
		} catch (IOException e) {
			// do something
		}

		if (downloadedFileName != null) {
			log.info("Downloaded file name: " + downloadedFileName);
		} else {
			log.info("File wasn't downloaded! ");
		}
	}

	private String waitFile(int timeoutSeconds) throws IOException {

		Path directory = Paths.get(filePath);

		try (WatchService service = directory.getFileSystem().newWatchService()) {
			directory.register(service, StandardWatchEventKinds.ENTRY_CREATE);

			long timeout = TimeUnit.NANOSECONDS.convert(timeoutSeconds, TimeUnit.SECONDS);
			while (timeout > 0L) {
				final long start = System.nanoTime();
				WatchKey key = service.poll(timeout, TimeUnit.NANOSECONDS);
				if (key != null) {
					for (WatchEvent<?> event : key.pollEvents()) {
						Path path = (Path) event.context();

						if (path.toString().toLowerCase().endsWith(FILE_EXTENSION)) {
							return path.getFileName().toString();
						}
					}
					key.reset();
					timeout -= System.nanoTime() - start;
				} else {
					break;
				}
			}
		} catch (InterruptedException ignore) {
		}
		return null;
	}
}

MainPage.java
package eu.ibagroup.easyrpa.filedownload.page;

import eu.ibagroup.easyrpa.engine.rpa.element.BrowserElement;
import eu.ibagroup.easyrpa.engine.rpa.page.WebPage;
import eu.ibagroup.easyrpa.engine.rpa.po.annotation.FindBy;
import eu.ibagroup.easyrpa.engine.rpa.po.annotation.Wait;

public class MainPage extends WebPage {

	@FindBy(xpath = "//a[@href='100MB.bin']")
	@Wait(waitFunc = Wait.WaitFunc.VISIBLE)
	private BrowserElement fileLink100mb;

	public void dovnloadTestFile() {
		fileLink100mb.click();
	}
}

DownloadFileAp.java
package eu.ibagroup.easyrpa.filedownload;

import eu.ibagroup.easyrpa.engine.annotation.ApModuleEntry;
import eu.ibagroup.easyrpa.engine.apflow.ApModule;
import eu.ibagroup.easyrpa.engine.apflow.TaskOutput;
import eu.ibagroup.easyrpa.filedownload.task.DownloadFile;

@ApModuleEntry(name = "KB - File Download Automation Demo")
public class DownloadFileAp extends ApModule {

	public TaskOutput run() throws Exception {
		return execute(getInput(), DownloadFile.class).get();
	}
}
WebApplication.java
package eu.ibagroup.easyrpa.filedownload;

import eu.ibagroup.easyrpa.engine.rpa.Application;
import eu.ibagroup.easyrpa.engine.rpa.driver.BrowserDriver;
import eu.ibagroup.easyrpa.engine.rpa.element.BrowserElement;
import eu.ibagroup.easyrpa.filedownload.page.MainPage;

public class WebApplication extends Application<BrowserDriver, BrowserElement> {

	public WebApplication(BrowserDriver driver) {
		super(driver);
	}

	@Override
	public MainPage open(String... args) {
		String gmailUrl = args[0];
		getDriver().get(gmailUrl);
		return createPage(MainPage.class);
	}
}

DownloadFileApLocalRunner.java
package eu.ibagroup.easyrpa.filedownload;

import eu.ibagroup.easyrpa.engine.boot.ApModuleRunner;

public class DownloadFileApLocalRunner {

	public static void main(String[] args) {
		ApModuleRunner.localLaunch(DownloadFileAp.class);
	}
}