使用超级csv用Java写回csv

使用超级csv用Java写回csv,java,csv,file-io,supercsv,Java,Csv,File Io,Supercsv,我在这段代码上工作了很长一段时间,如果我走到了死胡同,我只想得到一些简单的提示。现在im的重点是从不同的.csv文件中匹配相同的单元格,并将一行复制到另一个csv文件中。问题是,是否可以在特定的行中写入,例如,如果两个单元格在第50行匹配,我希望写回第50行。我假设我可能会将所有内容提取到hashmap中,将其写入其中,然后写回.csv文件?有没有更简单的方法 例如,我有一个Csv包含人员详细信息,另一个Csv包含实际人员居住位置的财产详细信息,我希望将财产详细信息复制到人员Csv,并将其与正确

我在这段代码上工作了很长一段时间,如果我走到了死胡同,我只想得到一些简单的提示。现在im的重点是从不同的.csv文件中匹配相同的单元格,并将一行复制到另一个csv文件中。问题是,是否可以在特定的行中写入,例如,如果两个单元格在第50行匹配,我希望写回第50行。我假设我可能会将所有内容提取到hashmap中,将其写入其中,然后写回.csv文件?有没有更简单的方法


例如,我有一个Csv包含人员详细信息,另一个Csv包含实际人员居住位置的财产详细信息,我希望将财产详细信息复制到人员Csv,并将其与正确的人员详细信息进行匹配。希望这有意义

public class Old {
 public static void main(String [] args) throws IOException
 {
   List<String[]> cols;
   List<String[]> cols1;

   int row =0;
   int count= 0;
   boolean b;
   CsvMapReader Reader = new CsvMapReader(new FileReader("file1.csv"), CsvPreference.EXCEL_PREFERENCE);
   CsvMapReader Reader2 = new CsvMapReader(new FileReader("file2.csv"), CsvPreference.EXCEL_PREFERENCE);

   try {
       cols = readFile("file1.csv");
       cols1 = readFile("fiel2.csv");
       String [] headers = Reader.getCSVHeader(true);

       headers = header(cols1,headers          

           } catch (IOException e) {
       e.printStackTrace();
       return;
   }

   for (int j =1; j<cols.size();j++) //1
   {
       for (int i=1;i<cols1.size();i++){
           if (cols.get(j)[0].equals(cols1.get(i)[0]))
           {


           }
       }

   }

}


private static List<String[]> readFile(String fileName) throws IOException
{
   List<String[]> values = new ArrayList<String[]>();
   Scanner s = new Scanner(new File(fileName));
   while (s.hasNextLine()) {
       String line = s.nextLine();
       values.add(line.split(","));
   }
   return values;
}
public static void csvWriter (String fileName, String [] nameMapping ) throws FileNotFoundException
{
    ICsvListWriter writer = new CsvListWriter(new PrintWriter(fileName),CsvPreference.STANDARD_PREFERENCE);
    try {
        writer.writeHeader(nameMapping);

    } catch (IOException e) {

        e.printStackTrace();
    }

}
public static String[] header(List<String[]> cols1, String[] headers){
    List<String> list = new ArrayList<String>();
    String [] add;
    int count= 0;
    for (int i=0;i<headers.length;i++){
        list.add(headers[i]);
    }

    boolean c;
    c= true;
    while(c)        {           
        add = cols1.get(0);
        list.add(add[count]);
        if (cols1.get(0)[count].equals(null))// this line is never read errpr
        {               
            c=false;
            break;
        } else  
        count ++;

    }

    String[] array = new String[list.size()];
    list.toArray(array);
    return array;

}
公共类旧{
公共静态void main(字符串[]args)引发IOException
{
列出COL;
列出cols1;
int行=0;
整数计数=0;
布尔b;
CsvMapReader Reader=新的CsvMapReader(新文件读取器(“file1.csv”)、CsvPreference.EXCEL\u首选项);
CsvMapReader Reader2=新的CsvMapReader(新的文件阅读器(“file2.csv”),CsvPreference.EXCEL_首选项);
试一试{
cols=readFile(“file1.csv”);
cols1=readFile(“fiel2.csv”);
String[]headers=Reader.getCSVHeader(true);
页眉=页眉(第1列,页眉
}捕获(IOE异常){
e、 printStackTrace();
返回;
}

对于(int j=1;j,从您的评论来看,您似乎有以下情况:

  • 文件1包含人员
  • 文件2包含地址
然后,您希望通过一些键(一个或多个字段)匹配人员和地址,并将组合写回CSV文件

因此,最简单的方法可能是这样的:

//use a LinkedHashMap to preserve the order of the persons as found in file 1
Map<PersonKey, String[]> persons = new LinkedHashMap<>();
//fill in the persons from file 1 here

Map<PersonKey, String[]> addresses = new HashMap<>();
//fill in the addresses from file 2 here

List<String[]> outputLines = new ArrayList<>(persons.size());    
for( Map.Entry<PersonKey, String[]> personEntry: persons.entrySet() ) {
  String[] person = personEntry.getValue();
  String[] address = addresses.get( personEntry.getKey() );

  //merge the two arrays and put them into outputLines
}

//write outputLines to a file
//使用LinkedHashMap保留文件1中的人员顺序
Map persons=newlinkedhashmap();
//在这里填写文件1中的人员
映射地址=新的HashMap();
//在这里填写文件2中的地址
List outputLines=新的ArrayList(persons.size());
for(Map.Entry personEntry:persons.entrySet()){
字符串[]person=personEntry.getValue();
String[]address=addresses.get(personEntry.getKey());
//合并两个数组并将它们放入输出行
}
//将输出行写入文件

请注意,
PersonKey
可能只是一个
String
或一个包装器对象(
Integer
等),如果您可以通过一个字段匹配人员和地址。如果您有更多字段,您可能需要一个带有
equals()
hashCode()的自定义
PersonKey
对象
已正确覆盖。

如果您先将所有地址和人员详细信息读入内存(正如Thomas所建议的那样),请务必小心-如果您只处理小的CSV文件,则可以,但如果处理较大的文件,则可能会耗尽内存

另一种选择是,我创建了一个示例,首先读取中的地址,然后在读取人员详细信息时写入组合的人员/地址详细信息

只需注意以下几点:

  • 我使用了CsvMapReader和CsvMapWriter,因为你是-这意味着我必须使用一个包含映射的映射来存储地址。使用CsvBeanReader/CsvBeanWriter会使这更优雅一些

  • 您问题中的代码实际上没有使用超级CSV来读取CSV(您使用的是
    扫描器
    字符串.split()
    )。如果您的CSV在数据中包含逗号(这很可能与地址有关),则会遇到问题,因此使用超级CSV更安全,因为超级CSV将为您处理转义的逗号

例如:

package example;

import java.io.StringReader;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

import org.supercsv.io.CsvMapReader;
import org.supercsv.io.CsvMapWriter;
import org.supercsv.io.ICsvMapReader;
import org.supercsv.io.ICsvMapWriter;
import org.supercsv.prefs.CsvPreference;

public class CombiningPersonAndAddress {

    private static final String PERSON_CSV = "id,firstName,lastName\n"
            + "1,philip,fry\n2,amy,wong\n3,hubert,farnsworth";

    private static final String ADDRESS_CSV = "personId,address,country\n"
            + "1,address 1,USA\n2,address 2,UK\n3,address 3,AUS";

    private static final String[] COMBINED_HEADER = new String[] { "id",
            "firstName", "lastName", "address", "country" };

    public static void main(String[] args) throws Exception {

        ICsvMapReader personReader = null;
        ICsvMapReader addressReader = null;
        ICsvMapWriter combinedWriter = null;
        final StringWriter output = new StringWriter();

        try {
            // set up the readers/writer
            personReader = new CsvMapReader(new StringReader(PERSON_CSV),
                    CsvPreference.STANDARD_PREFERENCE);
            addressReader = new CsvMapReader(new StringReader(ADDRESS_CSV),
                    CsvPreference.STANDARD_PREFERENCE);
            combinedWriter = new CsvMapWriter(output,
                    CsvPreference.STANDARD_PREFERENCE);

            // map of personId -> address (inner map is address details)
            final Map<String, Map<String, String>> addresses = 
                    new HashMap<String, Map<String, String>>();

            // read in all of the addresses
            Map<String, String> address;
            final String[] addressHeader = addressReader.getCSVHeader(true);
            while ((address = addressReader.read(addressHeader)) != null) {
                final String personId = address.get("personId");
                addresses.put(personId, address);
            }

            // write the header
            combinedWriter.writeHeader(COMBINED_HEADER);

            // read each person
            Map<String, String> person;
            final String[] personHeader = personReader.getCSVHeader(true);
            while ((person = personReader.read(personHeader)) != null) {

                // copy address details to person if they exist
                final String personId = person.get("id");
                final Map<String, String> personAddress = addresses.get(personId);
                if (personAddress != null) {
                    person.putAll(personAddress);
                }

                // write the combined details
                combinedWriter.write(person, COMBINED_HEADER);
            }

        } finally {
            personReader.close();
            addressReader.close();
            combinedWriter.close();
        }

        // print the output
        System.out.println(output);

    }
}

我不确定我是否理解你想要实现的目标,你能举个例子吗?例如,我有一个Csv有个人详细信息,另一个有实际人居住的房产详细信息,我希望将房产详细信息复制到个人Csv,并将其与正确的个人详细信息进行匹配。希望这有意义@ThomasFYI is ou现在。它包括许多错误修复和新功能(包括Maven支持和用于映射嵌套属性和数组/集合的新Dozer扩展)。谢谢你,我将立即安装它,我想知道为什么java文档网站改变了主意,为什么我会出现空指针错误。@Hound Dog
code combinedWriter.write(UDC,校长)
我检查了两个值,它们都返回了entries谢谢你的想法非常感谢,我的while循环有问题。@Hound Dog it return java.lang.nullPointer异常我不完全确定原因。我把它分解了,似乎停在了第90行。@jbel我猜你是在谈论你的原始代码。我猜是oc在
cols1.get(0)[count].equals(null)
-这不是检查某个内容是否为null的正确方法,因为如果数组的元素为null,则
.equals()
将抛出NullPointerException。它应该是
cols1.get(0)[count]==null
。这么说,我认为你最好让你的代码看起来更像我的示例-你有很多难以阅读/冗余的代码!我在使用你的代码,我的道歉我在你有[code]combinedWriter.write(person,COMBINED_HEADER);[/code]的地方出现空指针异常错误@Hound Dog.我假设这是我的用户错误
id,firstName,lastName,address,country
1,philip,fry,address 1,USA
2,amy,wong,address 2,UK
3,hubert,farnsworth,address 3,AUS