将文件中的数字相加
Add up numbers in files
我有一个包含很多文件(~40,000)的目录,每个文件正好有两行,每行都有一个数字。我想把整个目录中的所有数字加起来;我如何快速有效地做到这一点?
我试过了,但没用,而且我一辈子也想不通为什么。我得到一个 NullPointerException,但它不应该是,因为我猜是 listOfFiles.length 引起的。
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;
}
}
不要为文件使用数组,而是使用 ArrayList。让您了解错误发生的原因更加方便和透明。而且,如果你使用数组,你必须在启动它时定义一个长度,你还没有在你的情况下完成。
堆栈跟踪应该会告诉您确切发生错误的行号,您不必猜测。请检查:该目录存在并且它是一个目录,并且您的 listOfFiles 不为空,然后再对其进行长度处理。
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 行,则输赢都一样。现在,如果它不存在,您正在创建一个,然后立即读取您刚创建的那个,我们不必这样做。
这正是您所需要的。
它将动态检查所有文件,您不需要提供文件数量。
例如,如果您有任意数量的文件并且每个文件中有不同数量的行,请不要担心。它会正确读取。
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;
}
}
我有一个包含很多文件(~40,000)的目录,每个文件正好有两行,每行都有一个数字。我想把整个目录中的所有数字加起来;我如何快速有效地做到这一点?
我试过了,但没用,而且我一辈子也想不通为什么。我得到一个 NullPointerException,但它不应该是,因为我猜是 listOfFiles.length 引起的。
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;
}
}
不要为文件使用数组,而是使用 ArrayList。让您了解错误发生的原因更加方便和透明。而且,如果你使用数组,你必须在启动它时定义一个长度,你还没有在你的情况下完成。
堆栈跟踪应该会告诉您确切发生错误的行号,您不必猜测。请检查:该目录存在并且它是一个目录,并且您的 listOfFiles 不为空,然后再对其进行长度处理。
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 行,则输赢都一样。现在,如果它不存在,您正在创建一个,然后立即读取您刚创建的那个,我们不必这样做。
这正是您所需要的。 它将动态检查所有文件,您不需要提供文件数量。 例如,如果您有任意数量的文件并且每个文件中有不同数量的行,请不要担心。它会正确读取。
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;
}
}