如何比较2个csv文件,执行操作并输出到新的csv文件

时间:2016-11-15 08:23:16

标签: java arrays csv pattern-matching

我不知道如何比较2个csv文件(old.csv,change.csv)以及执行new.csv文件将产生的不同操作(添加,更新,删除)之后。我只需要一个如何做到这一点的想法。我能够使用FileReader和Writer读取和写入文件。我不知道如何比较文件和执行操作。我应该使用数组来输入数据。

我的csv文件包含列:

Old.csv
CODE  NAME  ADDRESS  NUMBER
0001  John  USA      1234

Change.csv
CHANGE  CODE  NAME   ADDRESS  NUMBER
ADD     0002  Shane  Germany  5678
UPDATE  0001         Canada   

New.csv
CODE   NAME  ADDRESS  NUMBER
0001   John  Canada   1234
0002   Shane Germany  5678

请提供帮助。提前谢谢。

2 个答案:

答案 0 :(得分:0)

看起来,这里你的名字列是2个csv文件之间的主键,在读取CSV文件时你可以创建一个类型的hashmap,其中Name = Name coulmn value和Data是整个对象。稍后在遍历每个更改CSV记录时,您可以使用switch语句来处理更改,并且在每种情况下,您都可以管理对hashmap的单独更新。成功遍历后,您的hashmap将包含所需的更新实例,您可以遍历并转换为新的csv。

答案 1 :(得分:0)

对于这样的任务,我建议使用csv解析器,如opencsvsupercsv

并使用数据类。

以下是使用opencsv的示例:

创建一个看起来像这样的类:

    public class Person {

    private String code;
    private String name;
    private String address;
    private String number;

    public Person(String code, String name, String address, String number) {
        this.code = code;
        this.name = name;
        this.address = address;
        this.number = number;            
    }

    public String geCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }
}

并在您的应用程序中使用上面的类作为数据持有者来比较这两个文件并创建一个新的csv文件

    import com.opencsv.CSVReader;
import com.opencsv.CSVWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

public class NewClass1 {
    public static void main(String[] args) {
        try {
            String oldFile = "Old.csv";
            String changeFile = "Change.csv";
            String newFile = "New.csv";
            Map<String,Person> personsList = readOldCsv(oldFile);
            personsList = getChangesfromChangeCsv(changeFile,personsList);
            writeNewCsvFile(newFile,personsList);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
    //read your old csv file line by line and create an object person 
    //and put it in a map with code as key and person itself as value
    //here assumed that your files are tab separeted '\t'; 
    //if not change to ';' or ',' according to your separator
    public static Map<String,Person> readOldCsv(String fileName) throws IOException{
        Map<String,Person> personsList = new HashMap<>();
        String [] nextLine;
        CSVReader reader = new CSVReader(new FileReader(fileName), '\t' ,'\'', 1);
        while ((nextLine = reader.readNext()) != null) {        
            personsList.put(nextLine[0],new Person(nextLine[0], nextLine[1], nextLine[2], nextLine[3]));
        }       
        return personsList;        
    }
    // read your change csv file and add or update persons depending on the change column
    public static Map<String,Person> getChangesfromChangeCsv(String fileName, Map<String,Person> personsList) throws IOException{            
        String [] nextLine;
        CSVReader reader = new CSVReader(new FileReader(fileName), '\t' ,'\'', 1);
        while ((nextLine = reader.readNext()) != null) { 
            switch(nextLine[0].toLowerCase()){
                case "add":
                    personsList.put(nextLine[1],new Person(nextLine[1], nextLine[2], nextLine[3], nextLine[4]));
                case "update":
                    personsList.get(nextLine[1]).setName(!nextLine[2].isEmpty()? nextLine[2]:personsList.get(nextLine[1]).getName());
                    personsList.get(nextLine[1]).setAddress(!nextLine[3].isEmpty()? nextLine[3]:personsList.get(nextLine[1]).getAddress());
                    personsList.get(nextLine[1]).setNumber(!nextLine[4].isEmpty()? nextLine[4]:personsList.get(nextLine[1]).getNumber());
                default:
                    System.out.println("unexpected entry");
            }                
        } 
        // use TreeMap to get a map sorted by key
        return new TreeMap<>(personsList);        
    }

    //write the values of the map into a new csv file
    private static void writeNewCsvFile(String filename,Map<String,Person> personsList) throws IOException {            
        CSVWriter writer = new CSVWriter(new FileWriter(filename,false), '\t',CSVWriter.NO_QUOTE_CHARACTER);
        for(Person p : personsList.values() ){
            String[] entries = {p.geCode(),p.getName(),p.getAddress(),p.getNumber()};
            writer.writeNext(entries);
        }                
        writer.close();                    
    }
}