2013-08-02 4 views
7

У меня есть файлы CSV с одинаковыми заголовками столбцов. НапримерОбъединить CSV-файлы в один файл без повторных заголовков

Файл A

header1,header2,header3 
one,two,three 
four,five,six 

Файл B

header1,header2,header3 
seven,eight,nine 
ten,eleven,twelve 

Я хочу, чтобы объединить его с тем, что данные объединены в один файл с заголовками в верхней части, но не заголовки где-нибудь еще ,

header1,header2,header3 
one,two,three 
four,five,six 
seven,eight,nine 
ten,eleven,twelve 

Что такое хороший способ достичь этого?

+0

Я предполагаю, что вы знаете, как читать файлы построчно. Когда вы пишете строки в файл, пропустите первую строку в каждом последующем файле после первого. –

+0

Либо создайте текстовый файл, который просто содержит заголовок, и добавьте каждый CSV к нему, пропуская первую строку или прочитав все из них, не пропустив первую строку первого файла. Первое было бы немного проще, а второе было бы относительно простым и более портативным, если бы у вас были разные наборы файлов с разными заголовками. – danielunderwood

ответ

2

Это должно сработать. Он проверяет, имеют ли объединенные файлы соответствующие заголовки. В противном случае выбрасывается исключение. Обработка исключений (для закрытия потоков и т. Д.) Оставлена ​​в качестве упражнения.

String[] headers = null; 
String firstFile = "/path/to/firstFile.dat"; 
Scanner scanner = new Scanner(new File(firstFile)); 

if (scanner.hasNextLine()) 
    headers[] = scanner.nextLine().split(","); 

scanner.close(); 

Iterator<File> iterFiles = listOfFilesToBeMerged.iterator(); 
BufferedWriter writer = new BufferedWriter(new FileWriter(firstFile, true)); 

while (iterFiles.hasNext()) { 
    File nextFile = iterFiles.next(); 
    BufferedReader reader = new BufferedReader(new FileReader(nextFile)); 

    String line = null; 
    String[] firstLine = null; 
    if ((line = reader.readLine()) != null) 
    firstLine = line.split(","); 

    if (!Arrays.equals (headers, firstLine)) 
    throw new FileMergeException("Header mis-match between CSV files: '" + 
       firstFile + "' and '" + nextFile.getAbsolutePath()); 

    while ((line = reader.readLine()) != null) { 
    writer.write(line); 
    writer.newLine(); 
    } 

    reader.close(); 
} 
writer.close(); 
4

Вот пример:

public static void main(String[] args) throws IOException { 
    List<Path> paths = Arrays.asList(Paths.get("c:/temp/file1.csv"), Paths.get("c:/temp/file2.csv")); 
    List<String> mergedLines = getMergedLines(paths); 
    Path target = Paths.get("c:/temp/merged.csv"); 
    Files.write(target, mergedLines, Charset.forName("UTF-8")); 
} 

private static List<String> getMergedLines(List<Path> paths) throws IOException { 
    List<String> mergedLines = new ArrayList<>(); 
    for (Path p : paths){ 
     List<String> lines = Files.readAllLines(p, Charset.forName("UTF-8")); 
     if (!lines.isEmpty()) { 
      if (mergedLines.isEmpty()) { 
       mergedLines.add(lines.get(0)); //add header only once 
      } 
      mergedLines.addAll(lines.subList(1, lines.size())); 
     } 
    } 
    return mergedLines; 
} 
+0

Что такое Paths, какой файл jar является htis? – Siddharth

+0

Это часть стандартного JDK, так как Java 7: http://docs.oracle.com/javase/7/docs/api/java/nio/file/Paths.html – assylias

+0

О, хорошо, спасибо. должен был проверить – Siddharth

3

Это кажется немного тяжеловес, чтобы сделать это в Java. Его тривиальный в оболочке Linux:

(cat FileA ; tail --lines=+2 FileB) > FileC 
0

Перед:

idFile # x_y.csv

После:

idFile.csv

Например:

100 # 1_2.csv + 100 # 2_2.csv> 100.csv

100 # 1_2.csv содержит:

"one","two","three" 
"a","b","c" 
"d","e","f" 

100 # 2_2.csv содержит:

"one","two","three" 
"g","h","i" 
"j","k","l" 

100.csv содержит:

"one","two","three" 
"a","b","c" 
"d","e","f"  
"g","h","i" 
"j","k","l" 

Источник:

//MergeDemo.java 
import java.io.BufferedReader; 
import java.io.BufferedWriter; 
import java.io.File; 
import java.io.FileNotFoundException; 
import java.io.FileReader; 
import java.io.FileWriter; 
import java.io.IOException; 
import java.util.ArrayList; 
//import java.util.Arrays; 
import java.util.Iterator; 
import java.util.Scanner; 

public class MergeDemo { 

    public static void main(String[] args) { 

     String idFile = "100"; 
     int numFiles = 3; 

     try { 
      mergeCsvFiles(idFile, numFiles); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

    } 

    private static void mergeCsvFiles(String idFile, int numFiles) throws IOException { 

     // Variables 
     ArrayList<File> files = new ArrayList<File>(); 
     Iterator<File> iterFiles; 
     File fileOutput; 
     BufferedWriter fileWriter; 
     BufferedReader fileReader; 
     String csvFile; 
     String csvFinal = "C:\\out\\" + idFile + ".csv"; 
     String[] headers = null; 
     String header = null; 

     // Files: Input 
     for (int i = 1; i <= numFiles; i++) { 
      csvFile = "C:\\in\\" + idFile + "#" + i + "_" + numFiles + ".csv"; 
      files.add(new File(csvFile)); 
     } 

     // Files: Output 
     fileOutput = new File(csvFinal); 
     if (fileOutput.exists()) { 
      fileOutput.delete(); 
     } 
     try { 
      fileOutput.createNewFile(); 
      // log 
      // System.out.println("Output: " + fileOutput); 
     } catch (IOException e) { 
      // log 
     } 

     iterFiles = files.iterator(); 
     fileWriter = new BufferedWriter(new FileWriter(csvFinal, true)); 

     // Headers 
     Scanner scanner = new Scanner(files.get(0)); 
     if (scanner.hasNextLine()) 
      header = scanner.nextLine(); 
     // if (scanner.hasNextLine()) headers = scanner.nextLine().split(";"); 
     scanner.close(); 

     /* 
     * System.out.println(header); for(String s: headers){ 
     * fileWriter.write(s); System.out.println(s); } 
     */ 

     fileWriter.write(header); 
     fileWriter.newLine(); 

     while (iterFiles.hasNext()) { 

      String line;// = null; 
      String[] firstLine;// = null; 

      File nextFile = iterFiles.next(); 
      fileReader = new BufferedReader(new FileReader(nextFile)); 

      if ((line = fileReader.readLine()) != null) 
       firstLine = line.split(";"); 

      while ((line = fileReader.readLine()) != null) { 
       fileWriter.write(line); 
       fileWriter.newLine(); 
      } 
      fileReader.close(); 
     } 

     fileWriter.close(); 

    } 

}