# CSV Import - Zeilen, Spalten



## 0blacko0 (5. Dez 2008)

Hallo,

Ich muss folgenden Programm schreiben

CSV
Dies sind Textdateien, in denen Datentabellen gespeichert sind. Jede Zeile in der Datei entspricht einem Datensatz, die einzelnen "Spalten" sind durch Trennzeichen voneinander getrennt. In der ersten Zeile der Datei sind oft die Spaltennamen gespeichert.

Bsp:
KatNr;Nachname;Vorname;Geburtsdatum <- erste Zeile mit Spaltennamen, Trennzeichen ist hier der ;
1;Müller;Maxi;01.01.1980
2;Zisch;Walter;25.11.1981
	alle weiteren Zeilen enthalten die Wert

hier UML:





und hier mein Programm, soweit komme ich dann kommt eine Denkblockade oder so :bahnhof: 
könnt ihr mir wenigstens sagen was ich machn soll und erklären, weil ich das verstehen und nicht nur die Lösung haben  


```
package bsp;
import javax.swing.*;
/**
 *	der Konstruktor nimmt den Dateinamen zu einer CSV-Datei auf und 
 *	alternativ auch, ob die Datei Spaltennamen in der ersten Zeile gespeichert 
 *	hat oder nicht. Wenn keine CSV-Datei übergeben wurde (Endung ist nicht .csv),
 * 	dann soll eine IllegalAccessException geworfen werden.
 *
 */

public class CSVImport {
	private String dateiname;	
	private boolean hatSpaltennamen; 
	private String[][] daten;
	
	public CSVImport(String dateiname) throws IllegalAccessException	{
		dateiname="test.csv";
		this.dateiname=dateiname;
		
	}
	
	public CSVImport(String dateiname, boolean hatSpaltennnamen)	{
		dateiname="test.csv";
		this.dateiname=dateiname;
		this.hatSpaltennamen=hatSpaltennamen;
	}
	
	private void Import()	{
		
	}
	
	public String[][] getZeilen()	{
		return null;
	}
	
	public String[] getSpalte(int nr)	{
		return null;
	}
	
	public String getSpaltenName(int nr)	{
		return null;
	}
	
	public int getAnzahlZeilen()	{
		return 0;
	}
	
	public int getAnzahlSpalten()	{
		return 0;
	}
}
```

mfg


----------



## quivadis (5. Dez 2008)

Hallo 0blacko0,

die Konstruktoren sind schon mal nicht richtig, weil die  den ihr übergebenen Wert nicht  annehmen da er im Konstruktor wieder überschrieben wird. 
Die Zeilen sind im Konstruktor nicht ganz richtig: 


```
dateiname="test.csv";
```

Wenn das nur zu Testzwecken drin sein sollte ist es auch nicht richtig, so baut man sich nur Fehler rein. Besser ist die Klasse in einer Testklasse aufzurufen, welche auch eine Main-Methode hat. In dieser Testklasse kannst du dann den Dateinamen übergeben.

Weiter in Deinem Programm:

Es ist in meiner Meinung nach nicht Sinnvoll die Anzahl der Zeilen zurückzugeben, zumindest nicht am Anfang. Da es sich um Textdateien handelt, können diese immer bis zum EOF, sprich zum Dateiende eingelesen werden. Während des einlesens kannst du die Anzahl der Zeilen zählen lassen. Ansonsten meiner Meinung doppelter Aufwand.

Eigentlich brauchst du Anzahl der Zeilen auch gar nicht.

Du liest die Textdatei Zeile für Zeile bis zum Ende ein.  Die erste eingelesene Zeile muss anders behandelt werden da sie ja die Spaltennamen enthält. 
Die weiteren Zeilen enthalten ja die Werte der Spalten. 

Schaue dir mal die String-Verarbeitung in Java an. 

Weiter kann ich Dir im Moment nicht helfen, da mir keine Informationen zur weiteren Verarbeitung der Daten vorliegen.

Gruß

quivadis 
[/quote]


----------



## 0blacko0 (5. Dez 2008)

Ich bedanke mich für deine Meldung, aber ich kenne mich noch immer nicht aus
ich schau mal  API von String nach^^


----------



## quivadis (5. Dez 2008)

Wo ist Dein Problem genau?

Du willst nur eine csv-Datei einlesen. Dazu brauchst du eigentlich keine Klasse, sondern eine Methode reicht.
Dieser Methode übergibst du denn Datennamen der CSV-Datei.

Mit dem Dateinamen erzeugst du ein filereader objekt.
Danach eventuell ein bufferreader-Objekt.

Dann Datei öffnen und Zeile für Zeile einlesen und die Daten Verarbeiten.
Die ganze Zeile in einen String einlesen, und zerlegen. Wenn du Dir die Stringverarbeitung angeschaut hast bekommst das hin.


Wie gesagt ohne genauere Angaben kann ich Dir nicht besser helfen.


----------



## 0blacko0 (5. Dez 2008)

ich kenn mich nicht aus wie ich das alles machen soll mit den zeilen und spalten etc.

ok ich schreibe einmal was man in den methoden reinschreiben muss:

    - der Konstruktor nimmt den Dateinamen zu einer CSV-Datei auf und alternativ auch, ob die Datei Spaltennamen    
        in der ersten Zeile gespeichert hat oder nicht. Wenn keine CSV-Datei übergeben wurde , dann soll     
        eine IllegalAccessException geworfen werden.

    - die private Methode import() liest die Datei ein und speichert sie in einem 2D-String-Array                               (jede Zeile entspricht   einem String-Array der Spaltenwerte). Sie wird von den Konstruktoren aufgerufen.
      Sollten beim Import Fehler auftreten, oder die Datei leer sein, soll das Objekt trotzdem gültig sein!

     - getZeilen() liefert das 2D-String-Array zurück

      - getSpalte liest alle Werte einer Spalte (z.B. alle Nachnamen) und liefert diese als String-Array zurück. Welche        Spalte es sein soll bestimmt der Parameter nr. Wenn eine ungültige Nummer angegeben wird (z.B. negative Werte, Spaltennummern die es nicht gibt) soll eine IllegalArgumentException geworfen werden.

    - getSpaltenName liefert den Namen einer Spalte, so er in der Datei vorhanden war. Gab es keine Spaltennamen in der Datei soll die Methode eine NoSuchFieldException werfen.

    - getAnzahlZeilen() und getAnzahlSpalten() liefern die entsprechenden Informationen.


----------



## quivadis (5. Dez 2008)

Das ist praktisch die Aufgabenstellung aus der Schule?

Mir ist jetzt einiges klarer. Willst du eine fertige Lösung, oder hast du konkrete Probleme?

Wie gesagt du musst Dir Dateiverarbeitung, Arrays, Strings und die Fehlerbehandlung mal anschauen.

Bei Fragen einfach fragen, wenn ich helfen kann helfe ich Dir gerne, nur eine fertige Lösung ist auch nicht der Sinn der Sache da lernst du ja nichts.


----------



## 0blacko0 (6. Dez 2008)

quivadis hat gesagt.:
			
		

> Das ist praktisch die Aufgabenstellung aus der Schule?
> 
> Mir ist jetzt einiges klarer. Willst du eine fertige Lösung, oder hast du konkrete Probleme?
> 
> ...



Ja Ok , aber ich will das ja auch verstehn^^
du könntest auch kommentieren    :###


----------



## quivadis (6. Dez 2008)

Dann gib mal Deinen jetzigen Quellcode hier ein unter Berücksichtigung der Aufgabenstellung werde ich versuchen diesen zu kommentieren.

Programmieren lernt man eigentlich nur durch selbst probieren, da du auch etwas lernen willst, werde ich im ersten Schritt nur schreiben,  was falsch ist. 

Wenn du ach noch in Worten haben willst wie die Lösung asl Algorithmus ist musste es sagen.

*Tipp:
Und die Zeilen und Spalten beziehen sich nicht auf die CSV-Datei, sondern auf das Array.*


----------



## 0black0 (6. Dez 2008)

Ok hier:


```
import javax.swing.*;
/**
 *  der Konstruktor nimmt den Dateinamen zu einer CSV-Datei auf und 
 *  alternativ auch, ob die Datei Spaltennamen in der ersten Zeile gespeichert 
 *  hat oder nicht. Wenn keine CSV-Datei übergeben wurde (Endung ist nicht .csv),
 *  dann soll eine IllegalAccessException geworfen werden.
 *
 */

public class CSVImport {
    /**
     * Dateiname der CSV-Datei, für die dieses Objekt steht
     */
    private String dateiname;   
    /**
     * definiert ob ein Spaltennamen 
     */
    private boolean hatSpaltennamen=false; 
   /**
    * speichert die Daten aus der CSV-Datei
    */
    private String[][] daten;
    
    /**
     * Dieser Konstruktor übergibt den Attributen den Wert des Parameters
     * @param dateiname ist der Name der Datei
     */
    public CSVImport(String dateiname) throws IllegalAccessException    {
        this.dateiname=dateiname;
    }
    
    /**
     * Dieser Konstruktor übergibt den Attributen den Wert des Parameters
     * @param hatSpaltennamen definiert ob ein Spaltenname vorhanden ist 
     */
    public CSVImport(String dateiname, boolean hatSpaltennnamen) throws IllegalAccessException   {
        this.hatSpaltennamen=hatSpaltennamen;
        if((dateiname==null) || (dateiname.equals(""))) {
            throw new IllegalAccessException("Die angegebene Datei ist keine CSV DATEI!");
        }
        char letztesZeichen=dateiname.charAt(dateiname.length()-1);
        if(dateiname.subString(dateiname.length()-5).equals(".csv"))   {
            this.dateiname=dateiname;
        }else{
            throw new IllegalAccessException("Die angegebene Datei ist keine CSV DATEI!");
        }
    }
    
    private void Import()   {
        
    }
    
    public String[][] getZeilen()   {
        return null;
    }
    
    public String[] getSpalte(int nr)   {
        return null;
    }
    
    public String getSpaltenName(int nr)    {
        return null;
    }
    
    public int getAnzahlZeilen()    {
        return 0;
    }
    
    public int getAnzahlSpalten()   {
        return 0;
    }
}
```


----------



## quivadis (6. Dez 2008)

OK, das dauert einen Moment.

Eine Frage habe ich noch, bezüglich Array. 

Das Array bekommt immer eine Anfangsgröße, welche im Laufe des Programmess, während der Laufzeit nicht mehr geändert werden kann. Ist also demzufolge die Anzahl der Zeilen und Spalten in der CSV-Datei vorgegeben oder soll das dymamisch gehen?


----------



## 0black0 (6. Dez 2008)

Das Programm soll es nur herauslesen


----------



## quivadis (6. Dez 2008)

Hier mal ein leicht Kommentierter Quellcode.

Ich würde Dir empfehlen in einen Netbeans, Eclipse ...  zu schreiben, wegen Methoden usw. Schreibweise

Hoffe hilft ein klein wenig.  

Ob die Datei eine CSV-Datei ist würde ich nicht nur an der Endung fest machen. Endungen sagen wie Dateinnamen nicht immer die Wahrheit über den Inhalt der Datei aus.



```
import javax.swing.*;
 
 
 
/**
*  der Konstruktor nimmt den Dateinamen zu einer CSV-Datei auf und
*  alternativ auch, ob die Datei Spaltennamen in der ersten Zeile gespeichert
*  hat oder nicht. Wenn keine CSV-Datei übergeben wurde (Endung ist nicht .csv),
*  dann soll eine IllegalAccessException geworfen werden.
*
*/

public class CSVImport {
    /**
     * Dateiname der CSV-Datei, für die dieses Objekt steht
     */
    private String dateiname;   
   
    /**
     * definiert ob ein Spaltennamen   
     */
    private boolean hatSpaltennamen=false;
   
    /**
    * speichert die Daten aus der CSV-Datei
    */
    private String[][] daten;
   
    /**
     * Dieser Konstruktor übergibt den Attributen den Wert des Parameters
     * @param dateiname ist der Name der Datei
     */
    public CSVImport(String dateiname) throws IllegalAccessException    {
        this.dateiname=dateiname;
    }
   
    /**
     * Dieser Konstruktor übergibt den Attributen den Wert des Parameters
     * @param Dateiname übergebener Dateiname
     * @param hatSpaltennamen definiert ob ein Spaltenname vorhanden ist
     */
    public CSVImport(String dateiname, boolean hatSpaltennnamen) throws IllegalAccessException   {
              
        hatSpaltennamen=hatSpaltennamen;  // <<<< Fehler: Variable übergibt an sich selbst!  
        
        
        if((dateiname==null) || (dateiname.equals(""))) {
            throw new IllegalAccessException("Die angegebene Datei ist keine CSV DATEI!");   // 
        }
        char letztesZeichen=dateiname.charAt(dateiname.length()-1);
        if(dateiname.substring(dateiname.length()-5).equals(".csv"))   {
            this.dateiname=dateiname;
        }else{
            throw new IllegalAccessException("Die angegebene Datei ist keine CSV DATEI!");
        }
    }
   
    private void Import()   {
        
        // Hier dann das Dateiopbjekt erzeugen und die Datei Zeilenweise einlesen
        // da ihr nur ein Array verwenden dürft, muss die Datei 2 * eingelesen werden
        // als 1. zum Zeilen zählen, wenn spaltenname vorhanden -1 und hatSpalten =true
        // als 2. das eigentlich enlesen der Daten
        //        Spaltennamen werden wie ein normaler Datensatz behandelt
  
        
    }
   
    public String[][] getZeilen()   {
       
        // Rückgabe aller Zeilen aus dem Array ?
        
        return null;
    }
   
    public String[] getSpalte(int nr)   {
        
        // Rückgabe der Übergebenen Spalte aus dem Array
        
        return null;
    }
   
    public String getSpaltenName(int nr)    {
        
        // Rückgabe des Übergebenen Spaltennamens aus dem Array
        
        return null;  // Spaltenname zurückgeben
    }
   
    public int getAnzahlZeilen()    {
        return 0;
    }
   
    public int getAnzahlSpalten()   {
        return 0;
    }
}
```


----------



## quivadis (7. Dez 2008)

Hallo 0black0,

bist du einigermaßen klargekommen. Das was du bis jetzt hattest war doch schon ganz gut. 
Die Stelle an welcher ich fehler geschrieben hatte, da meckert mein Netbeans rum, obwohl meiner Meinung nach Syntaktisch in Ordnung ist.

Bei Problemen oder Fragen einfach sagen wo Dein Problem ist, ist wie du Hilfe erwartest, quelltext oder Kommentare.


----------



## 0blacko0 (9. Dez 2008)

Ich bin derzeit soweit und weiter kann ich nicht
(hab mich nur am Samstag damit beschäftigt^^)


```
import javax.swing.*;
import java.io.*;
import java.io.FileNotFoundException;
/**
 *  der Konstruktor nimmt den Dateinamen zu einer CSV-Datei auf und 
 *  alternativ auch, ob die Datei Spaltennamen in der ersten Zeile gespeichert 
 *  hat oder nicht. Wenn keine CSV-Datei übergeben wurde (Endung ist nicht .csv),
 *  dann soll eine IllegalAccessException geworfen werden.
 *
 */

public class CSVImport {
    /**
     * Dateiname der CSV-Datei, für die dieses Objekt steht
     */
    private String dateiname;   
    /**
     * definiert ob ein Spaltennamen 
     */
    private boolean hatSpaltennamen=false; 
   /**
    * speichert die Daten aus der CSV-Datei
    */
    private String[][] daten;
    
    /**
     * Dieser Konstruktor übergibt den Attributen den Wert des Parameters
     * @param dateiname ist der Name der Datei
     */
    private String spaltenName;
    
    public CSVImport(String dateiname) throws IllegalAccessException    {
        this.dateiname=dateiname;
    }
    
    /**
     * Dieser Konstruktor übergibt den Attributen den Wert des Parameters
     * @param hatSpaltennamen definiert ob ein Spaltenname vorhanden ist 
     */
    public CSVImport(String dateiname, boolean hatSpaltennnamen) throws IllegalAccessException, FileNotFoundException  {
        this.hatSpaltennamen=hatSpaltennamen;
        if((dateiname==null) || (dateiname.equals(""))) {
            throw new IllegalAccessException("Die angegebene Datei ist keine CSV DATEI!");
        }
        char letztesZeichen=dateiname.charAt(dateiname.length()-1);
        if(dateiname.substring(dateiname.length()-5).equals(".csv"))   {
            this.dateiname=dateiname;
            	if(hatSpaltennamen==true)	{
            		spaltenName="ja";
            	}else{
            		if(hatSpaltennamen==false)	{
            			spaltenName="nein";
            		}
            	}
        }else{
            throw new IllegalAccessException("Die angegebene Datei ist keine CSV DATEI!");
        }
        importDatei();
    }
    
    /**
     * Liest die CSV-datei und speichert die Werte in das das Attribut
     */
    private void importDatei() throws FileNotFoundException {
        File dateiname=new File(this.dateiname);
        String[][] daten=new String[0][];
        try{
            RandomAccessFile file=new RandomAccessFile(dateiname, "r");
            String zeile=file.readLine();
            while(zeile!=null)    {
               String[] zerlegteZeile=zerlegen(zeile);
               this.daten=arrayErweitern(this.daten);
               daten[0]=zerlegteZeile;
               zeile=file.readLine();
            }
            file.close();
        }catch(FileNotFoundException  e)    {
        }catch(IOException e)   {
            
        }
        
    }
    
    private String[][] arrayErweitern(String[][] altarray)   {
        String[][] hilfsarray=new String[altarray.length+1][];
          for(int z=0; z<altarray.length; z++)   {
            hilfsarray[z]=altarray[z];
          }
          return hilfsarray;
    }
    
    private String[] zerlegen(String zeile)   {
        return zeile.split(";");
    }
    
    public String[][] getZeilen()   {
        return daten;
    }
    
    public String[] getSpalte(int nr) throws IllegalArgumentException  {
        String[] array;
        array=daten[nr];
        return array;
        if(nr<0 || nr>daten.length)	{
        	throw new IllegalArgumentException("Was soll das? Bitte geben sie eine gültige Spaltennummer ein!");
        }
    }
    
    public String getSpaltenName(int nr) throws NoSuchFieldException    {
        return 0;//hmhm, wie geht das?
    }
    
    public int getAnzahlZeilen()    {
        return this.daten.length;
    }
    
    public int getAnzahlSpalten()   {
    	//0. element jeder Zeile<-------------- rechnet man sich die Zeilen so aus?
    	return 0;
    }
}
```


mfg


----------



## quivadis (9. Dez 2008)

Habe im Moment wenig Zeit, werde es mir wenn es nicht dringend ist in den Nächsten Tagen nochmal anschauen.

Die Zeilen brauchst du nicht zu berrechen, das sie ja der Zeilenzahl der eingelesenen Zeilen entspricht. Quassi übergibst du nur die Zählung wieder zurück. Wird gebraucht um die Größe der Arrays zu bestimmen.


----------



## 0black0 (11. Dez 2008)

Hallo,

ich brauche das Programm bis morgen Früh

mfg


----------

