# CSV Datei auslesen



## Dino264 (22. Okt 2014)

Hallo liebe Community,

ich habe wieder mal ein Problem.

Ich möchte eine CSV Datei auslesen lassen.

Ich habe mir nun mit einem Freund eine Main Class gebaut die aber durch eine andere Klasse noch erweitert werden muss.

Jedoch bekomme ich genau dieses erweitern nicht hin. Stehe grade total auf dem Schlauch und habe keine Ahnung wie ich das kleine Programm nun zum laufen bringen kann.

Ich hoffe einer von euch kann mir schnell weiter helfen.

Hier also nun mein bisheriger Quellcode:

Main Class:


```
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;


public class CSVSearch
{
	private String[] columnNames;

	private File csvfile;

	public CSVSearch(String filepath) throws IOException
	{
		this(new File(filepath));
	}

	public CSVSearch(File csvfile) throws IOException
	{
		setCSVFile(csvfile);
		initColumnNames();
	}

	private void initColumnNames() throws IOException
	{
		columnNames = null;

		if (csvfile == null)
			return;

		BufferedReader br = getLineReader();

		String line = br.readLine();
		if (line == null)
		{
			throw new IllegalArgumentException("In " + csvfile.getAbsolutePath() + " fehlt die erste Zeile mit Spaltennamen.");
		}

		columnNames = line.split(";");
		if (columnNames == null || columnNames.length < 1)
			throw new IllegalArgumentException("Zu wenige Spalten!");

		br.close();
	}

	public BufferedReader getLineReader() throws FileNotFoundException
	{
		FileInputStream fstream = new FileInputStream(csvfile);
		DataInputStream in = new DataInputStream(fstream);
		return new BufferedReader(new InputStreamReader(in));
	}

	public void setCSVFile(File f)
	{
		if (f == null || !f.isFile())
			throw new IllegalArgumentException("Datei " + f + " nicht gefunden.");

		csvfile = f;
	}

	public List<CSVLine> match(String colname, String srchstring) throws IOException
	{
		List<CSVLine> mlines = new ArrayList<CSVLine>();

		BufferedReader br = getLineReader();
		String sline = br.readLine();
		while ((sline = br.readLine()) != null)
		{
			CSVLine line = new CSVLine(columnNames, sline);
			if (line.get(colname).contains(srchstring))
			{
				mlines.add(line);
			}
		}
		br.close();

		return mlines;
	}

	public static void main(String args[]) throws Exception
	{
		/*
		 * File f = new File(pfad);
		 * csvsrch = new CSVSearch(f); (oder = new CSVSearch(pfad);)
		 * List<CSVLine> zeilen = csvsrch.match(spaltenname, suchbegriff);
		 * String[] spalten = zeilen.get(0).toArray();
		 * String csvzeile = zeilen.get(0).encodeCSV();
		 * csvzeile = zeilen.get(0);
		 * String inhalt = csvzeile.get(spaltenname);
		 */
		String dateiname = null;
		String name = null;
		String suchbegriff = null;

		if (args.length == 3)
		{
			dateiname = args[0]; // Dateiname  für Aufruf der Datei
			name = args[1]; // Spaltenangabe
			suchbegriff = args[2]; // Suchbegriff in der Spalte
		} else {
			throw new Exception("Applikation benötigt 3 Parameter");
		}
		
		CSVSearch csearch = new CSVSearch(dateiname);
		List<CSVLine> mlines = csearch.match(name, suchbegriff);
		for (int i = 0; i < mlines.size(); i++)
		{
			System.out.println(mlines.get(0).toString());
		}
		}
}
```

Hier nun die zweite Klasse:


```
import java.io.BufferedReader;
import java.io.File;


public class CSVLine
{
	private String columnNames;
	private String source;
	private String columns;

	public CSVLine(String[] colnames, String linesource)
	{

		
		
		
	}

	public String get(String spaltename)
	{
		return null;
	}

}
```

Mit freundlichen Grüßen

Dino264


----------



## Joose (22. Okt 2014)

Jetzt musst du uns nur verraten was denn passieren sollte.
Du meinst du musst was erweitern, es will aber nicht so richt klappen. Was zu tun wäre verratest du uns nicht!

Außerdem warum hast du diesen Thread im Bereich "AWT, Swing, ..." eröffnet? Was hat CSV auslesen mit UI Programmierung zu tun?
Habe es mal verschoben


----------



## Dino264 (22. Okt 2014)

Hey,

ja sorry das ich das Thema im falschen Bereich eröffnet habe. Danke Josse fürs verschieben.

Naja die Main Klasse ist ja mehr oder weniger eine Hülle.

Am ende will ich halt die Daten die in der CSV Datei stehen auslesen und ausgeben lassen.

Ich suche zur Zeit nach einem Weg wie ich das Ergebniss hinbekomme mit Hilfe dieser zwei Klassen.

Hoffe du kannst mir nun weiter helfen.

Viele Grüße

Dino264


----------



## Joose (22. Okt 2014)

Dino264 hat gesagt.:


> Am ende will ich halt die Daten die in der CSV Datei stehen auslesen und ausgeben lassen.
> 
> Ich suche zur Zeit nach einem Weg wie ich das Ergebniss hinbekomme mit Hilfe dieser zwei Klassen.



Dann stelle doch bitte eine konkrete Frage wenn du eine hast.
Bis jetzt hast du nur Code gepostet und beschrieben was gemacht werden sollte.

Was aber fehlt ist:

Was funktioniert nicht? 
Wo passiert ein Fehler? 
Was wird falsch gelesen/ausgegeben? 
Was hast du schon probiert um bei deinem Problem zu einer Lösung zu finden? 

Ich helfe gerne wenn ich kann, aber auch nur wenn ich entsprechende Informationen (die du wahrscheinlich schon hast) bekomme.


----------



## Dino264 (22. Okt 2014)

Hey,

Was nicht funktioniert ist, dass nicht ausgelesen wird und damit auch nichts ausgegeben werden kann.

Wo passiert ein Fehler?

Der Fehler passiert in der Main Klasse in Zeile 75 und 110. Hier dazu die Fehlermeldung:

Exception in thread "main" java.lang.NullPointerException
	at CSVSearch.match(CSVSearch.java:75)
	at CSVSearch.main(CSVSearch.java:110)

Was hast du schon probiert um bei deinem Problem zu einer Lösung zu finden? 

Ich habe nach verschiedenen Ansätze geschaut und einige ausproviert doch leider ohne Erfolg.

Wie gesagt stehe grade total auf dem Schlauch und weiß nicht weiter.

Gruß

Dino264


----------



## Joose (22. Okt 2014)

Dino264 hat gesagt.:


> Der Fehler passiert in der Main Klasse in Zeile 75 und 110. Hier dazu die Fehlermeldung:
> 
> Exception in thread "main" java.lang.NullPointerException
> at CSVSearch.match(CSVSearch.java:75)
> at CSVSearch.main(CSVSearch.java:110)



Und genau diese Fehlermeldung ist sehr gut zu wissen, deswegen immer mitposten wenn man eine hat! 

Die Fehlermeldung sagt auch schon was das Problem ist:
Du greifst auf ein Objekt zu welches null (nicht initialisiert ist), und versuchst mit diesen Objekt zu arbeiten.
Der StackTrace verratet dir in welcher Zeile du zu suchen hast: "at CSVSearch.match(CSVSearch.java:75)"

Wenn du eine IDE hast debugge in diese Zeile und kontrolliere welches Objekt null ist, dann überlege warum diese null ist.
Wenn du keine IDE verwendest (würde ich dir zu einer raten), kannst du selbiges machen indem du in Zwischenschritten immer auf != null prüfst.


----------



## Dino264 (22. Okt 2014)

Also ich benutze wie auch schon bei meinem letzten Projekt Eclipse zum Entwickeln.

Ich schätze mal das es an dem Objekt mlines liegt, da auf dieses auch wieder in Zeile 110 zugegriffen wird.

Auch columnNames, sline, colname, srchstring sind leer soweit ich das grade gesehen habe. Ich weiß nun aber nicht wie ich weiter komme.

Gruß


----------



## Joose (22. Okt 2014)

Dino264 hat gesagt.:


> Ich schätze mal das es an dem Objekt mlines liegt, da auf dieses auch wieder in Zeile 110 zugegriffen wird.



Nein. Der StackTrace zeigt dir nur an welche Methoden aufgerufen worden sind (von unten nach oben) bis man zu dem Code mit dem Fehler kommt.
Sprich dein Fehler passiert in der Methode "match", Zeile 75 der Datei. 
Aufgerufen wird die Methode "match" von der "main" Methode, Zeile 110 der Datei.



Dino264 hat gesagt.:


> Auch columnNames, sline, colname, srchstring sind leer soweit ich das grade gesehen habe. Ich weiß nun aber nicht wie ich weiter komme.



Dein Fehler passiert in folgender Zeile:

```
if (line.get(colname).contains(srchstring))
```
In dieser Zeile verwendest du 4 Objekte.

line
colname
srchstring
line.get(colname) // hier bekommst du ein Objekt vom Typ String zurück

"colname" und "srchstring" können null sein, da sonst der StackTrace anders ausschauen würde wenn diese beiden nicht null sein dürften.
Bleiben nur noch die anderen beiden Objekte.

Jetzt überlege: wo initialisierst du dein Objekt "line"? Kann dieses Objekt überhaupt null sein? Was für ein Objekt bekommst du von "line.get(colname)" zurück? Kann diese Objekt überhaupt null sein?


----------



## Dino264 (22. Okt 2014)

Wenn ich mich da nicht täusche initialisierst das Objekt line in Zeile 74. Von "line.get(colname)" bekomme ich das Objekt line zurück oder nicht? Sowohl line als auch line darf nicht null sein.


----------



## arilou (22. Okt 2014)

Deine Klasse CSVLine ist so dermaßen leer, füll'/programmier' die erst mal. Vmtl. ist dein "Fehler" dann auch schon weg.

Könntest z.B. mal drüber nachdenken, was ein CSVLine-Objekt beim Aufruf von .get(...) eigentlich zurückliefert...


----------



## Ruzmanz (22. Okt 2014)

Guck dir doch mal bitte deinen eigenen Code an:


```
if (line.get(colname).contains(srchstring))
//...
public String get(String spaltename)
{
return null;
}
```

line.get(xyz)
-> line ist nicht null.

linge.get(xyz)
-> liefert IMMER null zurück. Das ist so programmiert.

null.contains(xyz)
-> Geht nicht.


----------



## Dino264 (22. Okt 2014)

Hallo Ruzmanz,

soweit verstehe ich das ja. Ist klar das dann eine Nullpointerexception kommt. Aber das Problem was ich grade halt habe ist das ich nicht weiß wie ich das anders Definiere. 

Kannst du mir da einen kleinen Anstoß in Form von 1 - 2 Zeilen code geben?

Gruß

Dino264


----------



## Joose (22. Okt 2014)

Dino264 hat gesagt.:


> Aber das Problem was ich grade halt habe ist das ich nicht weiß wie ich das anders Definiere.
> Kannst du mir da einen kleinen Anstoß in Form von 1 - 2 Zeilen code geben?



Woher sollen wir wissen wie du deine Klasse CSVLine implementiert haben willst?
Was hast du dir beim Erstellen dieser "get" Methode gedacht was die Methode machen soll?
Worin liegt das Problem diese Funktionalität umzusetzen?


----------



## Dino264 (22. Okt 2014)

Naja die Klasse soll so einfach wie möglich implementiert werden.

Die Methode habe ich erstellt und eine Zeile auszugeben die in der angegebenen Spalte den angegebenen Suchbegriff enthält. Dieses Methode überprüft das und gibt speichert diese Zeile in einer Variable die später ausgegeben wird. Das Problem ist das ich nicht weiß wie ich ansetzen muss. Ich weiß ja eben nicht wie ich dies Funktion richtig umsetze bzw. was in die andere Klasse alles rein muss damit meine Methode so funktioniert wie sie soll.


----------



## Joose (22. Okt 2014)

Dino264 hat gesagt.:


> Die Methode habe ich erstellt und eine Zeile auszugeben die in der angegebenen Spalte den angegebenen Suchbegriff enthält.



Von welcher Methode redest du hier? Die Methode "get" der Klasse CSVLine erwartet einen Parameter, den Spaltennamen.
Was hat also die Methode mit deinem Suchbegriff zu tun?

Soll die Methode "get" den Wert der "linesource" an Spalte X zurückliefern?



Dino264 hat gesagt.:


> Dieses Methode überprüft das und gibt speichert diese Zeile in einer Variable die später ausgegeben wird. +



Lies dir diesen Satz bitte nochmals durch und überlege ob du als außenstehender verstehen würdest was damit gemeint ist.



Dino264 hat gesagt.:


> Das Problem ist das ich nicht weiß wie ich ansetzen muss. Ich weiß ja eben nicht wie ich dies Funktion richtig umsetze bzw. was in die andere Klasse alles rein muss damit meine Methode so funktioniert wie sie soll.



Gehe dein Problem Schritt für Schritt an! Nicht alles auf 1x so wird nie etwas fertig, bzw. es ist mehr ein durcheinander als schön programmiert.

Programmiere nur deine Klasse CSVLine fertig, überlege welche Methoden alle gebraucht werden (für diese Klasse) und implementiere diese.
In der "main" Methode erstellst du dann ein paar Dummy-Objekte (Testobjekte) von der Klasse CSVLine mit Testdaten.
Dann überprüfst du anhand dieser Testobjekte die Funktionsweise deiner Methoden (Hinweis: Für diese Vorgehen gibt es eigenen Begriff -> Unit Tests)
Wenn diese Klasse passt dann kannst du dich darum kümmern die Klasse CSVSearch zu implementieren.


----------



## Dino264 (22. Okt 2014)

Ja aber genau da stehe ich ja auf dem Schlauch. Ich will ja die Klasse CSVLine fertig machen aber ich weiß halt nicht wie. Da liegt ja der Hase im Pfeffer.


----------



## chuxXo (22. Okt 2014)

Ich habe jetzt zwar nicht alles durchgelesen, aber eine CSV kannst du sehr schnell mit folgendem Code auslesen:


```
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;



    public class ReadCsv {

        public static void main(String[] args) {
            
             String fileName = "deine.csv";
             File file = new File(fileName);
             List<String> CSV = new ArrayList<String>();

                 Scanner inputStream;
                try {
                    inputStream = new Scanner(file);
                    while(inputStream.hasNext())
                        {    
                         String input = inputStream.next();
                         System.out.println(input);
                         CSV.add(input);
                         }
                    } 
                catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                
                System.out.printf("Die CSV-Datei besteht aus %d Zeilen",CSV.size());
             
             
        }
    }
```

vllt kann ich dir bei deinem weiteren Problem weiterhelfen, wenn noch eins besteht.


----------



## Dino264 (22. Okt 2014)

Hallo chuxXo,

danke erstmal für deine Antwort.
Ja ich weiß.

Das ganze soll aber für 3 Parameter aufgerufen werden. Diese sind Dateiname, Spaltenname und ein Suchbegriff.
Anschließend soll dann in der angegebenen Datei in der angegebenen Spalte der Suchbegriff gesucht und wenn er gefunden wurde ausgegeben werden.

Hast du auch dafür eine Lösung für mich? Vielleicht auch eine die ich direkt auf meinen Code hin anwenden kann?

Gruß

Dino264


----------



## Joose (22. Okt 2014)

Dino264 hat gesagt.:


> Ich will ja die Klasse CSVLine fertig machen aber ich weiß halt nicht wie



Dann schreibe dir mal auf ein Blatt Papier, in eine Textdatei oder in die Luft was genau soll deine Klasse CSVLine alles können?
Welche Methoden braucht diese Klasse dafür? Was machen diese einzelnen Methoden?

Beispiel an der Methode "get":
Die Methode "get" soll den Wert der Zeile (linesource) für die Spalte X zurückgeben. (Wobei X ein Parameter vom Typ String ist)
"linesource" ist ein String und enthält die Daten einer ganzen Zeile aus dem CSV File.
Ein CSV File hat immer ein Trennzeichen, anhand diese Trennzeichen müsste ich diesen String splitten und dann den Wert für die gesuchte Spalte zurückgeben.
usw.

Dadurch sollt es dir möglich sein die Methode "get" zu implementieren (die richtigen Stichwörter habe ich dir im Beispiel geliefert)


----------



## chuxXo (22. Okt 2014)

Dino264 hat gesagt.:


> Das ganze soll aber für 3 Parameter aufgerufen werden. Diese sind Dateiname, Spaltenname und ein Suchbegriff.
> Anschließend soll dann in der angegebenen Datei in der angegebenen Spalte der Suchbegriff gesucht und wenn er gefunden wurde ausgegeben werden.
> Dino264



Ich würde es folgendermaßen gestalten:


```
public static void main(String[] args) {
        	String Dateiname = "deine.csv",
        		   Suchbegriff = "Peterpan";     	
        	//ARRAYPOSITION - DANK DARAN -> ERSTE POSITION = "0"
        	int Spaltenname = 0;				
        	
        	GetCsv(Dateiname, Spaltenname, Suchbegriff);
        }
        	
        	
        	
        	public static void GetCsv(String Dateiname, int Spaltenname, String Suchbegriff)
        	{
        	String fileName = Dateiname;
        	File file = new File(fileName);
        	List<String> CSV = new ArrayList<String>();
        	List<String> FoundSuchbegriff = new ArrayList<String>(); 
        	int LineCount = 0;
        	
        	Scanner inputStream;
				try {
					inputStream = new Scanner(file);
					while(inputStream.hasNextLine()){	
	        			 String input = inputStream.nextLine();
	        			 //CSV ZEILE IN ARRAY BEI JEDEM ";" TRENNEN
	        			 String[] inputSplit = input.split(";");
	        			 
	        			 System.out.println(input);
	        			 if (inputSplit[Spaltenname] != "" && inputSplit[Spaltenname].contains(Suchbegriff)){
	        				 FoundSuchbegriff.add("Zeile: "+LineCount+" Spalte: "+Spaltenname+" enthält: "+Suchbegriff);
	        				 System.out.println("In Zeile "+LineCount+"und Spalte "+Spaltenname+" wurde der Suchbegriff: '"+Suchbegriff+"' gefunden");
	        			 }
	        			 else{
	        				 System.out.println("In Zeile "+LineCount+" wurde der Suchbegriff '"+Suchbegriff+"' nicht gefunden");
	        			 }
	        			 CSV.add(input);
	        			 LineCount++;
	        		 	}
					} 
				catch (FileNotFoundException e) {
					e.printStackTrace();
				}		
				System.out.printf("Die CSV-Datei besteht aus %d Zeilen",CSV.size());     	 
				System.out.printf("Der Suchbegriff %s wurde %d gefunden",Suchbegriff,FoundSuchbegriff.size());
        	}
```

hab es bis jetzt noch nicht getestet. Hoffe es funktioniert so und es ist das, was du willst.


----------



## Ruzmanz (22. Okt 2014)

@chuxXo Methoden und Variablen fangen in Java [nahezu] immer mit einem kleinen Buchstaben an. Ausgehend von der Fragestellung und dem Quellcode ist davon auszugehen, dass dies Hausaufgaben sind. Somit wird es wohl egal sein, wenn du das Problem "lösen" kannst, aber nicht seine Klasse dazu benutzt :reflect: Davon abgesehen ist dort bereits 95% fertig.


----------



## chuxXo (22. Okt 2014)

Ist ja sehr schön, dass du das erkannt hast  bist wohl ein Genie! 
Ich will auch nicht seine Klasse lösen, sondern ihm so einen Denkanstoß geben.
Außerdem kanns dir, wie mir egal sein, was er damit anstellt. Entweder es hilft ihm weiter, oder nicht.
Versteh dein Problem nicht.


----------



## Ruzmanz (22. Okt 2014)

Sehe ich nicht so. Mit Quellcode gibt man keinen Denkanstoß, sondern eine Lösung. Mal davon abgesehen scheitert der TE an der Übergabe von den einzelnen Daten von Klasse CSVSearch an CSVLine. Davon sieht man absolut nichts in deinem Code. Als Anfänger ist es zudem notwendig Aufgaben in eine kleinstmöglichste Arbeitsschritte zu teilen und diese präzise zu formulieren. Sorry wenn ich das so direkt sage, aber bei deinem Coding-Skills wäre es besser wenn du dem TS auch nur mit Pseudocode hilfst. Dein "Ansatz" ist zwar richtig, aber ...


```
(inputSplit[Spaltenname] != "" && inputSplit[Spaltenname].contains(Suchbegriff))
```


----------



## chuxXo (22. Okt 2014)

Ich bin auch nicht auf seinen Code eingegange. Wollte nur helfen. Falls dus nicht geschnallt hast, ich hab seine Namen übernommen, damit er sieht, was wo ist. Sind noch keine Profis vom Baum gefallen. Sry, dass ich nicht so heftig unterwegs bin wie du


----------

