# Doppelte Datensätze aus CSV-Datei löschen



## paradox. (11. Mrz 2014)

Hallo,

ist es möglich aus einer CSV-Datei alle doppelt vorkommenden Datensätze zu löschen?
Meine Programm liest eine CSV-Datei von einem URL Link ein und speichert diese in einer neuen CSV-Datei. Wenn ich dass erneut Programm aufrufe, werden alle Datensätze nochmal hinzugefügt + die Datensätze die in der ursprünglichen CSV aus dem Internet neu dazugekommen sind.


----------



## VfL_Freak (11. Mrz 2014)

Moin,



paradox. hat gesagt.:


> ist es möglich aus einer CSV-Datei alle doppelt vorkommenden Datensätze zu löschen?


Sicher ... warum sollte es nicht 



paradox. hat gesagt.:


> Meine Programm liest eine CSV-Datei von einem URL Link ein und speichert diese in einer neuen CSV-Datei. Wenn ich dass erneut Programm aufrufe, werden alle Datensätze nochmal hinzugefügt + die Datensätze die in der ursprünglichen CSV aus dem Internet neu dazugekommen sind.


tja, was soll man jetzt dazu ohne den Code sagen ???:L
*Vermutlich * machst Du beim Einlesen etwas falsch ...

Gruß
Klaus


----------



## paradox. (11. Mrz 2014)

Das wäre mein Code, der liest nur die Datei aus. Jedoch hab ich keinen Plan wie ich an die Sache herangehen soll, dass die Duplikate entfernt werden. Außerdem finde ich es seltsam dass die erste Zeile nicht eingelesen wird und dafür als letzte Zeile null steht.


```
private static void Einlesen() throws FileNotFoundException, IOException {
		try {
			BufferedReader File = new BufferedReader(new FileReader("Dateiausgabe.csv")); 
		    String datei; 
		    
		    try{ 
		    datei = File.readLine(); 
		        while (datei != null) 
		    { 
		    datei = File.readLine(); 
		    System.out.println(datei);
		    } 
		    File.close(); 
		    } 
		    catch (IOException e) { 
		    System.out.println("Fehler beim einlesen der Datei."); 
		    } 
		    } catch (IOException e) {
		    e.printStackTrace();
		    }
		}
		}
```


----------



## VfL_Freak (11. Mrz 2014)

Moin,



paradox. hat gesagt.:


> Das wäre mein Code, der liest nur die Datei aus. Jedoch hab ich keinen Plan wie ich an die Sache herangehen soll, dass die Duplikate entfernt werden.


mir ist noch nicht wirklich klar, wo jetzt was doppelt ist ... und wo Du was speichert ...





paradox. hat gesagt.:


> Außerdem habe ich muss ist es seltsam dass die erste Zeile nicht eingelesen wird und dafür als letzte Zeile null steht.
> 
> ```
> private static void Einlesen() throws FileNotFoundException, IOException {
> ...


Nö, ist es nicht ueh: (siehe die beiden Kommentare oben ... den ersten Satz überspringst Du einfach!)

Richtig wäre es so:

```
private static void Einlesen() throws FileNotFoundException, IOException 
{
    try 
    {
        BufferedReader File = new BufferedReader(new FileReader("Dateiausgabe.csv")); 
        String datei; 
        try
        { 
            while( (datei = File.readLine()) != null )   // !!! 
	    { 
                System.out.println(datei);
            } 
            File.close(); 
	} 
	catch (Exception e) // sonst kommt die FileNotFoundException nicht !!
        { 
	    System.out.println("Fehler beim einlesen der Datei."); 
	    e.printStackTrace();  // besser so !!!
        } 
    }
}
```

Gruß
Klaus


----------



## paradox. (11. Mrz 2014)

VfL_Freak hat gesagt.:


> Moin,
> 
> 
> mir ist noch nicht wirklich klar, wo jetzt was doppelt ist ... und wo Du was speichert ...
> ...



Danke erstmal für die schnelle Antwort!

Es geht darum, dass ich eine CSV Datei aus dem Internet habe, bei der ständig neue Datensätze dazukommen und ältere wegfallen. Diese Datensätze lese ich aus und schreibe Sie in meine Dateiausgabe.csv. Jetzt lese ich die Datei aus dem Internet ein weiteres Mal aus (z.B. weil die Datei sich geändert hat) dann werden die Datensätze einfach an die vorhandenen Datensätze unten angefügt, was auch so sein soll. Jedoch ist jetzt mein Problem, dass teilweise schon vorhandene Datensätze nochmals hinzugefügt werden und diese Duplikate muss ich irgendwie entfernen.

Danke, jetzt ist zumindestens die der null-Wert in der letzten Zeile weg, aber die erste Zeile fehlt leider trotzdem..

Grüße


----------



## VfL_Freak (11. Mrz 2014)

Moin,



> Danke, jetzt ist zumindestens die der null-Wert in der letzten Zeile weg, aber die erste Zeile fehlt leider trotzdem..


hmm, das glaube ich nun kaum, da ich genau diesen Code bei mir in zig Stellen so drin habe .... 
Poste ggf. nochmal Deinen aktuellen Code!


Allerdings habe ich dir im Überschwand der Gefühle :lol: FNF-Exception wegoptimiert - sorry!
Also doch eher so:

```
private static void Einlesen() throws FileNotFoundException, IOException
    {
        try
        {
            BufferedReader File = new BufferedReader(new FileReader("Dateiausgabe.csv"));
            String datei;
            try
            {
                while( (datei = File.readLine()) != null )   // !!!
                {
                    System.out.println(datei);
                }
                File.close();
            }
            catch( IOException e )
            {
                e.printStackTrace();
            }
        }
        catch( FileNotFoundException ex )
        {
            e.printStackTrace();
        }
    }
```
Die SysOuts kannst Du Dir übrigens ersparen, da der Typ ja schon im StackTrace steht!


Zu den doppelten Einträgen:
ist doch klar ... wenn Du jedesmal die gesamte csv-Datei ausliest und 'stumpf' anhängst (warum sollte das so gewollt sein ??), dann sind natürlich Zeilen doppelt!

Warum schreibst Du nicht jedesmal in eine leere Datei?

Andernfalls fiele mir so auf die Schnelle nur ein, dass Du die Zieldatei auch in eine geeignete Struktur einliest und dann beim Einlesen mit der obigen Funktion jedesmal diese Struktur nach der gerade eingelesen Zeile durchsuchst, um ggf. entscheiden zu können, ob Du anhängst oder eben nicht!
Das ist aber ggf. sicher so unperformant wie nur was!

Was soll denn überhaupt damit erreicht werden?

Gruß
Klaus


----------



## paradox. (12. Mrz 2014)

Guten Morgen,

hier nochmal mein Code, wo die erste Zeile der Datei nicht ausgegeben wird.


```
private static void Einlesen() throws FileNotFoundException, IOException {
		try {
			BufferedReader File = new BufferedReader(new FileReader("Dateiausgabe.csv")); 
		    String datei; 
		    
		    try{ 
		    datei = File.readLine(); 
		    while( (datei = File.readLine()) != null ){
		    System.out.println(datei);
		    } 
		    File.close(); 
		    } 
		    catch (IOException e) { 
		    e.printStackTrace();
		    } 
		    } catch (IOException e) {
		    e.printStackTrace();
		    }
		}
```

Zum Thema Duplikate entfernen. Ich muss jetzt mal etwas weiter ausholen. Also ich hab schon ein Programm geschrieben, das eine URL einliest wo eine CSV Datei (nennen wir sie mal online.csv) liegt, diese CSV Datei wird ausgelesen und in meine "Dateiausgabe.csv" geschrieben. In dieser online.csv befinden sich die Daten der letzten 7 Tage, jedoch muss ich mit meiner Dateiausgabe.csv eine Übersicht über mehrere Wochen erstellen, da das zu Auswertungszwecken dienen soll. Und das das Programm mehrmals täglich aufgerufen werden wird, muss ich irgendwie versuchen alle Duplikate zu entfernen, aber ich kann ja nicht jedes Mal die CSV Datei überschreiben, da sonst alle Datensätze, die älter als 7 Tage sind, entfernt werden.


----------



## VfL_Freak (12. Mrz 2014)

Moin,



paradox. hat gesagt.:


> hier nochmal mein Code, wo die erste Zeile der Datei nicht ausgegeben wird.


Kein Wunder, du liest die erste Zeile ja immer noch separat aus, ohne sie zu behandeln ;(
In der Deklaration der WHILE-Schleife wird dann ja erneut gelesen, also schon die zweite Zeile :autsch:


```
private static void Einlesen() throws FileNotFoundException, IOException {
		try {
			BufferedReader File = new BufferedReader(new FileReader("Dateiausgabe.csv")); 
		    String datei; 
		    try{ 

//		    datei = File.readLine();  DIESE ZEILE MUSS RAUS !!!!!!!!!!!

		    while( (datei = File.readLine()) != null ){
		    System.out.println(datei);
		    } 
		    File.close(); 
		    } 
		    catch (IOException e) { 
		    e.printStackTrace();
		    } 
		    } catch (IOException e) {
		    e.printStackTrace();
		    }
		}
```



paradox. hat gesagt.:


> Zum Thema Duplikate entfernen. Ich muss jetzt mal etwas weiter ausholen. Also ich hab schon ein Programm geschrieben, das eine URL einliest wo eine CSV Datei (nennen wir sie mal online.csv) liegt, diese CSV Datei wird ausgelesen und in meine "Dateiausgabe.csv" geschrieben. In dieser online.csv befinden sich die Daten der letzten 7 Tage, jedoch muss ich mit meiner Dateiausgabe.csv eine Übersicht über mehrere Wochen erstellen, da das zu Auswertungszwecken dienen soll. Und das das Programm mehrmals täglich aufgerufen werden wird, muss ich irgendwie versuchen alle Duplikate zu entfernen, aber ich kann ja nicht jedes Mal die CSV Datei überschreiben, da sonst alle Datensätze, die älter als 7 Tage sind, entfernt werden


dann verweise ich noch mal auf meinen vorherigen Post ....

Gruß
Klaus


----------



## paradox. (12. Mrz 2014)

Ah mist, gut danke jetzt klappts :toll:



VfL_Freak hat gesagt.:


> dann verweise ich noch mal auf meinen vorherigen Post ....



ok dann werde ich die Daten mal in ein Array einlesen und dann mal weitersehen. Danke schon mal..


----------



## VfL_Freak (12. Mrz 2014)

Moin,

prima 

Wobei die Frage bleibt, ob ein Array Dir da wirklich weiterhilft. Das hängt dann sicher auch von konkreten Inhalt der csv-Datei ab.

Ich würde bspw. eher zu einer HashMap tendieren, da Du da so nette Funktionen hast wie "_containsValue_" ... wirf mal eine Blick in die API: Java Platform SE 7

Gruß
Klaus


----------



## paradox. (12. Mrz 2014)

VfL_Freak hat gesagt.:


> Moin,
> 
> prima
> 
> ...



Eigentlich müsst ich nur immer eine Spalte vergleichen, da wenn die Uhrzeit der Messung abweicht auch der Datensatz abweicht. Wäre dann doch nicht ein Array günstiger, wenn ich die Split-Funktion verwende?


----------



## VfL_Freak (12. Mrz 2014)

Moin,



paradox. hat gesagt.:


> Eigentlich müsst ich nur immer eine Spalte vergleichen, da wenn die Uhrzeit der Messung abweicht auch der Datensatz abweicht. Wäre dann doch nicht ein Array günstiger, wenn ich die Split-Funktion verwende?


Äh  ... Uhrzeit???:L Messung???:L
Was steht denn konkret in der Datei drin?

Zeig' mal den Aufbau!

Gruß
Klaus


----------



## paradox. (12. Mrz 2014)

VfL_Freak hat gesagt.:


> Moin,
> 
> 
> Äh  ... Uhrzeit???:L Messung???:L
> ...



Es sind die Daten einer Schraubsteuerung. Hier mal die Spaltenbezeichnungen und darunter ein kleines Beispiel  

Datum,Uhrzeit,Programmnummer,Status,Gesamtlaufzeit,Schritt1,Moment1,Winkel1,
Schritt2,Moment2,Winkel2,Schritt3,Moment3,Winkel3,SchrittNIO,MomentNIO,WinkelNIO,FC Status,
FC Zaehler,Momenteinheit,Winkeleinheit
04.03.2014,00:51:30,1,10,0.6,0,0.00,0,0,0.00,0,0,0.00,0,1,0.31,1066,0,0/0,Nm,Grad


----------



## VfL_Freak (12. Mrz 2014)

Moin,

aha, und Du hast Dann pro {Datum|Uhrzeit} immer genau einen Satz?
Dann wäre das doch ein gutes Suchkriterium, um die doppelten Sätze rauszufiltern ...

Rausziehen kannst Du Werte per SPLIT, RegEx oder ganz simpel mittels SUBSTRING !

Gruß
Klaus


[EDIT]
[OT]
Sorry, habe deine Anfrage abgelehnt, da ich in dieser Beziehung nicht sonderlich "SocialMedia-affin" bin 
[/OT]
[/EDIT]


----------



## paradox. (12. Mrz 2014)

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

		// Einlesen
		FileReader myFile = null;
		BufferedReader buff = null;
		final List<String> lines = new ArrayList<String>();

		try {
		myFile = new FileReader("Dateiausgabe.csv");
		buff = new BufferedReader(myFile);
		String line;
		while ((line = buff.readLine()) != null) {
		System.out.println(line); // kontrolle was eingelesen

		lines.add(line);
		}
		}
		 catch (IOException e) {
			 System.err.println("Fehler:" + e);
			 } finally {
			 try {
			 buff.close();
			 myFile.close();
			 } catch (IOException e) {
			 System.err.println("Fehler:" + e);
			 }
	}
		final String[][] valuesArray = new String[lines.size()][];
		int zaehler = 0;
		for (final String line : lines) {
		valuesArray[zaehler++] = line.split(",");
		}

}}
```

irgendwie hat das jetzt mit dem trennen nicht ganz so geklappt..


----------



## VfL_Freak (12. Mrz 2014)

Moin,

hmm ..... verstehe nicht so ganz, was Du da versuchst ... 

```
final String[][] valuesArray = new String[lines.size()][]; // warum 2D??
int zaehler = 0;
for (final String line : lines) {
valuesArray[zaehler++] = line.split(","); // das kann so auch nicht klappen
```



```
for (final String line : lines) 
{
    String[] valuesArray = line.split(","); // enthält jetzt das Ergebnis des Splits
    
    // nun kann das Stringarray 'valuesArray' zu einer entsprechenden Struktur (bspw. HashMap, Liste,
    // Vektor) hin zugefügt werden !!
}
```
Gruß
Klaus


----------



## paradox. (12. Mrz 2014)

VfL_Freak hat gesagt.:


> Moin,
> 
> hmm ..... verstehe nicht so ganz, was Du da versuchst ...
> 
> ...



Sehr verwirrend alles, besonders dass ich bis jetzt nur mit Arrays gearbeitet habe..


```
for (final String line : lines) 
		{
		    String[] valuesArray = line.split(","); 
		    List<String> liste = Arrays.asList(valuesArray);  
			duplikateLoeschen(liste);
		      for (String e : liste)  
		      {  
		         System.out.println(e);
		      }
		}
		}

	  public static void duplikateLoeschen(List<String> liste) {
	    HashSet<String> hashSet = new HashSet<String>(liste);
	    liste.clear();
	    liste.addAll(hashSet);
	  }
```

Das sollte doch jetzt so irgendwie klappen? Wie gesagt habe noch nie mit ArrayList gearbeitet, ist gerade etwas verwirrend.


----------



## paradox. (13. Mrz 2014)

paradox. hat gesagt.:


> Sehr verwirrend alles, besonders dass ich bis jetzt nur mit Arrays gearbeitet habe..
> 
> 
> ```
> ...




Kann mir niemand weiterhelfen? Komm nicht drauf was mein Fehler ist..


----------

