2015-06-10 2 views
-2

У меня есть каталог с большим количеством файлов (~ 40 000), и каждый файл имеет ровно две строки, каждая с номером. Я хочу добавить все числа во весь каталог; как я могу сделать это быстро и эффективно?Добавить числа в файлах

Я пробовал это, но это не сработает, и я не могу понять, почему жизнь меня объясняет. Я получаю исключение NullPointerException, но этого не должно быть, поскольку я предполагаю, что listOfFiles.length вызывает его.

package minerguy31.ai.tictactoe.counter; 

import java.io.File; 
import java.io.IOException; 
import java.io.PrintWriter; 
import java.util.Scanner; 

public class TicTacToeCounter { 
    static String dir = "./data/"; 
    public static void main(String args[]) throws IOException{ 
     int total = 0; 
     File folder = new File(dir); 
     File[] listOfFiles = folder.listFiles(); 

      for (int i = 0; i < listOfFiles.length; i++) { 
       total += getWins(listOfFiles[i].getAbsolutePath()); 
       total += getLosses(listOfFiles[i].getAbsolutePath()); 
      } 

      System.out.println(total); 
    } 

    public static int getWins(String move) throws IOException{ 
     File f = new File(move); 
     if(!f.exists()){ 
      f.createNewFile(); 
      PrintWriter writer = new PrintWriter(move, "UTF-8"); 
      writer.println("0"); 
      writer.println("0"); 
      writer.close(); 
      return 0; 
     } 
     Scanner fscanner = new Scanner(f); 
     int wins = 0; 
     if(fscanner.hasNext()) 
      wins = fscanner.nextInt(); 
     fscanner.close(); 
     return wins; 
    } 

    public static int getLosses(String move) throws IOException{ 
     File f = new File(move); 
     if(!f.exists()){ 
      f.createNewFile(); 
      PrintWriter writer = new PrintWriter(move, "UTF-8"); 
      writer.println("0"); 
      writer.println("0"); 
      writer.close(); 
      return 0; 
     } 
     Scanner fscanner = new Scanner(f); 
     fscanner.nextInt(); 
     int losses = 0; 
     if(fscanner.hasNext()) 
      losses = fscanner.nextInt(); 
     fscanner.close(); 
     return losses; 
    } 
} 
+0

Попробуйте что-нибудь. Отправьте свою попытку и отредактируйте свой вопрос, если у вас есть определенные проблемы. – paisanco

+0

@paisanco Я добавил свой код – eukaryote

+1

возможный дубликат [Что такое исключение Null Pointer Exception и как его исправить?] (Http://stackoverflow.com/questions/218384/what-is-a-null-pointer- exception-and-how-do-i-fix-it) – Gosu

ответ

1

Это именно то, что вам нужно. Он будет проверять все файлы динамически, вам не нужно указывать количество файлов. , например, если у вас есть количество файлов и различное количество строк в каждом файле, не беспокойтесь. он будет читать его правильно.

import java.io.*; 
import java.util.*; 
import java.text.*; 

public class TicTacToeCounter 
{ 
    //arraylist that will read and hold all file names that can be used later in the program. 
    public ArrayList<String> fileList = new ArrayList<String>(); 
    //arraylist of all lines from all files. 
    ArrayList<Integer> theData = new ArrayList<Integer>(); 

    //class constructor 
    public TicTacToeCounter() throws Exception 
    { 
     //provide the directory name here where you have those 40000 files. 
     //I have testdata directory in my program in the same folder where my .java and .class file resides. 
     File folder = new File("testdata"); 
     File[] listOfFiles = folder.listFiles(); 
     ArrayList<String> tempData = new ArrayList<String>(); 

     for (int i = 0; i < listOfFiles.length; i++) 
     { 
      if (listOfFiles[i].isFile()) 
      { 
       fileList.add(listOfFiles[i].getName()); 
      } 
      else if (listOfFiles[i].isDirectory()) 
      { 
       System.out.println("Directory " + listOfFiles[i].getName()); 
      } 
     } 

     //for every filename in fileList, do.... 
     for (String s : fileList) 
     { 
      //call readFile method and pass file name as a variable s. add objects to tempData arraylist. 
      tempData = readFile(s); 
      //for every line in tempData, do.... 
      for (String line : tempData) 
      { 
       //add the line in theData arraylist, also convert into Integer before adding. 
       theData.add(Integer.parseInt(line)); 
      } 
     } 

     //for every object in theData arraylist, print the object. alternatevely you can print it in previous stage. 
     for (Integer s : theData) 
     { 
      System.out.println(s); 
     } 
    } 

    //readFile method that will read our data files. 
    public ArrayList<String> readFile(String fileName) throws Exception 
    { 
     ArrayList<String> data = new ArrayList<String>(); 
     //don't forget to add directory name here as we are only passing filename, not directory. 
     BufferedReader in = new BufferedReader(new FileReader("testdata/"+fileName)); 

     String temp = in.readLine(); 
     while (temp != null) 
     { 
      data.add(temp); 
      temp = in.readLine(); 
     } 
     in.close(); 
     return data; 
    } 
} 
+0

Это не работает для меня, я все равно получаю исключение NullPointerException в строке 22 – eukaryote

+0

Убедитесь, что ваши файлы данных не повреждены или не имеют пустых строк и т. Д. (Проверьте в конце). Начните с небольшого количества файлов с точными данными, которые вы можете отслеживать. затем добавьте еще несколько и проверяйте каждый раз, чтобы убедиться, что код работает правильно. – VD007

+0

, используйте 'while (_variable_! = Null)' перед тем, как продолжить код. чтобы узнать, где вам нужно использовать цикл while, используйте отладчик. – VD007

-1

Вместо использования массива для файла используйте ArrayList. Удобнее и прозрачнее дать вам понять, почему возникает ошибка. а также, если вы используете массивы, вы должны определить длину, когда вы ее инициируете, чего вы не сделали в своем случае.

+0

Это ничего не меняет; это лучше, но на самом деле это не делает работу. – eukaryote

+0

Это, конечно, ничего не меняет, но ArrayLists легче справиться, я думаю. во всяком случае, решение с arraylist приведено выше. – VD007

0

Трассировка стека должна указывать номер строки, где именно происходит ошибка, и вам не нужно угадывать. Проверьте: каталог существует, и он является каталогом, и ваш listOfFiles не имеет значения null до того, как вы сделаете над ним длину.

folder.exists() && folder.isDirectory() { 
    \\ you might want to check if folder.canRead() and folder.canWrite() 
    \\ get listOfFiles 
} 

if (listOfFiles != null) { // proceed with operations 

P.S: Также могут быть улучшены ваши getWins и getLosses. Я бы, наверное, попробовал прочитать файл один раз (и создать, если они не существуют, если вам нужно, но поскольку @sstan упомянул, что вы только что получили имя файла из каталога, нет причин, почему он не должен существовать) и читать как победы, так и потери, если в файлах всегда всего 2 строки. Прямо сейчас вы создаете один, если он не существует, и читайте тот, который вы только что создали сразу после него, чего нам не нужно.

+2

Я даже не понимаю, почему OP проверяет существование файла. Файл должен существовать, потому что он получил его от вызова до 'File.listFiles()'. – sstan

+0

Да, ты прав. Я тоже этого не знаю. Может быть, кто-то удалил файл после того, как мы получили список, и до того, как мы его прочитаем. Я просто предполагаю, что это часть некоторых требований, которые им нужно делать. – prabugp