# Datei einlesen und splitten nur zeilenweise



## auxilium (25. Feb 2008)

hallo , 

ich habe eine Date mit folgendem Inhalt:

Hans,Manuel,Josef,Marco
Carsten,Daniel,Manuel,Marco

und möchte jeweils die Daten aus einer Zeile in ein Array, hier in dem Fall hätte ich also 2 Arrays.

Habe das aber nur mit einem Array hinbekommen :-( und leider weiß ich auch nicht, wie viele Elemente ins Array sollen 



```
import java.io.FileReader;
import java.io.IOException;

public class FileRead {

	/**
	 * @param args
	 * @throws IOException
	 */
		public static void main(String[] args) throws IOException {

		FileReader reader;

		// Read file
		reader = new FileReader("replace.txt");
		int zeichen;
		String ausgabe = "";
		while ((zeichen = reader.read()) != -1) {

			ausgabe += "" + (char) zeichen;
		}
		String[] test = ausgabe.split("/n");
		System.out.println(ausgabe);

		String[] werte;
		String [] werte2 = new String[20];
		int i3 = 0;

		int i = 0;
		while (i <= test.length - 1) {

			werte = test[i].split(",");
			int i2 = 0;
			while (i2 <= werte.length - 1) {
				werte2[i3]=werte[i2];
				i3++;
				i2++;
			}
		
			i++;

		}
		i = 0;
		while (i<werte2.length){
			System.out.println(werte2[i]);
			i++;
			
		}

	}

}
```


----------



## SlaterB (25. Feb 2008)

der Zeilenumbruch ist \n, nicht /n

mit einem BufferedReader und readLine() bekommst du die Zeilen frei Haus zeilenweise geliefert, 
jeden Buchstaben einzeln zu lesen ist unnötig aufwendig und auch langsam(er)

wenn du ein ein Array splittest, dann hast du String[] werte = ..;

dieses Array kannst du nun in ein anderes schreiben:
String[][] alleZeilen = ..;
alleZeilen[3] = werte;

> und leider weiß ich auch nicht, wie viele Elemente ins Array sollen 

verwende zunächst eine dynamische Datenstruktur wie eine ArrayList,
da passen beliebig viele rein, 
am Ende weißt du wieviele es sind und kannst sie in ein passend großes Array umschaufeln
(oder die fertige toArray()-Operation verwenden)


----------



## Wildcard (25. Feb 2008)

ArrayList würde ich nicht empfehlen, da je nach länge der Datei sehr oft das Array umkopiert werden muss. Das brauchst Speicher und ist langsam. Besser eine LinkedList, oder (wenn die Reihenfolge egal ist und keine Duplikate vorhanden sind) ein HashSet.


----------



## auxilium (25. Feb 2008)

```
FileReader reader;
		ArrayList<String> zeilen = new ArrayList<String>();
		ArrayList<String>ausgabe = new ArrayList<String>();
		
	LineNumberReader test = new LineNumberReader(new FileReader("replace.txt"));
		String lesen;
	while ((lesen = test.readLine())!=null){
		zeilen.add(lesen);
	}
int i = 0;	
while(i<zeilen.size()){
	System.out.println(zeilen.get(i));
ARRAY MIT BESTIMMTEM WERT =	zeilen.get(i).split(",");

	i++;
}
```

also habs mit dem LineNumberReader versucht der ist klasse.

Beim splitten habe ich allerdings ein problem, weil ich nicht weiß,  in wie viele Teile das aufgesplittet wird.

Aber ich muss daas Array entsprechend festlegen.

eine SPlit Methode für eine Arraylist gibt es nicht, da hätte ich das problem nicht?


----------



## SlaterB (25. Feb 2008)

nein, du musst das Array nicht vorher initialisieren,

String[] werte = zeilen.get(i).split(","); 
dann ist werte ein neues Array genau der richtigen Größe, das macht split()

> eine SPlit Methode für eine Arraylist gibt es nicht, da hätte ich das problem nicht?

die Liste ist nur zum Sammeln der werte-Array pro Zeile,
da musst du nix splitten?

---------



Offtopic @Wildcard:
hmm, eine kühne Behauptung, gleich mal testen,

zumindest das HashSet, also eine HashMap, hat doch genauso wie die ArrayList eine initiale Größe von 16, die dann ständig verdoppelt wird? 

bleibt noch die Frage der LinkedList,
was stören da die paar Verdopplungen? gerademal 20 Verdopplungen bei einer Mio. Elementen, warum soll das was ausmachen?
dagegen für LinkedList 1 Mio. Hilfsobjekte erzeugen..

was meinst du mit 'je nach länge der Datei'? ich denke mal bei höherer Länge liegt die ArrayList besser, da die Anzahl der Verdopplungen abnimmt


```
public class Test
{
    static int k = 1000;

    public static void main(String[] args)
        throws Exception
    {
        String[] items = new String[10000];
        for (int i = 0; i < items.length; i++)
        {
            items[i] = "" + i;
        }
        buildUpArrayList(items);
        buildUpLinkedList(items);
        buildUpArrayList(items);
        buildUpLinkedList(items);
        buildUpArrayList(items);
        buildUpLinkedList(items);

    }

    public static void buildUpArrayList(String[] items)
    {
        long time = System.currentTimeMillis();
        for (int i = 0; i < k; i++)
        {
            List l = new ArrayList();
            for (String st : items)
            {
                l.add(st);
            }
        }
        System.out.println("time AL: " + (System.currentTimeMillis() - time));
    }

    public static void buildUpLinkedList(String[] items)
    {
        long time = System.currentTimeMillis();
        for (int i = 0; i < k; i++)
        {
            List l = new LinkedList();
            for (String st : items)
            {
                l.add(st);
            }
        }
        System.out.println("time LL: " + (System.currentTimeMillis() - time));
    }
}


--------

time AL: 469
time LL: 2156
time AL: 454
time LL: 2078
time AL: 468
time LL: 2110
```

bei 100 Elementen kann LinkedList noch mithalten, bei 10000 dann eher weniger,

der Platzvorteil bleibt natürlich optisch ungenommen, 
allerdings nur, wenn die zusätzlichen LinkedList-Entry-Objekte nicht die schmalen 4 Byte im Array übertreffen

bei

```
private static class Entry<E> {
	E element;
	Entry<E> next;
	Entry<E> previous;
}
```
siehts da wohl auch düster aus für LinkedList, aber habe ich mal nicht getestet


----------



## zilti (25. Feb 2008)

Der Zeilenumbruch ist nicht /n, nicht \n sondern System.getProperty("line.separator"); .


----------



## Wildcard (25. Feb 2008)

@SlaterB
Worum es mir eigentlich geht ist, dass IMO zu oft die ArrayList vorgeschlagen wird. Jede Collection hat ihre eigenen Vor- und Nachteile. Ich verwende die ArrayList beispielsweise kaum.
Bei wahlfreiem Zugriff nehme ich wo immer möglich ein HashSet, weil die Zugriffszeiten besser sind.
Bei sequentiellem Zugriff, oder wahlfreiem einfügen/entfernen nehme ich die LinkedList.
Die ArrayList ist die Notlösung, wenn nichts anderes passt, seltsamerweise wird sie hier bei praktisch jedem Problem vorgeschlagen.  ???:L


----------



## SlaterB (26. Feb 2008)

das liegt nunmal daran, dass ArrayList eben nicht eine Notlösung ist, 
sondern das Beste, was man sich wünschen kann, wenn man eigentlich ein Array braucht 

siehe meine Tests/ Erläuterungen,
wenn du Argumente dagegen hast, dann kannst du sie ja nennen,

LinkedList ist nur gut bei ständigen Einfügen/ Entfernen, was ich praktisch noch nie gebraucht habe,
ArrayList dagegen 10x am Tag..

eine Menge von Elementen ohne vorher die Anzahl zu kennen, sogar noch mit Reihenfolge und schnellstmöglichen Index-Zugriff,
schlicht, gut, perfekt

Set und Map kommen eh nicht in Frage, haben Sonderaufgaben (Doppelte, Key-Zugriff) 
und damit für normale Zwecke unnötigen Overhead/ Speicheraufwand/ Verlangsamung

edit: falls Umfragen/ Anwendungen noch überzeugen:
Hibernate liefert bei Anfragen ArrayLists zurück 

edit2: und immerhin gabs ja früher nur Vector, also ArrayList, und LinkedList noch gar nicht,
alles spricht für ArrayList, wie kann man was anderes vermuten?

edit3:
ach halt, beim sequentiellen Durchlauf ist die LinkedList schneller,
ich meine, das wurde schon mal in einem Thread hier besprochen,

ja das ist dann ein gutes Argument, wenn man eine Liste öfters durchläuft, dann kann LinkedList auftrumpfen


----------

