# ArrayIndexOutOfBounds



## Dark-Nemesis (25. Juni 2007)

Kriege den fehler ArrayIndexOutOfBounds sobald in meiner CSV Datei eine Zeile mit einem ; endet, solange es nicht am ende der Zeile ist können auch ;; ohne fehler vorkommen.

Eine Lösung wie man dass lösen könnte wäre nicht verkehrt 


```
BufferedReader Datei = new BufferedReader(new FileReader("C:\\Documents and Settings\\Paul\\Desktop\\Script\\test.csv"));
            zeile = Datei.readLine();

            while (zeile != null)
            {
		if(zeile.contains(";"))
		{
			String[] daten = zeile.split(";");
		}
		else if(zeile.contains(","))
		{
			String[] daten = zeile.split(",");
		}
		else
		{
			System.out.println("File in wrong format! \n" +
					   "The file must be delimited with \";\" or \",\"!");
		}
                
		zeile = Datei.readLine();

//....

//SQL STATEMENTS
		String SqlUpdate = "Update `stundenplan` SET Stunde = '"+daten[0]+"', Montag = '"+daten[1]+"', Dienstag = '"+daten[2]+"', Mittwoch = '"+daten[3]+"', Donnerstag = '"+daten[4]+"', Freitag = '"+daten[5]+"' WHERE Stunde = '"+daten[0]+"' ";
		String SqlSelect = "SELECT Stunde FROM `stundenplan` WHERE Stunde = '"+daten[0]+"' ";
		String SqlInsert = "INSERT INTO `stundenplan` (Stunde, Montag, Dienstag, Mittwoch, Donnerstag, Freitag) VALUES ('"+daten[0]+"', '"+daten[1]+"', '"+daten[2]+"', '"+daten[3]+"', '"+daten[4]+"', '"+daten[5]+"') ";
		//SQL STATEMENTS
```


----------



## Sebastian Seidelmann (25. Juni 2007)

Hi
in welcher Zeile passiert denn der Fehler?

Mein Verdacht ist, dass du daten[5] über das Array hinausschiesst!

MfG djjada


----------



## Dark-Nemesis (25. Juni 2007)

die zeile gibt groovy leider nicht an ...
der verdacht ist schon nicht verkehrt, da es ja beim letzten ; der fehler auftritt, die frage ist nur wie ich es schaffen kann das zu umgehen bei dem split hört er ja scheinbar bei dem letzten ; auf und setzt die daten[5] nicht auf leer bzw. legt den garnicht erst an :/


----------



## KlaDi (25. Juni 2007)

Hallo Dark,

das Problem ist, das Du davon ausgehst, das fünf mal das Semikolon in einer Zeile ist und jeweils davor und dahinter Text steht. In diesem Falle funktioniert Dein Programm theoretisch einwandfrei. Steht aber hinter dem letzten Semikolon kein Text kommt es zu eben jenem Fehler.

Die Frage ist halt, was soll passieren, wenn die Zeile quasi zu "kurz" ist? Soll danach einfach das SQL-Update ausgelassen werden oder soll es angepasst werden?

gruß klaus.


----------



## Dark-Nemesis (25. Juni 2007)

Das Programm sollte in dem Fall quasi einen leer string bzw null eintragen, das Feld muss aber auf jedenfall weiterhin berücksichtigt werden.


----------



## KlaDi (25. Juni 2007)

Hallo, 

dann mach es doch einfach als if-Abfrage:

```
if(daten.length == 6) {
	String SqlUpdate = "Update `stundenplan` SET Stunde = '"+daten[0]+"', Montag = '"+daten[1]+"', Dienstag = '"+daten[2]+"', Mittwoch = '"+daten[3]+"', Donnerstag = '"+daten[4]+"', Freitag = ' ' WHERE Stunde = '"+daten[0]+"' ";
	String SqlSelect = "SELECT Stunde FROM `stundenplan` WHERE Stunde = '"+daten[0]+"' ";
	String SqlInsert = "INSERT INTO `stundenplan` (Stunde, Montag, Dienstag, Mittwoch, Donnerstag, Freitag) VALUES ('"+daten[0]+"', '"+daten[1]+"', '"+daten[2]+"', '"+daten[3]+"', '"+daten[4]+"', ' ') ";
} else {
	String SqlUpdate = "Update `stundenplan` SET Stunde = '"+daten[0]+"', Montag = '"+daten[1]+"', Dienstag = '"+daten[2]+"', Mittwoch = '"+daten[3]+"', Donnerstag = '"+daten[4]+"', Freitag = '"+daten[5]+"' WHERE Stunde = '"+daten[0]+"' ";
		String SqlSelect = "SELECT Stunde FROM `stundenplan` WHERE Stunde = '"+daten[0]+"' ";
		String SqlInsert = "INSERT INTO `stundenplan` (Stunde, Montag, Dienstag, Mittwoch, Donnerstag, Freitag) VALUES ('"+daten[0]+"', '"+daten[1]+"', '"+daten[2]+"', '"+daten[3]+"', '"+daten[4]+"', ' ') ";
}
```

gruß klaus.


----------



## zerix (25. Juni 2007)

Hallo,

du könntest es dann so lösen


```
String[] tmp = new String[6];

if(daten.length < 6)
for(int i = 0; i < daten.length; i++){
   tmp[i] = daten[i];
}


daten = tmp;
```

Also das müsstest du vor dem SQL-Statement ausführen.

MFG

zEriX


----------



## Dark-Nemesis (25. Juni 2007)

Ja, danke werd das mal direkt einbauen/umbauen


----------



## Anime-Otaku (25. Juni 2007)

Oder benutze  eine CSV Lib z.B. opencsv


----------



## zerix (25. Juni 2007)

Ich sehe gerade, da hab ich noch Klammern vergessen. Das kommt davon wenn man das direkt hier schreibt. 


```
String[] tmp = new String[6];

if(daten.length < 6){
for(int i = 0; i < daten.length; i++){
   tmp[i] = daten[i];
}


daten = tmp;
}
```


MFG

zEriX


----------



## Dark-Nemesis (25. Juni 2007)

Die idee mit der CSV Lib war genial  ersparrt einiges an code 
die anderen vorschläge wären aber auch eine alternative gewesen 

danke


----------



## Dark-Nemesis (25. Juni 2007)

Anime-Otaku hat gesagt.:


> Oder benutze  eine CSV Lib z.B. opencsv



Mal ne frage zum der Lib.

Exception occurred during event dispatching:
java.lang.OutOfMemoryError: Java heap space
Exception occurred during event dispatching:
java.lang.OutOfMemoryError: Java heap space

diese Fehlermeldung bekomme ich wenn ich versuch meine eigenen seperatoren zu setzen.... kannst du mir sagen woran es liegt?


```
CSVReader Datei = new CSVReader(new FileReader("C:\\Documents and Settings\\Paul\\Desktop\\Script\\test.csv"), ';');
```


----------



## Anime-Otaku (25. Juni 2007)

java.lang.OutOfMemoryError: Java heap space

Dein java Heap Speicher geht dir aus...dieser ist standardmässig maximal 64MiByte, den kannst du mittels eines Java VM Parameters leicht erhöhen: -Xmx128


----------



## Dark-Nemesis (25. Juni 2007)

Anime-Otaku hat gesagt.:


> java.lang.OutOfMemoryError: Java heap space
> 
> Dein java Heap Speicher geht dir aus...dieser ist standardmässig maximal 64MiByte, den kannst du mittels eines Java VM Parameters leicht erhöhen: -Xmx128



ok ... ist das normal ^^? ich mein das programm ist relativ klein, ebenso die csv die hat gerade mal 5 einträge mit 6 spalten .... die richtige csv wird nachher über 2k einträge haben


----------



## zerix (25. Juni 2007)

Also das mit dem Speicher erhöhen sollte meiner Meinung nach der letzte Ausweg sein, da man es auch immer explizit angeben muss.
Normal ist es nicht wenn dein Programm nicht sehr groß ist. Ich würde sagen, dass du irgendwo viele Objecte erzeugst die den Speicher zum Überlaufen bringen.
Vielleicht solltest du mal den Code posten, wenn es möglich ist.

MFG

zEriX


----------



## Anime-Otaku (25. Juni 2007)

Naja normal ist das glaub ich nicht...die Frage ist auch machst du vorher irgendetwas was nicht aufgeräumt werden kann?

Ansonsten würde ich mal die JConsole im jdk bin Verzeichnis zur Rate ziehen wie es mit der Speicherentwicklung aussieht.


----------



## Dark-Nemesis (25. Juni 2007)

Das wäre der Code, das Speicherproblem tritt aber nur auf wenn ich versuche den CSVReader mit meinen eigenen seperatoren zu füttern.


```
import java.io.*;
import java.sql.*;
import au.com.bytecode.opencsv.*;

Boolean ok = false;
String zeile;
String separator;
int count = 0;
	try 
	{
	    BufferedReader CSVFile = new BufferedReader(new FileReader("C:\\Documents and Settings\\Paul\\Desktop\\Script\\test.csv"));
            zeile = CSVFile.readLine();

	    if(zeile != null)
	    {
		System.out.println("......... Loading file ok!");
		if(zeile.contains(";"))
		{
			System.out.println("......... CSV-File seperated by using \";\"");
			ok = true;
			separator = ";";
		}
		else if(zeile.contains(","))
		{
			System.out.println("......... CSV-File seperated by using \",\"");
			ok = true;
			separator = ",";
		}
		else
		{
			System.out.println("......... Can't find separate entry, maybe this is no CSV-File or wrong CSV-File-Format!");
		}
	    }

	    if(ok == true)
	    {
		    CSVReader Datei = new CSVReader(new FileReader("C:\\Documents and Settings\\Paul\\Desktop\\Script\\test.csv"));
		    String [] daten;

		    while ((daten = Datei.readNext()) != null)
		    {
			count++;
			//SHOWS THE CSV CONTENT
			System.out.println(
						daten[0] + "\t" + 
						daten[1] + "\t" + 
						daten[2] + "\t" +
						daten[3] + "\t" +
						daten[4] + "\t" +
						daten[5] + "\t"
					   );
			//SHOWS THE CSV CONTENT

			//SQL CONNECTION
			Connection conn = null;
			String treiber = "com.mysql.jdbc.Driver"; 
			String url = "jdbc:mysql://localhost:3306/csv_test"; 
			String userName = "root";
			String password = "root";
			//SQL CONNECTION

			//SQL STATEMENTS
			String SqlUpdate = "Update `stundenplan` SET Stunde = '"+daten[0]+"', Montag = '"+daten[1]+"', Dienstag = '"+daten[2]+"', Mittwoch = '"+daten[3]+"', Donnerstag = '"+daten[4]+"', Freitag = '"+daten[5]+"' WHERE Stunde = '"+daten[0]+"' ";
			String SqlSelect = "SELECT Stunde FROM `stundenplan` WHERE Stunde = '"+daten[0]+"' ";
			String SqlInsert = "INSERT INTO `stundenplan` (Stunde, Montag, Dienstag, Mittwoch, Donnerstag, Freitag) VALUES ('"+daten[0]+"', '"+daten[1]+"', '"+daten[2]+"', '"+daten[3]+"', '"+daten[4]+"', '"+daten[5]+"') ";
			//SQL STATEMENTS

			try 
			{ 
				Class.forName ( treiber ).newInstance (); 
				conn = DriverManager.getConnection (url, userName, password);
			}
			catch (Exception e) 
			{ 
				System.err.println ("Error connecting to server! "+e); 
			}
			
			try 
			{
				java.sql.Statement s = conn.createStatement();
				ResultSet result = s.executeQuery (SqlSelect);

				if(result.next())
				{
					if(result.getString("Stunde") == daten[0])
					{
						java.sql.Statement u = conn.createStatement();
						int r = u.executeUpdate (SqlUpdate);
					}	
				}
				else
				{
					i = conn.createStatement();
					int r2 = i.executeUpdate (SqlInsert);
				}
				s.close();
			}
			catch (Exception e) 
			{
				return ("Error writing to Database! "+e);
			}
			conn.close();
			//SQL CONNECTION
		    }
		    System.out.println("......... " + count + " entries proceded!");
		    return (SqlUpdate);
		    return (SqlInsert);
		    CSVFile.close();
		    Datei.close();
	    }
        }
        catch (IOException e) 
	{
           System.out.println("Error reading from file! \n" +
			      "Please check the filename (test.csv) and the path.");
	   //System.out.println(e.toString());
        }
```


----------



## Anime-Otaku (25. Juni 2007)

Das wird zwar wahrscheinlich nicht das Problem sein, aber ein möglicher Memory Leak hab ich schon gefunden. 
Das Schliesen der Verbindung und des Statements sollte in einen finally Block nach dem try catch, ansonsten kann es sein dass es nicht geschlossen wird und ich glaube je nachdem brauchst du in dem finally nochmals ein try catch.

Dann solle man Strings mit .equals oder equalsIgnoreCase vergleichen, bei == vergleicht man die Speicheradresse aber nicht den Inhalt.


----------



## Dark-Nemesis (25. Juni 2007)

Die Sachen hab ich geändert ... aber wie du vermutet hast bleibt das problem bestehen.


----------



## Dark-Nemesis (26. Juni 2007)

Nach einem neustart kommt dieser fehler nicht mehr, scheint nur zu kommen, wenn man das programm öfters compiliert und ausführt.

Jetzt kann ich auch sagen welche Fehlermeldung exakt ich bekomme, beim einstellen der seperatoren.

Could not find matching constructor for au.com.bytecode.opencsv.CSVReader(java.io.FileReader, java.lang.String)

Was damit jemand was anzufangen bzw. eine möglichkeit dies zu beheben?


----------



## Kulabac (26. Juni 2007)

Naja, jetzt ist es doch einfach. Such dir eine API ... zum Beispiel http://opencsv.sourceforge.net/api/index-all.html

und da steht dann:
CSVReader(Reader, char) - Constructor for class au.com.bytecode.opencsv.CSVReader 
Constructs CSVReader with supplied separator. 

Mit anderen Worten: Dein Separator muss ein Char sein, kein String! Gibt auch noch ein paar andere Construktoren, die man nehmen könnte...


----------



## Anime-Otaku (26. Juni 2007)

Ein char, also ein einzelnes Zeichen gibt man einfach durch ein einzelnes *';'* anstatt ";"


----------



## Dark-Nemesis (26. Juni 2007)

```
CSVReader Datei = new CSVReader(new FileReader("C:\\Documents and Settings\\Paul\\Desktop\\Script\\test.csv"), ';');
```
dann ist das doch eigentlich richtig wie ichs habe, aber der Fehler kommt dennoch.


----------



## Kulabac (26. Juni 2007)

In deinem Code oben benutzt du ja gar keinen Separator mehr ... aber definiert hast du 

```
String separator;
```

Wenn du den einsetzt kommt der Fehler. Da ist es egal aus wievielen Zeichen er besteht. String bleibt nunmal String. Änder das auf 

```
char separator;
```
und schon sollte es gehen.

Bzw. wenn du wie im vorherigen Post das direkt übergibst und es so nicht geht (ich versteh nicht warum), probier

```
CSVReader Datei = new CSVReader(new FileReader("C:\\Documents and Settings\\Paul\\Desktop\\Script\\test.csv"), (char) ';');
```
Der Cast ist zwar eigentlich völlig überflüssig ... aber wer weiß


----------



## Dark-Nemesis (26. Juni 2007)

Danke, das mit dem char separator hab ich bereits korriegiert nachdem ersten post von dir, und das eigentliche problem war tatsächlich damit zu lösen (char) ';'

seltsam aber ok ^^


----------

