简体   繁体   中英

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:

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:

/** * Main class of the Java program. * */

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. How can I resolve the compilation errors in the main class and is the method readSCV correct like this? 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

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?

In your main() method:

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[][] ). 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):

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:

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.

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:

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");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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