# Struktur aus Datei lesen [C++] -> [Java]



## sisela (24. November 2004)

Hallo Leute,
beschäftige mich erst seit kurzem mit Java und habe nun folgendes Problem!

folgendes mache ich in C++.
	
	
	



```
file.Read(&Struktur, sizeof(Struktur));
```
 Und mit dieser einfachen Zeile habe ich mein komplette Struktur, bestehend aus mehreren int´s und char Arrays gelesen.

Das versuche ich nun auch in Java. Erstes Problem: Es gibt keine Strukturen! OK, man nehme eine Klasse und definiert dort alle Variablen. Nun kann ich aber nicht 
sizeof() machen zumal es das ja in Java nicht gibt.

Ich habe nun folgendes: 

```
JFileChooser fc = new JFileChooser();
fc.showOpenDialog(MyApp.this);
File file = fc.getSelectedFile();
try 
{
  FileInputStream in = new FileInputStream(file);
  MyStrukturClass struktur = new MyStrukturClass();
                  
  byte[] buf = new byte[4096];
  int len;
  while ((len = in.read(buf)) > 0) 
  {
    // hier was Struktur beschreiben
  }
  in.close();
}
catch (IOException ec) 
{
  System.err.println(ec.toString());
}
```

Wie bekomme ich jetzt am komfortabelsten meine Variablen der Strukturklasse beschrieben. Ich muss doch nicht etwa jedesmal, je nach Datentyp eine bestimmte Anzahl an Bytes lesen  

Vielleicht kann mir ja jemand von Euch einen Tipp geben (vielleicht mit Beispiel). Nehmen wir an ich will eine Struktur{int alter, char Info[30], usw.} auslesen.
mfg


----------



## Thomas Darimont (24. November 2004)

Hallo!

In Java muss man sich um solche Dinge (im Normalfall) nicht mehr kümmern, dafür gibts Serialisierung:

Beispiel:


```
package de.tutorials;

import java.io.Serializable;

class Struct implements Serializable {
	public int x;

	public int y;

	public char c;

	public boolean b = false;
}
```


```
package de.tutorials;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class Test06 {

	public static void main(String[] args) {
		new Test06().doIt();
	}

	private void doIt() {
		Struct s = new Struct();
		s.b = true;
		s.x = 2313;
		s.y = 34231414;
		s.c = 'A';
		
		try {
			ObjectOutputStream oos = new ObjectOutputStream(
					new FileOutputStream("c:/out.ser"));
			oos.writeObject(s);
			oos.flush();
			oos.close();

			Struct s0 = null;

			ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
					"c:/out.ser"));

			s0 = (Struct) ois.readObject();
			System.out.println(s0.b);
			System.out.println(s0.x);
			System.out.println(s0.y);
			System.out.println(s0.c);

			ois.close();

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

	}
}
```

Gruß Tom


----------



## sisela (25. November 2004)

Hi Tom,

man ist ja gar nicht mal so schlecht dieses Java, Steige gerade von C++ in die Java Programmiertechnik ein und habe mir den Umstieg leichter vorgestellt.

Auf jeden Fall danke nochmal, denn das macht die Sache doch wesentlich einfacher.

 Gruß Christian


----------



## sisela (25. November 2004)

Hallo Tom,

ich glaube ich habe mich zu früh gefreut! Kann es sein, dass ich nur so lesen kann, wenn ich es auch mittels eines Streams geschrieben habe? Denn ich habe die Datei, fertig dazuliegen (wird von einem anderen System geliefert) und schreibe daher nicht mit 
	
	
	



```
ObjectOutputStream oos = new ObjectOutputStream(
  new FileOutputStream("c:/out.ser"));
  oos.writeObject(s);
  oos.flush();
  oos.close();
```
Denn nun bekomme ich nämlich beim lesen aus der vorhandenen Datei eine Exception "invalid stream header". Kannst du dir das erklären und hättest du einen anderen Vorschlag?

Hier mein Code:

```
if (e.getActionCommand() == "File open")
            {
                JFileChooser fc = new JFileChooser();
                fc.showOpenDialog(MyApp.this);
                File file = fc.getSelectedFile();
                try 
                {
                    ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
                    init = (InitStruct) ois.readObject();
                    
                    System.out.println("Info: "+ init.lpszInfo.toString());
                    System.out.println("Flags: "+init.flags);
                    System.out.println("AppType: "+init.nAppTyp);
                    System.out.println("ProtoType: "+init.nPrototyp);
                    System.out.println("Size: "+init.nSize);
                    System.out.println("Version: "+init.nVersion);
                    
                    ois.close();
                
                } 
                catch (FileNotFoundException event) 
                {
                    event.printStackTrace();
        	} 
                catch (IOException event) 
                {
                    event.printStackTrace();
        	} 
                catch (ClassNotFoundException event) 
                {
                    event.printStackTrace();
        	}
            
            }
```


```
class InitStruct implements Serializable
{
    public long 	nSize;
    public int 	nVersion;
    public int 	nPrototyp;
    public int 	nAppTyp;
    public char 	lpszInfo[];
    public long 	flags;
}
```
Gruß Christian


----------



## Snape (25. November 2004)

sisela hat gesagt.:
			
		

> Hi Tom,
> man ist ja gar nicht mal so schlecht dieses Java, Steige gerade von C++ in die Java Programmiertechnik ein und habe mir den Umstieg leichter vorgestellt.
> 
> Gruß Christian



Java ist wesentlich einfacher als C++. Ich habe erst Java gelernt und wenn ich mich nun mit C++ beschäftigen muss, kriege ich die Krise, wie kompliziert und umständlich alles in der C++ Welt ist. Von der API ganz zu schweigen...
3 Tips:
1. Schau in die Sun Tutorials
2. Schau in die API
3. Verschiedene Bücher zum Nachschlagen gibt es auch als Online-Versionen, z.B. die Java-Insel oder Handbuch der Java-Programmierung

Zu Deiner Datei: Nimm mal einen BufferedReader und/oder 1-3.


----------



## sisela (25. November 2004)

Hi @snape!

Danke erst einmal. Sag mal gibt es in Java denn nichts wie sizeof()? Denn wenn ich den BufferedReader nehme, muss ich ja immer angeben wieviele Bytes ich lesen will. Wenn sich nun aber meine Datenstruktur ändert, möchte ich ja nicht die tausend stellen im Programm ändern. In C gibt es sowas wie sizeof(variable) und dann würde ich bei einem WORD variable halt ein WORD lesen und bei DWORD variable ein DWORD.
Ich hoffe du verstehst was ich meine, ich will halt nicht sowas wie
	
	
	



```
raFile.read(byte[]b, raFile.getFilePointer(), 8);
```
 Die 8 muss halt irgendwie weg

mfg


----------



## Snape (25. November 2004)

Du musst die Größe nicht wissen. Schau mal z.B. hier:


```
public static void main(String[] args)
	{
		try
		{
			FileReader fr = new FileReader("C:/boot.ini");
			BufferedReader br = new BufferedReader(fr);
			String line = null;
			Vector vector = new Vector();

			//So lange Zeilen aus der Datei einlesen bis
			//End Of File (EOF) --> br.readLine() => null 
			//gelesene Zeilen in den Vector schieben
			while ((line = br.readLine()) != null)
			{
				vector.add(line);
			}

			//Anzahl der Elemente im Vector
			int size = vector.size();
			//Zeilen ausgeben
			for (int i = 0; i < size; i++)
			{
				System.out.println(vector.get(i));
			}

		}
		catch (FileNotFoundException e)
		{
			e.printStackTrace();
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}
```


----------



## sisela (25. November 2004)

Sicherlich wäre es möglich die ganze Datei einzulesen aber genau das will ich nicht, denn die ist riesig. In meiner Datei stehen lauter Strukturen (leider kein Java Stream). Also sagen wir mal meine erste Variable der Struktur ist ein Integer. Nun möchte ich nur  diese Variable also sizeof(int) gerne auslesen, was genau 4Bytes entsprechen müsste. Also es bringt mir nichts die komplette Datei einzulesen, noch mit Streams aus der Datei heraus lesen, weil die Daten nicht mittels Java Streams reingeschrieben werden.

Wie gesagt in C ist das eine Zeile:
	
	
	



```
file.Read(&var, sizeof(var));
```

Im Moment versuche ich mich an der RandomAccessFile und lese halt immer genau die Größe eines bestimmten Datentyps. 
	
	
	



```
init.nVersion = raFile.readShort();
```

Aber der Code wird dann so lang, das muss doch einfacher gehen, da ich ja jeden einzelnen Datentyp extra einlesen muss.

mfg


----------



## Thomas Darimont (25. November 2004)

Hallo!

Die Serialisierung in Java macht noch ein wneig mehr als nur die Werte der jeweiligen Membervariablen (die sich Externalisieren lassen) ein einen Stream und dann auf die Platte zu hauen. Zusätzlich werden nämlich noch einige Verwaltungsinformationen zu der Klasse und den darin enthaltenen Daten abgelegt. Wie etwa Klassenname, Variablentyp etc. Deshalb kannst du mit dem Serialisierungsmechanismus nur schwer Daten die aus anderen nicht Java Anwendungen heraus erstellt wurden lesen (Du müsstest eben diese zusätzlichen Verwaltungsinformationen noch hinzufügen und so gestallten, dass Java was damit anfangen kann, was eigentlich so gut wie unmöglich ...oder sagen wir mal schwer möglich ist.)

Btw. lerne ich auch gerade C++ und muss sagen, dass mir meine Java Erfahrung dort extrem Hilft. Java hat nun mal sehr viele Konzepte von C++ übernommen /bzw. ähnlich realisiert was einem den Einstieg IMHO recht einfach macht.

Gruß Tom


----------



## Snape (25. November 2004)

Thomas Darimont hat gesagt.:
			
		

> Hallo!
> Btw. lerne ich auch gerade C++ und muss sagen, dass mir meine Java Erfahrung dort extrem Hilft. Java hat nun mal sehr viele Konzepte von C++ übernommen /bzw. ähnlich realisiert was einem den Einstieg IMHO recht einfach macht.
> Gruß Tom



Dann bin ich entweder zu alt, zu doof oder mir fehlt einfach ein (guter) Tutor. Der ganze Krempel mit * und & will einfach nicht in meinen Kopf, wann und warum die zu benutzen sind.
Dazu geben mir die schlechte API und die kryptische Syntax den Rest.


----------



## sisela (25. November 2004)

@Thomas
Ja, das mit den Zusatzinformationen habe ich schon mitbekommen, als ich mir die Datei dann mal angeschaut habe. Sprich Serialisierung kommt für mich nicht in Frage.
@snape
Also deine lieblige * und & sind wenn man sie erst einmal schätzen gelernt hat, sehr nette Wegbegleiter und machen so manches möglich   .

PS
- und zu doof bist du bestimmt nicht...  
- und API und Syntax sind gewöhnungsbedürftig (ich gebe es zu) aber es ist nicht unmöglich sie zu verstehen...

mfg


----------



## Snape (25. November 2004)

sisela hat gesagt.:
			
		

> @snape
> Also deine lieblige * und & sind wenn man sie erst einmal schätzen gelernt hat, sehr nette Wegbegleiter und machen so manches möglich   .



Ja, ich habe ja schon mitbekommen, dass man damit ab und an nette Sachen machen kann. Aber wie gesagt, das ist mir noch nicht in Fleisch und Blut übergegangen. Und fehlerträchtig sind sie wohl auch, es heißt rund 70% der C++ Fehler sind Zeiger/Pointer-Fehler...



> PS
> - und zu doof bist du bestimmt nicht...



Zumindest für C++ habe ich den Eindruck...



> - und API und Syntax sind gewöhnungsbedürftig (ich gebe es zu) aber es ist nicht unmöglich sie zu verstehen...
> 
> mfg



Unmöglich vielleicht nicht, aber vergiss nicht, ich bin Java ge- und verwöhnt.


----------



## sisela (25. November 2004)

@snape:
mit 70% magst du recht haben...


----------



## torsch2711 (25. November 2004)

Lol Snape,

da fang erst gar nicht mit C an, das wird noch komplexer 

War n scherz, ist aber richtig, hab in meinem Studium zwischendurch mal C gecodet und danach nur noch Java. Jetzt bin ich wieder in ein C Projekt involviert und muss sagen, dass ich dort in das ein oder andere Fettnäpfchen trete....

Naja, dem C++ Coder hier geht es genauso mit C. Ist halt dort alles umständlicher.

Egal.

Viel Spass noch mit Java, ist ein sehr gutes Konzept meiner Meinung nach.

Grüsse

Torsten


----------

