# Binärdateien mit "unbekanntem" Inhalt auslesen



## MJA (2. Okt 2005)

Hallo.

Ich möchte Binärdateien auslesen und den Inhalt als String Array zurückgeben lassen.
Zum Auslesen der Dateien verwende ich einen FileInputStream, der von einem DataInputStream ummantelt ist. Die Klasse DataInputStream bietet ja nun für alle primitiven Datentypen und für String Methoden zum Auslesen. Dies setzt aber vorraus, dass der Datentyp, des Inhaltes der aktuell gelesenen Zeile bekannt ist. In meine Fall weiß ich aber nicht, um welchen Datentypen es sich handelt (also es kann boolean, byte, char, short, int, float, long, double oder String sein). Wie kann ich die Daten also auslesen und sie hinterher in einen String konvertieren um sie dem Array hinzuzufügen? Wie kann ich vor dem Auslesen herrausfinden, wie groß der Ziel-Array sein muss?

Gruß,
Jan.


----------



## Bleiglanz (2. Okt 2005)

das ist unmöglich

wie billst du etwa die Folge 

byte-byte-byte-byte

von

int

unterscheiden? Wenn du nicht weisst was drin ist, dann geht das nicht (ein DataOubputStream speichert keine "MetaInformationen")

abgesehen davon, funktionert das Lesen eines Strings NUR dann, wenn da wirklich ein String reingeschrieben wurde?

was genau willstn machen?


----------



## byte (2. Okt 2005)

MJA hat gesagt.:
			
		

> Dies setzt aber vorraus, dass der Datentyp, des Inhaltes der aktuell gelesenen Zeile bekannt ist. In meine Fall weiß ich aber nicht, um welchen Datentypen es sich handelt (also es kann boolean, byte, char, short, int, float, long, double oder String sein).



es stehen ja keine "datentypen" in ner datei. die daten sind entweder binär oder als klartext in einem entsprechenden zeichensatz gespeichert. du kannst sie also entweder als bytes einlesen (erster fall) oder als strings (zweiter fall). ob der string nun wirklich ein string ist oder eine konkatenation aus string / int / float / etc, das prüfst du erst dann, wenn du die daten schon eingelesen hast, indem du sie geeignet interpretierst.

also du musst schon wissen ob sie binär oder als "klartext" vorliegen. dann kannst du mit geeigneten methoden einlesen. oder willst vorher durch java serialisierte daten (serializable) wieder einlesen? dann guck dir den ObjectInputStream an.


----------



## MJA (2. Okt 2005)

Also, alle diese Dateien werden mit dieser Methode geschrieben:


```
public static boolean writeFile(String fileName, String data[], boolean overwrite)
	{
		if(!isValidFileName(fileName))
			throw new IllegalArgumentException("fileName cannot be " + fileName);
		
		File file = new File(dataDirectoryPath +
				System.getProperty("file.separator") +
				fileName);
		
		try
		{
			if(!file.exists())
				file.createNewFile();
			else
				if(overwrite)
				{
					FileOutputStream fileOutputStream = new FileOutputStream(file);
					DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream);

					for(int i = 0; i < data.length; i++)
						dataOutputStream.writeUTF(data[i]);

					dataOutputStream.close();
					
					return true;
				}
			
			return false;
		}
		catch(Exception e)
		{
			return false;
		}
	}
```

Ich benutze diese Methode sowohl, um binäre Daten, wie z.B. Bilder zu speichern, wie auch für Einstellungen oder normale Textdaten. Ich weiß, dass man letzteres eigentlich viel einfacher als ASCII speichern könnte, aber ich bevorzuge binär, unter anderem auch, weil ich den Zugriff mit normalen Texteditoren nicht so leicht freigeben will.
Wenn ich die Binärdatei wieder auslese möchte ich genau den String Array zurückgeben, den ich geschrieben habe.


----------



## Bleiglanz (2. Okt 2005)

> also es kann boolean, byte, char, short, int, float, long, double oder String sein
> ...
> dataOutputStream.writeUTF(data_);
> _


_
das versteh wer will? du schreibst doch nur Strings raus, dann lies sie eben mit readUTF wieder ein...???_


----------



## MJA (2. Okt 2005)

Ja, tut mir leid, als ich den Thread gepostet habe, hatte ich für jeden angeführten Datentypen eine überladene Methode. Ich habe mich jetzt dagegen entschieden.
Was ich mich aber noch frage ist, wenn ich Daten mit writeUTF() schreibe, wird doch kein Zeilenumbruch angehängt, oder? Weiß readUTF() denn trotzdem, wo das Ende eines Strings ist?

Mein Hauptproblem jetzt besteht darin, wie ich herausfinden kann wie viele Strings in der Datei vorhanden sind. Ich will ja einen Array zurückgeben. Der soll natürlich nicht am Ende noch etliche leere Elemente beinhalten und eine ArrayIndexOutOfBoundsException wäre auch dumm. Muss ich mit einer for-Schleife erst einmal alles bis zum Ende durchgehen und dabei zählen oder geht das auch einfacher?


----------



## Bleiglanz (2. Okt 2005)

eventuell etwas langsamer, aber komfortabler:

Ein String[] ist serialisierbar, schreib und lies es einfach mit einem ObjectOutputstrem


----------



## MJA (2. Okt 2005)

Ich hab sowas noch nie gemacht, könntest du mir dafür einen kurzen Code schicken oder einen Link?


----------



## MJA (2. Okt 2005)

So, ich habe es jetzt auch mal selber probiert. Hier sind die beiden fertigen Methoden:


```
public static boolean writeFile(String fileName, String data[], boolean overwrite)
	{
		if(!isValidFileName(fileName))
			throw new IllegalArgumentException("fileName cannot be " + fileName);
		
		File file = new File(dataDirectoryPath +
				System.getProperty("file.separator") +
				fileName);
		
		try
		{
			if(!file.exists())
			{
				file.createNewFile();
				overwrite = true;
			}
			
			if(overwrite)
			{
				FileOutputStream fileOutputStream = new FileOutputStream(fileName);
				ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
				
				objectOutputStream.writeObject(data);
				objectOutputStream.close();
				
				return true;
			}
			
			return false;
		}
		catch(Exception e)
		{
			return false;
		}
	}
```


```
public static String[] readFile(String fileName)
	{
		try
		{
			FileInputStream fileInputStream = new FileInputStream(fileName);
			ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
			
			String data[] = (String[]) objectInputStream.readObject();
			
			objectInputStream.close();
			
			return data;
		}
		catch(Exception e)
		{
			return null;
		}
	}
```

Ich hoffe das funktioniert.

Danke!

Gruß,
Jan.


----------



## MJA (2. Okt 2005)

Also, es geht!

Vielen Dank!


----------

