Design and develop a program that accepts the name of a directory that contains
ID: 3728912 • Letter: D
Question
Design and develop a program that accepts the name of a directory that contains a set of text-only
files. The program must be executable as below.
java PA2
The program ensures the following:
a) there are two parameters to the main method
b) is a valid, readable directory
c) the directory does not exist.
If there is a violation of these requirements, the program prints an error message and stops.
The program must read the files in in parallel using multiple threads and
create an index of every token (a sequence of characters delineated by white space) in the input
files: the token, the file name in which it occurs and the line number or offset in the file must all be
output to a file in . All file names and line numbers associated with a token
must be output before outputting the next token and its related information.
Suppose the files data1 and data2 are files in the folder C:PA2 Mapdata. The
file data1 contains the following three lines.
one two
three four
four
And data2 contains the following three lines.
one two three
two three four five six seven
eight
An output would be as follows. (The order of the tokens is unimportant.)
six: C:PA2 Mapdataile2.txt:2
2
four: C:PA2 Mapdataile1.txt:2 C:PA2
Mapdataile1.txt:3 C:PA2 Mapdataile2.txt:2
one: C:PA2 Mapdataile1.txt:1 C:PA2
Mapdataile2.txt:1
seven: C:PA2 Mapdataile2.txt:2
two: C:PA2 Mapdataile1.txt:1 C:PA2
Mapdataile2.txt:1 C:PA2 Mapdataile2.txt:2
three: C:PA2 Mapdataile1.txt:2 C:PA2
Mapdataile2.txt:1 C:PA2 Mapdataile2.txt:2
five: C:PA2 Mapdataile2.txt:2
eight: C:PA2 Mapdataile2.txt:3
It is fine to output just the file name relative to the folder as opposed to the absolute path name.
Use a combination of thread pools, Callables, and Futures. All files must be processed in parallel to
update a concurrent map implementation from java.util.
Explanation / Answer
package TypesOfLinkedList;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;
public class TokenInfo implements Callable<Map<String, String>> {
final Map<String, String> TokensInfo;
private final String[] filePath;
AtomicInteger counter=new AtomicInteger(0);
public TokenInfo(String[] StringPath)
{
this.filePath=StringPath;
this.TokensInfo=new ConcurrentHashMap<String, String>();
}
public Map<String, String> getPaths(String filePath)
{
//System.out.println(filePath);
try {
List<String> allLines = Files.readAllLines(Paths.get(filePath));
int count=1;
for (String line : allLines) {
//System.out.println(line);
String[] str=line.split(" ");
for (String string : str) {
String found=TokensInfo.putIfAbsent(string, filePath+":"+count);
if(found==null){
//do Nothing since it was already put into map
}
else{
String path=found;
path+=" "+filePath+":"+count;
TokensInfo.replace(string, path);
}
}
count++;
}
} catch (IOException e) {
e.printStackTrace();
}
return TokensInfo;
}
@Override
public Map<String, String> call() throws Exception {
int ct=counter.getAndIncrement();
//System.out.println(counter);
return getPaths(filePath[ct]);
}
public static void main(String[] args) {
int noOfThreads=args.length;
if (noOfThreads==0) {
System.out.println("No file is provided to read...Please input");
return;
}
for (int i = 0; i < args.length; i++) {
File file = new File(args[i]);
if (!file.exists()) {
System.out.println(args[i] + " does not exist.");
return;
}
if (!(file.isFile() && file.canRead())) {
System.out.println(file.getName() + " cannot be read from.");
return;
}
}
//Get ExecutorService from Executors utility class, thread pool size is fine counts
ExecutorService executor = Executors.newFixedThreadPool(noOfThreads);
//create a list to hold the Future object associated with Callable
List<Future<Map<String, String>>> list = new ArrayList<Future<Map<String, String>>>();
//Create MyCallable instance
Callable<Map<String, String>> callable = new TokenInfo(args);
for(int i=0; i< noOfThreads; i++){
//submit Callable tasks to be executed by thread pool
Future<Map<String, String>> future = executor.submit(callable);
//add Future to the list, we can get return value using Future
list.add(future);
}
Map<String, String> tokens=new ConcurrentHashMap<String, String>();
for(Future<Map<String, String>> fut : list){
try {
//print the return value of Future, notice the output delay in console
// because Future.get() waits for task to get completed
tokens=fut.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
//shut down the executor service now
executor.shutdown();
for (Map.Entry<String, String> token : tokens.entrySet()) {
System.out.println("Token Name-"+token.getKey()+" Path-"+token.getValue());
}
}
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.