# Datei binär auslesen und speichern



## NRFi (9. März 2004)

Hallo auch,
wie krieg ichs in C++ hin, eine Datei zu öffnen, binär zu lesen und als byte()-array wieder binär zu speichern, so dass sie nach dem speichern(zb als neue datei(jpg)) wieder anzugucken ist?

hat jemand dazu ein beispiel? 

wäre nett.

gibt es da auch sowas schnelles wie buffered-stream oder irgendwie sowas? soll schnell sein und dem standard entsprechen.


danke für die hilfe 


gruß, NRFilein :-(


----------



## Daniel Toplak (10. März 2004)

Das hängt davon ab was du machen willst.
Die guten alten C-Funktionen sind da ziemlich gut (sind auch schnell)

fopen()
fread()
fwrite()
fclose()
Erklärung siehe MSDN oder Man-Pages, je nach Betriebssystem.

Wenn du allerdings die Daten änderst und danach soll die Datei lesbar sein (JPG z.b.) musst du genau wissen was du tust. Wenn du allerdings Dateien kopieren willst, dann empfehle ich dir das ganze blockweise zu machen (z.B. immer 64K-Blöcke).

Gruß Homer


----------



## NRFi (10. März 2004)

das mit den blöcken usw ist mir schon klar.
bis jetzt hab ich sowas aber noch nicht mit c++ gemacht und ich möchte für C++
gerne ein kleines beispiel, wie ich dateien vernünftig BINÄR einlesen kann..

danke


----------



## Kachelator (10. März 2004)

> bis jetzt hab ich sowas aber noch nicht mit c++ gemacht und ich möchte für C++ gerne ein kleines beispiel, wie ich dateien vernünftig BINÄR einlesen kann..


 fread() usw. funktionieren auch in C++ immer noch. Wenn du es allerdings richtig mit C++ machen willst, benutz ostream (schreiben) bzw. istream (lesen) - für den Dateizugriff entsprechend ofstream und ifstream. Die beiden Ein/Ausgabe-Streamklassen eignen sich mittels der Extraktions/Insertions-Operatoren << und >> zum formatierten (nicht-binären) Lesen und Schreiben. Wenn du es binär haben willst, kannt du die Methoden get()/read() bzw. put()/write() verwenden. Such mal in deiner Dokumentation nach basic_ostream bzw. basic_istream. Ein Beispiel ist wahrscheinlich dabei.


----------



## NRFi (10. März 2004)

ok, in dem fall wird wahrscheinlich auch fopen und fread reichen.
habe jetzt 

#include "stdafx.h"

#include <iostream.h>
#include <stdio.h>
#include <io.h>
#include <string.h>

void main()
{
	FILE *oFile;
	char *buffer;
	unsigned long lFileLen = 0;

	oFile = fopen("C:\\Adrian.jpg", "r+b");
	lFileLen = filelength(oFile->_file);

	buffer = new char[lFileLen];
	//cout << lFileLen;
	fread(buffer, 1, lFileLen, oFile);

	cout << buffer;
	fclose(oFile);
}

eine textdatei liest er schon aus, aber er kriegt zb. die jpg datei nicht ausgelesen. da gibt er nur ein paar byte aus. was ist da los


----------



## Kachelator (10. März 2004)

Ich verstehe deine Frage nicht. 

Jedenfalls produzierst du ein Memory-Leck, weil buffer nicht freigegeben wird. Und basic_iostreams sollen man nicht direkt instantiieren. Du brauchst für den Dateizugriff entweder std::ifstream oder std:fstream(#include <fstream>)  - allerdings wird dein Stream test ja nicht benutzt.


----------



## NRFi (10. März 2004)

jetzt versteh ich dich nicht...

bitte sag mir einfach nur, wie ich mit fopen und fread ein schönes array binär bekomme


----------



## Kachelator (10. März 2004)

Sieht eigentlich gut aus. Aber es macht doch keinen Sinn, Binärdaten als Chars ausgeben zu wollen. Wahrscheinlich ist folgende Ausgabe schonmal nicht richtig:  _cout << buffer;_. wenn nämlich der erste "char" im Array 0 ist (was ja bei Binärdaten vollig normal wäre),  bekommst du gar keine Ausgabe.


----------



## Sponko (11. März 2004)

Hallo erst einmal zusammen. 

Ich bin Fachinformatiker/Systemintegration in Ausbildung (2.Lehrjahr).

Bezüglich meiner Abschlussarbeit habe ich mir folgendes Thema ausgewählt, welches in diesen Kontext hier passen könnte...


Ich möchte Dateien (egal ob jpg,mpg, mp3, wav,usw.) blockweise binär auslesen, wobei jede "1" als "."(Punkt),  jede "0" als Leerzeichen und das Blockende als "| " definiert ist.
Diese Darstellungsform der binär ausgelesenen Datei wird dann in Word oder ein anderes Programm implementiert und ausgedruckt.

Analog dazu möchte ich dann die ausgedruckte Form der Datei über einen Scanner einlesen, über die Software laufen lassen und wieder in den ursprünglichen Zustand konvertieren lassen.


Ich hoffe, ich habe mich nicht zu verwirrend ausgedrückt.

kann mir jemand einen Anhaltspunkt geben,da ch in Sachen Programmierung nicht der fitteste bin, jedoch motiviert, das durchzuziehen, sofern es realisierbar ist....


----------



## Kachelator (11. März 2004)

Es wäre vielleicht gut, dazu einen neuen Thread mit passendem Titel anzulegen, aber für's Erste: 





> Ich möchte Dateien (egal ob jpg,mpg, mp3, wav,usw.) blockweise binär auslesen, wobei jede "1" als "."(Punkt), jede "0" als Leerzeichen und das Blockende als "| " definiert ist.


Meinst du mit "0" und "1" in der Datei (nicht) gesetzte Bits? Was wäre dann das Blockende? 

Es sollte möglich sein, so ein Projekt zu verwirklichen, aber nur unter der Voraussetzung, dass du prammiersprachlich einigermassen fit bist, da noch genug andere Probleme auf dich zukommen werden als die reine Kenntnis der Sprache. Beispielsweise die Einbindung in Word, es sei denn, du hast vor, eine Textdatei auszugeben, und diese mit Word zu öffnen. Oder die Verarbeitung der eingescannten Grafik, um das Bitmuster wiederherzustellen.


----------



## Sponko (11. März 2004)

Ja. ich möchte die ergebnisse in einer Textdatei ausgeben, die dann ausgedruckt wird. 
ich denke bis hierher dürfte es nicht allzu schwer sein, da ich schon eine änliche lösung unter basic entdeckt habe.

Problematischer dürfte es dann bei der Rückkonvertierung werden.
Wie erkennt das Interface, dass der wulscht aus einsen und nullen eine jpg oder mp3 ist?


ps: wie könnte ich den thread denn nennen? 

"Archivierung von Dateien in binärer Form"   ?


----------



## Kachelator (11. März 2004)

> Problematischer dürfte es dann bei der Rückkonvertierung werden.
> Wie erkennt das Interface, dass der wulscht aus einsen und nullen eine jpg oder mp3 ist?


  Wenn dein Programm das Scannen selbst erledigt, erübrigt sich das Problem. Wenn es mit einem Grafikprogramm gemacht wird und gespeichert (Photoshop), hast du eine Bilddatei vor dir, die die ursprüngliche Bilddatei als "unscharfes" Pixelmuster (Punkte und Spaces) beeinhaltet. Diese Bilddatei (ob JPG oder BMP) müsstest du dann wieder öffnen und pixelweise untersuchen, um das ursprüngliche Bitmuster aus dem ersten Schritt wiederherzustellen.

Hm, hm, hm, ich glaube, ich verstehe nicht ganz, was du vorhast - willst du im ersten Schritt bereits Grafikdateien binär einlesen?


----------



## Sponko (11. März 2004)

1. Datei wird binär ausgelesen
2. Binär ausgelesene Datei wird als Textdatei ausgegeben und ausgedruckt

sodass das DinA4 Blatt ungefär so aussehen sollte:

.. . ...|  .. ....|........|.   . ..|..  . ..|.... . .|..  ..  |. . . ..|........|.. .... |
........|........|.. .. ..|.. ....|....... |........|.... ...|

 "." =1   Leerzeichen=0    |=Byte ende 

3. Das vollgedruckte DinA4 blatt wird dann mit einem Scanner einscannt

4. nun muss ja die Erstellte Bilddatei entweder direkt in ursprungszustand konvertiert werden, oder erst einmal in Textdatei mittels eines Finereaders
und dann zurück in Ursprungsform

ps. darf ich dich auch per icq kontaktieren?


----------



## Kachelator (11. März 2004)

Okay, jetzt verstehe ich besser, was du vorhast. Dann lässt sich das Projekt ja schonmal in die verschiedenen Schritte aufteilen.

1. Binär->Textdatei (deine Anwendung)
Liest eine Binärdatei und gibt sie als Textdatei aus.

2. Textdatei->Ausdruck.
Mit Textverarbeitung Textdatei öffnen und ausdrucken.

Jetzt entweder
3. Ausdruck->Bilddatei 
Mit Grafikprogramm wird als Grafik gescannt und als Grafikdatei gespeichert
oder
3. Ausdruck->Textdatei  (einfacher)
Mit Hilfe irgendeiner Texterkennungssoftware (meist bei Scannern dabei) 

Wenn du das Ganze als Grafik einscannst, musst du die Grafikdatei natürlich noch selber pixelmässig analysieren.


----------



## Sponko (11. März 2004)

zu 3.

stimmt ja, ich kann ja angeben in welcher form das zu scannende Medium ausgegeben werden soll. ich sag dann einfach als Textdatei-> kann nun direkt zurückkonvertieren.


Schön, dass wenigstens einer checkt, was ich vorhabe 

da ich kein anwendungsentwickler bin und ich lediglich diese idee hatte, bräuchte ich ein paar eckpfeiler, welche ich bei der drchführung des projektes berücksichtigen muss.

ich möchte ja nicht, dass mir hier irgendwelchen leute im forum das interface programmieren und ich präsentiere es dann der ihk.

ich bräuchte ledigl. ein paar infos, ein paar hints auf die ich achten muss.

vor allem zu Schritt 3.


----------



## Kachelator (11. März 2004)

Ja, wenn du Texterkennungssoftware benutzt.


----------



## Sponko (11. März 2004)

Schön, dass wenigstens einer checkt, was ich vorhabe 

da ich kein anwendungsentwickler bin und ich lediglich diese idee hatte, bräuchte ich ein paar eckpfeiler, welche ich bei der drchführung des projektes berücksichtigen muss.

ich möchte ja nicht, dass mir hier irgendwelchen leute im forum das interface programmieren und ich präsentiere es dann der ihk.

ich bräuchte ledigl. ein paar infos, ein paar hints auf die ich achten muss.

vor allem zu Schritt 3.


----------



## Kachelator (11. März 2004)

Setzt dich hin und überlege genau, was deiner meiner nach für Verarbeitungsschritte nötig sind für deine Daten. So öhnlich, wie ich das angefangen habe, aber ausführlicher. Überlege dir, ob das alles ein einziges Programm macht, oder mehrere. Überlege, welche Grafik/Scannersoftware du verwenden wirst. Schreib das Ganze auf und stell es hier im Forum vor, mit der Bitte um Rat. Dazu solltest du schon einige konkrete Fragen stellen können. Poste diese auch mit.

Threadtitel: "[Projekt] Binärdateien als "Balkencode" codieren und wieder einlesen"   oder so?


----------



## Sponko (11. März 2004)

ok. danke ersteinmal für deine geduld.
jetzt weiss ich zumindest, dass ein solches projekt sich grundsätzlich mit c++ realisieren lässt. und das ist schon mal ein anfang für mich.
denn wenn sich die ganze sache realsieren lässt könnte ich je nach qualität der tinte und der tatsächlichen Leistung des Druckers und scanners ja einige MB pro Blatt abspeichern...

Danke


Ich melde mich dann (jedoch mach ich dann einen neuen thread auf)


----------



## Kachelator (11. März 2004)

> denn wenn sich die ganze sache realsieren lässt könnte ich je nach qualität der tinte und der tatsächlichen Leistung des Druckers und scanners ja einige MB pro Blatt abspeichern...


 Auf eine Diskette passen auch ungefähr 1,44 MB drauf... 
Übrigens gibt es sicherlich fertige Libs, mit denen man Balkencode lesen und schreiben kann.

Der folgende Link sollte für dich auch interessant sein: http://www.paperdisk.com/


----------



## Sponko (11. März 2004)

Hey
genau das hab ich ja vor! genauso hab ich mir mein Projekt vorgestellt.


du hast recht! auf eine diskette passen auch 1,44 MB jedoch sind disketten keine permanenten Datenträger. Lässt man disketten ne weile liegen und möchte dann irgendwann an die daten ran, sind die disketten meist defekt und bringen datenfehler.
Papier ist geduldig. Es ist eine alternative zur konventionellen datensicherung/archivierung


----------



## Kachelator (11. März 2004)

Ja, das macht  schon Sinn. Je nachdem, wie gross die Zeiträume sind, über die Datensicherheit gewährleistet werden muss.


----------



## Daniel Toplak (13. März 2004)

Ich möchte mich ja jetzt nich einmischen in dein Projekt, aber du schreibst du lernst Systemintegration, wenn ich mich nicht irre, ist das ein wenig vorbei an Systemintegration.
Sicher die sollten auch etwas mit Programmierung zu tun haben (Scripte usw...) aber dein Projekt wäre wenn dann nur was für einen Anwendungsentwickler.
Außerdem hast du da massive zeitliche Probleme, denn so weit ich das weiß hat ein Anwendungs entwickler 70 Stunden und ein Systemintegrator nur 35 Stunden Zeit für die Projektarbeit.
In dieser Zeit sollst du aber dein Projekt nicht nur runtertippen, sondern auch die Planung, Dokumentation und Präsentation machen.
Somit wäre das für einen Prüfer, der halbwegs was versteht sehr unglaubwürdig, ich würde behaupten das, das sogar für einen Anwendungsentwickler unglaubwürdig wäre.
Also ich will dir dein Projekt nicht schlechtreden im gegenteil, ich finde es eine klasse Idee, aber sei vorsichtig, daß du dich da in nix verrennts, sonst wirst du das bitter bereuen, denn weniger ist oft mehr.

Denk mal darüber nach.

Gruß Homer


----------



## NRFi (16. März 2004)

Noch ne Frage, wie kann ich denn ne Datei mit "rb" in sagen wir mal 64k blöcken auslesen?


----------



## Kachelator (16. März 2004)

_size_t fread( void *buffer, size_t size, size_t count, FILE *stream );_ 
Der dritte Parameter gibt die Anzahl der einzulesenden Objekte ein - das könnten zum Beispiel auch 64K sein, wenn du byteweise einliest (zweiter Parameter = 1).


----------



## NRFi (16. März 2004)

size_t fread( void *buffer, size_t size, size_t count, FILE *stream ); 

d.h.:

buffer = die 64k zurückgegebenen daten
size = ?
count = anzahl zu lesene bytes?

komme da leicht durcheinander.
in c# hab ich das mit dem filestream so gemacht:

(in etwa)

read(buffer, pos, anzahl)

dh. von wo gelesen werden soll und wieviel.

aber bei fread komm ich da leicht durcheinander


----------



## Kachelator (16. März 2004)

Size ist die Grösse in Byte. Wenn du Bytes lesen willst, mach da 1 hin. Wenn du 15 Foo-Objekte einlesen willst, sieht es ungefähr so aus:

```
size_t geleseneFoos = fread( meinBuffer, sizeof( Foo ), 15, meinFile );
```


----------



## NRFi (16. März 2004)

achso, ok, danke.
und was ist jetzt, wenn ich in 64 k-blöcken lesen will, die datei aber 128 k groß ist?
dann lese ich die ersten 64 k und dann muss ich dem ja sagen, dass im nächsten schritt die nächsten 64 k dran sind.
mit fseek?

und das wäre dann schneller, als alles auf einmal auszulesen ohne in blöcken?
wieso?


----------



## Kachelator (16. März 2004)

> dann lese ich die ersten 64 k und dann muss ich dem ja sagen, dass im nächsten schritt die nächsten 64 k dran sind.
> mit fseek?


  Du brauchst kein fseek - der Filepointer ist dann schon automatisch durch das fread um 64KB weitergesetzt.



> und das wäre dann schneller, als alles auf einmal auszulesen ohne in blöcken?


Hm. Da kann man vermutlich keine allgemeingültige Antwort geben. Es hängt auch davon ab, wie die Daten verarbeitet werden sollen. Übrigens war das doch deine Idee mit den 64KB-Blöcken. Hast du da nicht was bei gedacht?


----------



## Sponko (29. März 2004)

Ja ich weiss, dass es eher ein Thema für anwendungsentwickler ist. muss da mal schauen und mich mal eh bei der IHK informieren, inwiefern mein Thema ausbildungskonform ist.
Egal was da kommt...ich werde trotzdem versuchen, es durch zuziehen


----------

