I wrote a program that searches for the necessary files in a directory and its subfolders based on the desired file size. But according to the assignment, I need to add a multithreaded "Fork-join" mode. I understand that he can slow down, not speed up the work, but this was my assignment. I can't add it to the code in any way to make everything work.
import java.io.File;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
public class Main{
static Scanner in = new Scanner(System.in);
static File directory = new File(in.next());
public static final double MIN_LENGTH = in.nextDouble() * 1048576;
static int numOfThreads = 2;
public static void main(String[] args) {
ArrayList<File> fileList = new ArrayList<>();
getFiles(directory, fileList);
fileList.sort(Comparator.<File>comparingLong(File::length).reversed());
DecimalFormat df = new DecimalFormat("#.#");
ForkJoinPool pool = new ForkJoinPool(numOfThreads);
for(File file: fileList) {
if(file.length()>= 1073741824) {
double Gb = (double) file.length() / 1073741824;
System.out.printf("%s Gb %s%n", df.format(Gb), file);
} else if(file.length()>= 1048576) {
System.out.printf("%s Mb %s%n", file.length() / 1048576, file);
} else if (file.length()>= 1024){
System.out.printf("%s Kb %s%n", file.length() / 1024, file);
} else if (file.length()< 1024){
System.out.printf("%s B %s%n", file.length(), file);
} else {
System.out.printf("%s Gb %s%n", file.length() / (1073741824 * 1024), file);
}
}
}
private static void getFiles(File rootFile, List<File> fileList) {
if (rootFile.isDirectory()) {
File[] directoryFiles = rootFile.listFiles();
if (directoryFiles != null) {
for (File file: directoryFiles) {
if (file.isDirectory()) {
getFiles(file, fileList);
} else {
if (file.isFile() && file.length() >= MIN_LENGTH) {
fileList.add(file);
}
}
}
}
}
}
}
I tried to divide the work into 2 threads, the first thread processes files up to 5 megabytes, and the second one connects if the file is larger than 5 megabytes, but everything turned out crookedly and does not work
I think the idea is that each task should process a single file/directory.
Example:
ForkJoinPool pool = new ForkJoinPool(20);
FileTask task = new FileTask(directory);
pool.invoke(task);
class FileTask:
public class FileTask extends RecursiveAction {
private final DecimalFormat df = new DecimalFormat("#.#");
private final File file;
public FileTask(File file) {
this.file = file;
}
@Override
protected void compute() {
if (file.isDirectory()) {
processDir();
} else if (file.isFile()) {
processFile();
}
}
private void processFile() {
if(file.length()>= 1073741824) {
double Gb = (double) file.length() / 1073741824;
System.out.printf("%s Gb %s%n", df.format(Gb), file);
} else if(file.length()>= 1048576) {
System.out.printf("%s Mb %s%n", file.length() / 1048576, file);
} else if (file.length()>= 1024){
System.out.printf("%s Kb %s%n", file.length() / 1024, file);
} else if (file.length()< 1024){
System.out.printf("%s B %s%n", file.length(), file);
} else {
System.out.printf("%s Gb %s%n", file.length() / (1073741824 * 1024), file);
}
}
private void processDir() {
List<FileTask> tasks = new ArrayList<>();
File[] subFiles = file.listFiles();
for (File sub: subFiles) {
tasks.add(new FileTask(sub));
}
ForkJoinTask.invokeAll(tasks);
}
}