Java 从文件中读取字符串并将它们放入多维数组

Java reading Strings from file ant putting them into a multidimensional array

基本上,我有一堆信息需要从文件中读取并将其放入二维数组中。 data.txt 文件如下所示:

a 2016-10-03 Boston Type1 112
b 2016-05-02 Chicago Type2 150
c 2016-06-01 Denver Type3 1500
d 2016-08-26 NewYork Type4 80

谢谢!

您显然需要的是一个二维数组,它最终将由无限行组成,每行 5 列。要声明二维数组,您首先需要确定每一列的数据类型。例如,让我们看一下您的文件内容的第一行:

a 2016-10-03 波士顿 Type1 112

1st 我们有'a',这是一个字符串数据类型;

2nd 我们有'2016-10-03',这是一个日期数据类型,

第三我们有'Boston',它也是一个字符串数据类型,

4th 我们有'Type1',它又是一个字符串数据类型,

5,最后我们有'112',这很可能是整数数据类型。

如果您想在 2D 数组中维护这些特定的数据类型,那么您需要将数组声明为对象:

对象[][] myArray = {};

如果您更愿意将这些数据类型维护为字符串,这正是它们在文本文件中的真实含义,那么您需要将二维数组声明为字符串:

String[][] myArray = {};

这取决于您,您的决定应基于您将如何处理从数组中检索到的元素数据。

您首先需要确定需要多少行来确定数组的维度。为此,您需要知道数据文件中包含多少数据行。为此,我们需要制定一个简单的方法来获取此金额。让我们创建一个方法来计算文本文件中的文本行数,我们将其命名为 countFileLines():

private static int countFileLines(String filePath) {
    try {
        int count = 0;
        try (InputStream inSt = new BufferedInputStream(new FileInputStream(filePath))) {
            byte[] c = new byte[1024];
            int readChars = 0;
            boolean NoNewLine = false;
            while ((readChars = inSt.read(c)) != -1) {
                for (int i = 0; i < readChars; ++i) {
                    if (c[i] == '\n') { ++count; }
                }
                NoNewLine = (c[readChars - 1] != '\n');
            }   
            if(NoNewLine) { ++count; }
            inSt.close();
        }
        return count;
    } 
    catch (FileNotFoundException ex) {
        System.out.println("countFileLines() Method ERROR - File Not Found!");
    } 
    catch (IOException ex) {
        System.out.println("countFileLines() Method ERROR - IO Exception Encountered\n" + ex.getMessage());
    } 
    return 0;
}

现在我们已经解决了这个问题,让我们从二维 'String' 数组开始:

// Let's get the number of data lines within file.
// If file is not in classpath then supply full path.
int dl = countFileLines("data.txt");
if (dl == 0) { System.exit(0); }
String[][] myArray = new String[dl][5];

在那里,现在我们已经声明并初始化了我们的 2D 字符串数组,以保存提供的数据文件中包含的数据行的总行数,并且我们将列设置为 5,因为我们已经知道每个文件行由 5 个用 space.

分隔的数据字符串块组成

现在我们需要做的就是读入每个数据文件行(行)并将每个字符串块(列)放入二维字符串数组中各自的元素中。我们需要制作一个简单的自定义方法来执行任务。我们称它为 applyFileDataToArray():

private static String[][] applyFileDataToArray(String filePath, String[][] myArray) {
    // declare and intialize a String variable to hold string 
    // data lines read from file.
    String line = "";
    // Declare and initialize a temporary 2D Array to fill with file data
    // and return.
    String[][] tmpArray = new String[myArray.length][myArray[0].length];
    // Declare and iniialize a Integer variable to be used as a incremental
    // index counter for our temporary 2D Array.
    int cnt = 0;
    try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
        // Read in each line of the data text file so as to place each
        // line of data into the a temporary 2D String Array which will
        // be ulimately returned...
        while((line = br.readLine()) != null){
            // Skip past blank lines in the text file and only process file lines
            // which actually contain data.
            if (!line.equals("")) { 
                // Each line of data within the data text file consists
                // of a string with 5 data chunks each delimited with a 
                // whitespace. We place each data chunk into a String 
                // Array and then interate through this array and place 
                // each element into the 2D Array.
                String[] tok = line.split(" ");
                for (int i = 0; i < tok.length; i++) {
                    tmpArray[cnt][i] = tok[i];
                }
                // increment index counter...
                cnt++;
            }
        }
        // Data now acquired from file - Close the BufferReader
        br.close();
    } 
    // Trap IO Exceptions from the Bufferreader if any...
    catch (IOException ex) {
        System.out.println("\n\u001B[31mThe supplied data file could"
                         + " not be found!\n\u001B[39;49m" + filePath);
    }
    // Return filled 2D Array
    return tmpArray;
}

上面的方法有很好的注释,所以应该相对容易理解那里发生了什么。

现在使用您的两个新方法,我们的 'main' 代码应该如下所示:

int dl = CountFileLines("data.txt");
if (dl == 0) { System.exit(0); }
String[][] myArray = new String[dl][5];
myArray = applyFileDataToArray("data.txt", myArray);

// Display the contents of our 2D Array to Console...
for (int i = 0; i < myArray.length; i++) {
    System.out.println("\nROW " + (i+1) + ":");
    for (int j = 0; j < 5; j++) {
        System.out.println("\tColumn " + (j+1) + ":  " + myArray[i][j]);
    }
}

如前所述,如果要在二维数组的元素列中维护特定数据类型,则需要将二维数组声明并初始化为对象类型。您的“主要”代码将如下所示:

int dl = CountFileLines("data.txt");
if (dl == 0) { System.exit(0); }
Object[][] myArray = new Object[dl][5];
myArray = applyFileDataToArray("data.txt", myArray);

// Display the contents of our 2D Array to Console...
for (int i = 0; i < myArray.length; i++) {
    System.out.println("\nROW " + (i+1) + ":");
    for (int j = 0; j < 5; j++) {
        System.out.println("\tColumn " + (j+1) + ":  " + myArray[i][j]);
    }
}

和我们的 applyFileDataToArray() 方法会稍有不同,以适应不同的数据类型要求。该方法现在看起来像:

private static Object[][] applyFileDataToArray(String filePath, Object[][] myArray) {
    String line = "";
    Object[][] tmpArray = new Object[myArray.length][myArray[0].length];
    int cnt = 0;
    try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
        // Read in each line of the data text file so as to place each
        // line of data into the a temporary 2D Object Array which will
        // be ulimately returned...
        while((line = br.readLine()) != null){
            // Skip past blank lines in the text file and only process file lines
            // which actually contain data.
            if (!line.equals("")) { 
                // Each line of data within the data text file consists
                // of a string with 5 data chunks each delimited with a 
                // whitespace. We place each data chunk into a String 
                // Array and then interate through this array and place 
                // each element into the 2D Object Array with their respective
                // data type.
                String[] tok = line.split(" ");
                tmpArray[cnt][0] = tok[0];
                tmpArray[cnt][1] = cDate(tok[1], "yyyy-MM-dd");
                tmpArray[cnt][2] = tok[2];
                tmpArray[cnt][3] = tok[3];
                tmpArray[cnt][4] = Integer.valueOf(tok[4]);
                cnt++;
            }
        }
        // Close the BufferReader
        br.close();
    } 
    // Trap IO Exceptions from the Bufferreader if any...
    catch (IOException ex) {
        System.out.println("\n\u001B[31mThe supplied Translation Table file could"
                         + " not be found!\n\u001B[39;49m" + filePath);
    }
    // Return filled 2D Object Array
    return tmpArray;
} 

注意上面代码中的行:tmpArray[cnt][1] = CDate(tok[1], "YYYY-MM-dd");。此行包含另一个将日期字符串转换为日期数据类型的自定义方法。这是 cDate() 方法的代码:

private static Date cDate(String val, String... expectedFormat) {
    //Usage:  Date d = cDate("2016-06-22", "yyyy-MM-dd");

    String dFormat = "dd/MM/yyyy";
    if (expectedFormat.length != 0) { dFormat = expectedFormat[0]; }

    SimpleDateFormat formatter = new SimpleDateFormat(dFormat, Locale.ENGLISH);
    try { 
        Date bdate = formatter.parse(val);
        return bdate;   // Default format is 01/01/2015
    }
    catch (ParseException e) { return null; }
}

希望这对您(和其他人)有帮助。