简体   繁体   English

读入两个文件并按元素比较每一行

[英]Read-in two files and compare each line by element

I want to read-in two files and compare each element of both files. 我想读入两个文件并比较两个文件的每个元素。 All lines of the files are like this: 17-995-364,Ruh,Konrad,Julia I have two classes: 文件的所有行都是这样的: 17-995-364,Ruh,Konrad,Julia我有两个类:

public class Student {
    public String name;
    public Student (String name) {
        this.name = name;
    }
    public static String[] toString(String name)
    {
        String s1 = ""; String s2 = ""; String s3 = ""; String s4 = "";
        int position = 0;
        for(int i = 0; name.charAt(i) != name.length(); i++)
        {
            if (name.charAt(i) == ',') {++position; continue;}
            if (position == 0) s1 += name.charAt(i);
            if (position == 1) s2 += name.charAt(i);
            if (position == 2) s3 += name.charAt(i);
            if (position == 3) s4 += name.charAt(i);
        }
        String[] s = new String[4];
        return s;
    }
}

and

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

/**
 * This class reads-in a *.csv file.
 * -
 */
public class CSVReader {

    /**
     * This method reads-in a *.csv file and
     * saves each element as entry
     * of a bidimensional array.
     *
     * @param filename track to the file, z.b. ".Root/test/echo.csv"
     * @return {@code String[][] s}  where {@code s[i][j]} is the j-th value 
     * in the i-th line
     */
    public static String[][] readCSV(String filename) {
        ArrayList<String[]> result = new ArrayList<>();

        BufferedReader br = null;
        String line = "";
        String cvsSplitBy = ",";
        StringBuilder  stringBuilder = new StringBuilder();
        for (int i = 0; br != null; ++i)
        {
            for (int j = 0; j < 4;)
            {
                if (result.charAt(i) == ',') {++j; continue;}
                result[i][j] += name.charAt(i);
            }
        }
        try {
            br = new BufferedReader(new FileReader(filename));
            while ((line = br.readLine()) != null) {
                result.add(line.split(cvsSplitBy));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result.toArray(new String[result.size()][]);
    }
}

The class of CSVReader isn't completed and the main class neither: CSVReader的类尚未完成,主类也未完成:

/** * Main class of the Java program. / ** * Java程序的主类。 * */ * * /

public class Main { 公共班级主要{

public static void main(String[] args) {

    /**
     * Read in "./Root/files/echo.csv" und "./Root/files/file1.csv"
     * and output the respective warning on System.out
     */
    String[][] codeexpert = CSVReader.readCSV("./Root/files/file1.csv");
    String[][] echo = CSVReader.readCSV("./Root/files/echo.csv");
    for (int i = 0, i != file1.end ; ++i)
    {
        System.out.println(readCSV(file1(i));
    }
    System.out.println(codeexpert);
    System.out.print(echo);
}

} }

I want to do a sort function, but before that the output in the main class must be correct. 我想做一个排序功能,但在此之前,主类中的输出必须正确。 At the moment I have compilation errors. 目前,我有编译错误。 The sort function isn't a problem for me if I get the elements like I would like to. 如果我得到想要的元素,排序功能对我来说不是问题。 Also I should use the toString fonction of the class Student. 另外,我应该使用Student类的toString函数。 How can I resolve the compilation errors in the main class and is the method readSCV correct like this? 我该如何解决主类中的编译错误,并且readSCV这样的方法正确吗? The compilation errors are: 编译错误为:

The compilation errors are: 编译错误为:

./Root/src/Main.java:16: error: ';' expected
        for (int i = 0, i != file1.end ; ++i)

./Root/src/Main.java:16: error: illegal start of expression
        for (int i = 0, i != file1.end ; ++i)

./Root/src/Main.java:16: error: ';' expected
        for (int i = 0, i != file1.end ; ++i)

./Root/src/Main.java:16: error: illegal start of expression
        for (int i = 0, i != file1.end ; ++i)

./Root/src/Main.java:16: error: ')' expected
        for (int i = 0, i != file1.end ; ++i)

./Root/src/Main.java:16: error: ';' expected
        for (int i = 0, i != file1.end ; ++i)

./Root/src/Main.java:18: error: ')' expected
            System.out.println(readCSV(file1(i));

7 errors 7个错误

I need this to be: 我需要这样:

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Arrays;
import java.util.List;

import static org.junit.Assert.assertEquals;

/**
 * Helper functions for testing
 */
public class MatchingTest {

    /**
     *  Current Project Directory.
     */
    public final static String curDir = Paths.get("").toAbsolutePath().toString() + "/Root/";


     static ByteArrayOutputStream outContent = new ByteArrayOutputStream();
    static ByteArrayOutputStream errContent = new ByteArrayOutputStream();

    /**
     * Copies the test files to the files directory, overwriting existing files
     *
     * @param  dir Directory in which test files are stored
     * @param test_prefix E.g. "00", "01", etc
     */
    public static void copy_testfiles(String dir, String test_prefix) {

        try {


            // Paths to test files
            Path test_echo = Paths.get(curDir + dir + test_prefix + "_echo.csv");
            Path test_codeexpert = Paths.get(curDir + dir + test_prefix + "_codeexpert.csv");

            // Target path
            Path target_echo = Paths.get(curDir + "files/echo.csv");
            Path target_codeexpert = Paths.get(curDir + "files/codeexpert.csv");

            Files.copy(test_echo, target_echo, StandardCopyOption.REPLACE_EXISTING);
            Files.copy(test_codeexpert, target_codeexpert, StandardCopyOption.REPLACE_EXISTING);

        } catch (IOException e) {
            throw new RuntimeException("Could not copy test files", e);
        }
    }

    /**
     * Reads the file containing the expected output and returns it as a String
     * @param dir Directory in which test files are stored
     * @param test_number
     * @return Contents of  ./dir/[test_number]_output.txt
     */
    static String output(String dir, String test_number) {
        try {
            Path test_output = Paths.get(curDir + dir + test_number + "_output.txt");
            return new String(Files.readAllBytes(test_output));
        } catch (IOException e) {
            throw new RuntimeException("Could not open test solution file", e);
        }
    }

    /**
     * This method compares the output to the correct solution.
     * It should be able to differentiate between lines that don't match the formating,
     * lines that are misordered and lines that shouldn't be in the oputput at all
     *
     * @param expected Answer that we expect
     * @param actual   Submitted answer
     */
    static void compare(String expected, String actual) {
        // Split strings into lines and save in a collection
        List<String> expected_lines = Arrays.asList(expected.split("(\r\n|\r|\n)", -1));
        List<String> actual_lines = Arrays.asList(actual.split("(\r\n|\r|\n)", -1));


        String name = "[a-zA-Z'-]+( [a-zA-Z'-]+)?";
        String pattern1 = name + " is enrolled to " + name + " in Echo, but registered with "  + name +  " in CodeExpert.";
        String pattern2 = name + " is enrolled to " + name + " in CodeExpert, but registered with "  + name + " in Echo.";
        String pattern3 = name + " is in CodeExpert but not in Echo.";
        String pattern4 = name + " is in Echo but not in CodeExpert.";
        String pattern = "((" + pattern1 + ")|(" + pattern2 + ")|(" + pattern3 + ")|(" + pattern4 + "))";


        // Special case: A case with no misassigned students should produce no output
        if (expected.equals("")) {
            assertEquals("There should be no output if there are no misassigned students.", expected, actual);
        }

        // Check all lines
        for (int i = 0; i < actual_lines.size(); ++i) {

            if (expected_lines.get(i) != actual_lines.get(i)) {

                if (!actual_lines.get(i).matches(pattern)) {
                    // Line is malformed
                    assertEquals("Line " + i + " is malformed", expected_lines.get(i), actual_lines.get(i));
                }

                if (expected_lines.contains(actual_lines.get(i))) {
                    //Line is correct, but at wrong position
                    int expected_line = expected_lines.indexOf(actual_lines.get(i));
                    if (actual_lines.contains(expected_lines.get(i))) {
                        // Expected line for this position is there but at wrong position
                        assertEquals("Wrong order in output, " +
                                        "line " + i + " should be at position " + expected_line,
                                expected_lines.get(i), actual_lines.get(i));
                    } else {
                        // Expected line is missing
                        assertEquals("Missing output item on line " + i, expected_lines.get(i), actual_lines.get(i));
                    }
                } else {
                    // Line should not appear in output
                    assertEquals("Line " + i + " should not be part of output", expected_lines.get(i), actual_lines.get(i));
                }
            }

        }

    }

    /**
     * Verify that there was no output to System.err
     */
    static void checkErr() {
        assertEquals("There should be no output on err", "", errContent.toString());
    }

    /**
     * Redirect the output from the console to a Stream we can save
     */
    @Before
    public void setUpStreams() {
        outContent.reset();
        errContent.reset();
        System.setOut(new PrintStream(outContent));
        System.setErr(new PrintStream(errContent));
    }

    /**
     * Restore routing of output to the console
     */
    @After
    public void restoreStreams() {
        System.setOut(System.out);
        System.setErr(System.err);
    }

    /**
     * This test is simply here to workaround a Codeboard.io issue
     */
    @Test
    public void dummyTest() {
        // empty test passes
    }
}

Where does this file1.end come from? 这个file1.end来自哪里?

In your main() method: 在您的main()方法中:

As I understand it, you want to compare the contents (line by line) of one file to another file. 据我了解,您想将一个文件的内容(逐行)与另一个文件进行比较。 You have already placed the data from each individual file into specific 2D String Arrays via your CSVReader Class ( codeexpert[][] and echo[][] ). 您已经通过CSVReader类( codeexpert [] []echo [] [] )将每个文件中的数据放入特定的2D字符串数组中。 Now it's a matter of iterating through those arrays to see if they differ (I'm assuming you handled the CSV files header lines if they have one): 现在,只需遍历这些数组以查看它们是否不同(我假设您处理了CSV文件标题行,如果它们有一个的话):

public static void main(String[] args) {
    /**
     * Read in "./Root/files/echo.csv" und "./Root/files/file1.csv"
     * and output the respective warning on System.out
     */
    String[][] codeexpert = CSVReader.readCSV("./Root/files/file1.csv");
    String[][] echo = CSVReader.readCSV("./Root/files/echo.csv");
    String msg = "The two files provided are not the same!";

    // See if the two arrays are of the same length.
    // This would be a dead give-away right from the start.
    if (codeexpert.length != echo.length) {
        System.err.println(msg);
        return;
    }

    // See if the lines in each file are the same. We check
    // the rows and columns of each 2D Array to do this.
    // Trap exceptions in case Array column indexing is different
    // on both 2D Arrays.
    try {
        // Get Row...
        for (int i = 0; i < codeexpert.length; i++) {
            // Get Coloumn...
            for (int j = 0; j < codeexpert[i].length; j++) {
                // Is the data in the columns of this particular row
                // the same in both arrays?
                if (!codeexpert[i][j].equals(echo[i][j])) {
                    // No it's not...  
                    System.err.println(msg);
                    return; 
                } 
            }
            System.out.println("File 1 - Line " + String.valueOf(i + 1) + ": " + Arrays.toString(codeexpert[i]));
            System.out.println("File 2 - Line " + String.valueOf(i + 1) + ": " + Arrays.toString(echo[i]));
        }
    } 
    catch (Exception ex) {
        // If the exception occurs then chances are the indexing
        // for columns is different on a particular row. 
        System.err.println(msg);
        return;
    }
    System.out.println("The two files are the same!");
}

EDIT: The Student.toString() Method: 编辑:Student.toString()方法:

It would be helpful to know what the components mean in each file line. 了解组件在每个文件行中的含义将很有帮助。 before creating a toString() method or overloading one for the Student class. 在创建toString()方法或为Student类重载一个方法之前。

From what I gather from your comments, you are trying to separate the supplied comma delimited file line into a string array and then return that array. 根据我从您的评论中收集到的信息,您正在尝试将提供的逗号分隔文件行分隔为字符串数组,然后返回该数组。 Here is how I think you should do it (sweet and simple): 我认为这是您应该做的(甜蜜和简单):

public static String[] toString(String inputString) {
    String[] s = inputString.split(",|,\\s+");
    return s;
}

Here is how your Student class MIGHT be better suited: 这是您的学生班级怎么可能更适合:

public class Student {

    private String firstName;
    private String middleName;
    private String lastName;
    private String assignmentNumber;

    /**
     * The Student Class constructor that can optionally accept arguments. 
     * If a single argument is supplied and it consists of a comma (,) 
     * delimited CSV file line as a single string, that string will be 
     * split and the elements placed into the appropriate class fields.
     * If multiple arguments are supplied then it is assumed that those
     * string arguments represent the contents for our class field 
     * components which are assignmentNumber, lastName, middleName, and 
     * firstName (in that order). Of course if nothing is supplied this
     * is just an empty constructor.<br><br>
     * 
     * @param inputString (Optional - String) Read the above.
     */
    public Student (String... inputString) {
        String inString;
        if (inputString.length > 0) {
            // Single file line assumed...
            if (inputString.length == 1) {
                inString = inputString[0]; 
                if (!inString.equals("")) {
                    if (!inString.contains(",")) { 
                        throw new IllegalArgumentException("Student value can not be empty "
                                    + "OR Student value must be a comma delimited String!");
                    }
                    String[] values = inString.split(",|,\\s+");
                    if (values.length >= 1) { this.assignmentNumber = values[0]; }
                    else { this.assignmentNumber = ""; }
                    if (values.length >= 2) { this.lastName = values[1]; }
                    else { this.assignmentNumber = ""; }
                    if (values.length >= 3) { this.middleName = values[2]; }
                    else { this.middleName = ""; }
                    if (values.length >= 4) { this.firstName = values[3]; }
                    else { this.firstName = ""; }
                }
            }
            else {
                if (inputString.length >= 1) { this.assignmentNumber = inputString[0]; }
                if (inputString.length >= 2) { this.lastName = inputString[1]; }
                if (inputString.length >= 3) { this.middleName = inputString[2]; }
                if (inputString.length >= 4) { this.firstName = inputString[3]; }
            }
        }
    }

    /**
     * Overriden - Student.toString() method with no arguments to return a 
     * string like:  "17-995-364 Ruh Konrad Julia"
     * based from what is contained within the class fields.<br><br>
     * 
     * @return (String)
     */
    @Override
    public String toString() {
        String s = assignmentNumber + " " + lastName + " " + middleName + " " + firstName;
        return s;
    }


    /**
     * A static Student.toString() method that takes a string argument 
     * which is to be considered a single line of CSV file text. This
     * method will return a String Array containing elements which 
     * could look like this: [17-995-364, Ruh, Konrad, Julia]<br><br>
     * 
     * @param inputString (String) A single line of comma delimited CSV 
     * file text.<br>
     * 
     * @return (Single Dimensional String Array) 1D String Array containing 
     * specific elements from the supplied comma delimited CSV file line.
     */
    public static String[] toString(String inputString) {
        String[] s = inputString.split(",|,\\s+");
        return s;
    }

    /**
     * A Overloaded static Student.toString() method that takes a String Array
     * argument which is to be considered a single line of CSV file 
     * text that is split to create that array. This method will 
     * return a String containing which could look like this:<br><br> 
     * "17-995-364 Ruh Konrad Julia"<br><br>
     * 
     * @param inputArray (Single Dimensional String Array)<br>
     * 
     * @return (String) See Above...
     */
    public static String toString(String[] inputArray) {
        String s = "";
        for (String inputArray1 : inputArray) {
            s += s.equals("") ? inputArray1 : " " + inputArray1;
        }
        return s;
    }

    // Field Getters And Setters to enhance the class
    // for better usability.
    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getMiddleName() {
        return middleName;
    }

    public void setMiddleName(String middleName) {
        this.middleName = middleName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getAssignmentNumber() {
        return assignmentNumber;
    }

    public void setAssignmentNumber(String assignmentNumber) {
        this.assignmentNumber = assignmentNumber;
    }

}

Of course none of this has really been tested and I don't really know what the overall purpose of your project might be but never the less, you may (or may not) benefit from this. 当然,这一切都没有经过真正的测试,我真的不知道您的项目的总体目标是什么,但总的来说,您可能会(或可能不会)从中受益。

I got told, the CSVreader should be like this: 我被告知,CSVreader应该是这样的:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

/**
 * Diese Klasse liest eine *.csv Datei ein.
 * Wie das intern genau funktioniert ist fuer die Uebung nicht relevant
 */
public class CSVReader {

    /**
     * Diese Methode liest eine *.csv Datei ein und
     * speichert die einzelnen Eintraege als Elemente
     * eines zweidimensionalen Arrays.
     *
     * @param filename Pfad zur Datei, z.b. ".Root/test/echo.csv"
     * @return {@code String[][] s}  Wobei {@code s[i][j]} Der j-te Wert in der i-ten Zeile ist
     */
    public String[][] readCSV(String filename) {
        ArrayList<String[]> result = new ArrayList<>();

        BufferedReader br = null;
        String line = "";
        String cvsSplitBy = ",";

        try {
            br = new BufferedReader(new FileReader(filename));
            while ((line = br.readLine()) != null) {
                result.add(line.split(cvsSplitBy));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result.toArray(new String[result.size()][]);
    }
}

And in the main class I should use this: 在主类中,我应该使用以下代码:

String[][] dataEcho = new CSVReader().readCSV("./Root/files/echo.csv");<br>
String[][] dataCodeExpert = new CSVReader().readCSV("./Root/files/codeexpert.csv");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM