-2

I have a directory with a lot of files (~40,000), and each file has exactly two lines, each with a number. I want to add up all of the numbers in the entire directory; how do I do that fast and efficiently?

I tried this, but it doesn't work, and I can't figure out for the life of me why. I get a NullPointerException, but it shouldn't be, since I'm guessing that the listOfFiles.length is causing it.

package me.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;
    }
}
takra
  • 457
  • 5
  • 15
  • Try something. Post your attempt and edit your question if you have specific problems. – paisanco Jun 10 '15 at 00:52
  • @paisanco I added my code – takra Jun 10 '15 at 01:03
  • 1
    possible duplicate of [What is a Null Pointer Exception, and how do I fix it?](http://stackoverflow.com/questions/218384/what-is-a-null-pointer-exception-and-how-do-i-fix-it) – almightyGOSU Jun 10 '15 at 01:09
  • 1
    `I'm guessing that the listOfFiles.length`: You don't need to guess. Please post your exact error message with the full stack trace, including line numbers, and we'll know for sure. – sstan Jun 10 '15 at 01:48
  • @sstan I got a message saying the error was from line 15, which is also where the listOfFiles.length is. – takra Jun 11 '15 at 01:04
  • Before the line that crashes, add the following line, and let us know if that file path exists: `System.out.println(folder.getAbsolutePath());`. Or, why not also add `System.out.println(folder.exists());` for good measure. Let us know what you get. – sstan Jun 11 '15 at 01:18

3 Answers3

1

This is exactly what you need. It will check all files dynamically, you don't need to give number of files. for example, if you have any number of files and various number of rows in each file, not to worry. it will read it correctly.

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;
    }
}
VD007
  • 267
  • 2
  • 15
  • It's not working for me, I'm still getting a NullPointerException at line 22 – takra Jun 11 '15 at 23:15
  • Make sure your data files are not corrupt or don't have any blank lines etc. (check at the end). Start with few number of files with accurate data that you can track. then add few more and check every time to ensure the code works correctly. – VD007 Jun 11 '15 at 23:33
  • alternatively, use 'while (_variable_ != null)' before proceeding further in the code. to find out where you need to use the while loop, use debugger. – VD007 Jun 12 '15 at 03:28
0

Stack trace should tell you the line number exactly where the error happens and you don't have to guess. Please check: the directory exists and it's a directory and your listOfFiles is not null before you do a length on it.

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: Also your getWins and getLosses could be improved. I'd probably try reading the file once (and create if those doesn't exist, if you must but as @sstan mentioned you just got the file name from the directory, there is no reason why it shouldn't exist) and read both wins and losses if there are always only 2 lines in the files. Right now, you are creating one if it doesn't exist and reading the one you just created right after, which we don't have to.

Praba
  • 1,373
  • 10
  • 30
  • 2
    I don't even understand why OP is checking for file existence. The file has to exist, because he got it from the call to `File.listFiles()`. – sstan Jun 10 '15 at 01:56
  • Yeah, you're right. I don't know that either. May be someone deleted the file after we got the list and before we read it.. I'm just assuming that it's part of some requirement that they need to do. – Praba Jun 10 '15 at 02:01
-1

Instead of using array for File, use ArrayList. It is more convenient and transparent to give you an idea why the error occurs. and also, if you use arrays, you must define a length when you initiate it, which you hasn't been done in your case.

VD007
  • 267
  • 2
  • 15
  • That doesn't really change anything; it is better practice, but it doesn't actually make it work. – takra Jun 11 '15 at 02:40
  • It certainly doesn't change anything but ArrayLists are easier to deal with, i guess. anyway, the solution with arraylist is provided above. – VD007 Jun 13 '15 at 07:03