Я хотел бы просмотреть все файлы из определенной папки и в каждом файле подсчитать определенные слова. Это должно быть сделано через пул потоков, где каждый поток должен быть создан, только если объединенный размер файлов больше, чем заданный размер файла. Итак, в другом классе я нашел все файлы в данной папке и там я звоню forkJoinPoolInstance.submit(new JobFileTask(files));
Я проверил некоторые другие потоки на stackoverflow и узнал о слиянии в HashMaps, но это не решает мою проблему. Если я использую код, как написано ниже, слиянием, то все значения из всех файлов каждой папки для определенного ключа будут нулевыми. И если бы вместо этого вызова слияния я поставил mapToReturn.putAll(readFile(f));
, он бы считал только одно слово на файл, даже если бы было больше вхождений данных ключевых слов. Что мне здесь не хватает?
public class JobFileTask extends RecursiveTask<Map<String, Integer>>
{
private File[] files;
public JobFileTask (File[] f)
{
this.files = f;
}
@Override
protected Map<String, Integer> compute()
{
System.out.println("Computing... ");
Map<String, Integer> mapToReturn = new ConcurrentHashMap<>();
long currentSize = 0;
ArrayList<File> newFiles = new ArrayList<>();
ArrayList<File> otherFiles = new ArrayList<>();
if (files.length == 0)
{
return mapToReturn;
}
for (File f: files)
{
currentSize += f.length();
if (currentSize <= Main.getScanningSizeLimit())
{
newFiles.add(f);
Map<String, Integer> temp = readFile(f);
mapToReturn.entrySet()
.forEach(entry -> temp.merge(
entry.getKey(),
entry.getValue(),
(key, value) -> entry.getValue() + value));
}
else
{
ForkJoinTask<Map<String, Integer>> forkTask = new JobFileTask((File[]) newFiles.toArray(new File[newFiles.size()]));
forkTask.fork();
for (File fs: files)
{
if (!newFiles.contains(fs))
{
otherFiles.add(fs);
}
}
JobFileTask callTask = new JobFileTask((File[]) otherFiles.toArray(new File[otherFiles.size()]));
Map<String, Integer> forkResult = callTask.compute();
Map<String, Integer> callResult = forkTask.join();
mapToReturn.putAll(forkResult);
mapToReturn.putAll(callResult);
break;
}
}
return mapToReturn;
}
public Map<String, Integer> readFile(File f)
{
Map<String, Integer> toReturn = new ConcurrentHashMap<>();
try
{
String line = "";
BufferedReader bufferedReader = new BufferedReader(new FileReader(f));
while ((line = bufferedReader.readLine()) != null)
{
for (String k: Main.getKeywords())
{
if (line.contains(k))
{
if (toReturn.containsKey(k))
{
toReturn.put(k, toReturn.get(k)+1);
}
else
{
toReturn.put(k, 1);
}
}
}
}
bufferedReader.close();
}
catch (Exception e)
{
e.printStackTrace();
}
return toReturn;
}