# (Binary)Datei einlesen, Inhalt ändern, Datei schreiben



## Tillus (26. Mrz 2008)

Eigentlich eine recht einfache Sache, nur funktioniert es leider nicht so wie ich will:

Beispiel: Mein Programm (eine Art encoder/encrypter - decoder/decrypter) liest _irgendeine_ Datei ein, wird dann nach der Eingabe eines Passworts verschlüsselt und abgespeichert.
Lese ich jetzt diese Datei wieder ein, entschlüssele und speichere sie, erhalte ich eine Datei, die in den meisten Fällen unbrauchbar ist.
Mit Textdateien und ähnlichen funktioniert es wunderbar, nur bei allen anderen Dateien, die in irgendeiner weise "binär" sind, nicht.
Ich habe schon verschiedene Möglichkeiten ausprobiert, die Dateien zu schreiben bzw. zu lesen, z.B. (f ist die zu speichernde/lesende Datei):
Lesen (toncodestringbatch ist der String, in den die Datei gelesen werden soll):

```
FileReader fr = new FileReader(f);
 char[] cbuf = new char[(int)f.length()];
 fr.read(cbuf);
 toncodestringbatch = new String(cbuf);
```


```
FileInputStream fis = new FileInputStream(f);
 FileChannel fc = fis.getChannel();
 int sz = (int) fc.size();
 MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, sz);
 byte[] b = new byte[sz];
 bb.get(b);
 fc.close();
 toncodestringbatch = new String(b)
```


```
byte[] bytes = new byte[(int)f.length()];
 RandomAccessFile raf = new RandomAccessFile(f,"r");
 raf.readFully(bytes);                
 raf.close();
 toncodestringbatch = new String(bytes);
```

Speichern (tosave ist der zu speichernde String):

```
FileOutputStream fos = new FileOutputStream(f);
 int sz = ndcode.length();
 byte[] b = new byte[sz];
 b = tosave.getBytes();
 fos.write(b);
 fos.flush();
 fos.close();
```


```
RandomAccessFile raf = new RandomAccessFile(f,"rw");  
 raf.writeBytes(tosave);
 raf.close();
```

Danke schonmal im Voraus


----------



## Marco13 (26. Mrz 2008)

:shock: ein String ist kein byte-Array!
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html#String(byte[])
_
Constructs a new String by decoding the specified array of bytes using the platform's default charset. The length of the new String is a function of the charset, and hence may not be equal to the length of the byte array. The behavior of this constructor when the given bytes are not valid in the default charset is unspecified. 
_

Speicher' es konsequent als byte array, dann müßte es irgendwie gehen...


----------



## Tillus (26. Mrz 2008)

Ich habe jetzt nochmal verschiedene Sachen ausprobiert, jetzt les ich es mittels ByteInputStream ein, bzw schreibe es mit einem ByteOutputStream.
Das Problem ist jetzt, dass der nCoder auf char[] || String || StringBuffer Basis läuft. Also kann ich wahrscheinlich nicht einfach den String aus dem byte[] konstruieren (String a = new String(byte[] b), dann den String "verschlüsseln", nach dem Entschlüsseln "die Bytes des Strings" in eine Datei schreiben (byte[] c = a.getBytes(); fos.write(c))...

Wenn ich nämlich wie beschrieben die Datei einlese, verschlüssele und speichere, erhalte ich eine Datei von etwa der doppelten Größe der Ursprungsgröße. Öffne ich die Datei, entschlüssele sie und speichere sie, ist diese Datei genausogroß (bis auf ein paar bytes [ca. 6]) wie die verschlüsselte. (könnte ein bisschen verwirrend geklungen haben).

Was ich gerade mal getestet habe: Bei normalen Text/CSS/XML/etc. Dateien funktioniert es natürlich wunderbar...
Und: bei der RandomAccesFile Methode kommt immerhin auch nach dem Entschlüsseln&Speichern die gleiche Anzahl an Bytes raus (allerdings nicht die, die ich gerne hätte).

Wahrscheinlich sollte ich meinen Encoder noch mit Methoden für ByteArrays überladen.


----------



## quippy (27. Mrz 2008)

Java verwendet Unicode und wandelt daher ein byte bei konvertierung in ein Char in ein Unicode-Zeichen (2 Byte)

char!=byte!!

Diese Codierung funktioniert vielleicht noch eineindeutig für ASCII-Zeichen <128 - bei Sonderzeichen ist das vorbei.

Dein Verschlüsselungsalgorithmus muss also in der Tat mit ByteArrays umgehen lernen... Anders geht das nicht.


----------



## Tillus (27. Mrz 2008)

Stimmt ^^
So, mein Programm kann jetzt auch mit ByteArrays umgehen, das klappt wunderbar.
( wen es interessiert http://cg-privat.de/till/?p=34 )
Danke für eure Hilfe, sonst hätte ich wohl noch ewig weiterversucht, es irgendwie vernünftig abzuspeichern und zu laden


----------

