2017-08-13 5 views
1

un pour chaque URL analysée).écrire un fichier utilisant ExecutorService et Callable en Java ne fonctionne pas

J'ai un WebPageAnalysisTask (qui met en œuvre appelable) et maintenant il est de retour nul, mais il retournera un objet qui contient les résultats du traitement (à faire):

public WebPageAnalyzerTask(String targetUrl, Pattern searchPattern) { 
    this.targetUrl = targetUrl; 
    this.searchPattern = searchPattern; 
} 

@Override 
public WebPageAnalysisTaskResult call() throws Exception { 
    long startTime = System.nanoTime(); 
    String htmlContent = this.getHtmlContentFromUrl(); 
    List<String> resultContent = this.getAnalysisResults(htmlContent); 

    try (BufferedWriter bw = Files.newBufferedWriter(Paths.get("c:/output", UUID.randomUUID().toString() + ".txt"), 
      StandardCharsets.UTF_8, StandardOpenOption.WRITE)) { 
     bw.write(parseListToLine(resultContent)); 
    } 

    long endTime = System.nanoTime(); 
    return null; 
} 

Je vous écris le fichier utilisant NIO et try-with-resources.

Le code qui utilisera la tâche est la suivante:

/** 
* Starts the analysis of the Web Pages retrieved from the input text file using the provided pattern. 
*/ 
public void startAnalysis() { 
    List<String> urlsToBeProcessed = null; 

    try (Stream<String> stream = Files.lines(Paths.get(this.inputPath))) { 

     urlsToBeProcessed = stream.collect(Collectors.toList()); 

     if (urlsToBeProcessed != null && urlsToBeProcessed.size() > 0) { 
      List<Callable<WebPageAnalysisTaskResult>> pageAnalysisTasks = this 
        .buildPageAnalysisTasksList(urlsToBeProcessed); 
      ExecutorService executor = Executors.newFixedThreadPool(THREAD_POOL_SIZE); 
      List<Future<WebPageAnalysisTaskResult>> results = executor.invokeAll(pageAnalysisTasks); 
      executor.shutdown(); 
     } else { 
      throw new NoContentToProcessException(); 
     } 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

/** 
* Builds a list of tasks in which each task will be filled with data required for the analysis processing. 
* @param urlsToBeProcessed The list of URLs to be processed. 
* @return A list of tasks that must be handled by an executor service for asynchronous processing. 
*/ 
private List<Callable<WebPageAnalysisTaskResult>> buildPageAnalysisTasksList(List<String> urlsToBeProcessed) { 
    List<Callable<WebPageAnalysisTaskResult>> tasks = new ArrayList<>(); 
    UrlValidator urlValidator = new UrlValidator(ALLOWED_URL_SCHEMES); 

    urlsToBeProcessed.forEach(urlAddress -> { 
     if (urlValidator.isValid(urlAddress)) { 
      tasks.add(new WebPageAnalyzerTask(urlAddress, this.targetPattern)); 
     } 
    }); 

    return tasks; 
} 

Le fichier contenant la liste des URL est lu une fois. ExecutorService crée la tâche pour chaque URL et analyse et écrit le fichier avec des résultats de manière asynchrone. À présent, le fichier est en cours de lecture et le contenu du code HTML de chaque URL est analysé et enregistré dans une chaîne. Cependant, la tâche n'écrit pas le fichier. Je me demande donc ce qui pourrait se passer là-bas. Est-ce que quelqu'un peut me dire s'il me manque quelque chose?

Merci d'avance.

+0

Vous écrivez le fichier avec 'java.io.BufferedWriter', pas NIO. – EJP

Répondre

1

Probablement vous obtenez une exception dans ce qui suit try bloc

try (BufferedWriter bw = Files.newBufferedWriter(Paths.get("c:/output", UUID.randomUUID().toString() + ".txt"), 
     StandardCharsets.UTF_8, StandardOpenOption.WRITE)) { 
    bw.write(parseListToLine(resultContent)); 
} 

Essayez d'ajouter un bloc à catch et imprimer l'exception si elle se fait de voir quelles sont les causes

catch (IOException e) { 
    // Replace with logger or some kind of error handling in production code 
    e.printStackTrace(); 
} 
+0

Honte à moi! J'ai complètement oublié le bloc catch, après quoi j'ai vu que je recevais une exception IOException en essayant d'écrire un fichier dans un répertoire qui n'existe pas. Merci! –

1

En raison de la tâche exécutera erreur à la méthode call() dans la classe WebPageAnalyzerTask, vous devez donc vérifier le résultat de List<Future<WebPageAnalysisTaskResult>> results = executor.invokeAll(pageAnalysisTasks); et déterminer quelle erreur se produire lorsque la tâche est en cours d'exécution.

for (Future<WebPageAnalysisTaskResult> future : results) { 
     try { 
      future.get(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } catch (ExecutionException e) { 
      e.printStackTrace(); 
     } 
    }