2013-08-02 19 views
7

Mam niektóre pliki CSV z tymi samymi nagłówkami kolumn. Na przykładScal pliki CSV w jeden plik bez powtarzających się nagłówków

złożyć

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

Plik B

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

chcę połączyć je tak, że dane zostały połączone w jeden plik z nagłówkami na górze, ale nie ma nagłówków nigdzie indziej .

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

Jaki jest dobry sposób na osiągnięcie tego?

+0

Jestem zakładając, że wiesz, jak czytać pliki linia po linii. Kiedy zapisujesz linie do pliku, pomiń pierwszy wiersz w kolejnych plikach po pierwszym. –

+0

Utwórz plik tekstowy zawierający nagłówek i dołącz do niego każdy plik CSV, pomijając pierwszy wiersz lub odczytaj wszystkie, nie pomijając pierwszego wiersza pierwszego pliku. Pierwszy byłby nieco łatwiejszy, a drugi byłby stosunkowo łatwy i bardziej przenośny, gdybyś miał różne zestawy plików z różnymi nagłówkami. – danielunderwood

Odpowiedz

2

To powinno zadziałać. Sprawdza, czy scalany plik ma pasujące nagłówki. W przeciwnym razie wyrzuciłby wyjątek. Obsługa wyjątków (zamykanie strumieni itp.) Została pozostawiona jako ćwiczenie.

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

Oto przykład:

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

Co to jest Paths, jaki plik jar to htis? – Siddharth

+0

jest częścią standardowego JDK od wersji Java 7: http://docs.oracle.com/javase/7/docs/api/java/nio/file/Paths.html – assylias

+0

o ok, dziękuję. powinien był sprawdzić – Siddharth

3

Wydaje się trochę wagi ciężkiej, aby to zrobić w Javie. Jego trywialna w powłoce Linux:

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

Przed:

idFile # x_y.csv

Po:

idFile.csv

Na przykład:

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

100 # 1_2.csv zawiera:

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

100 # 2_2.csv zawiera:

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

100.csv zawiera:

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

Źródło:

//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(); 

    } 

}