Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

Dateimodus 'BINARY'

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu QBasic.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
jb



Anmeldungsdatum: 14.01.2005
Beiträge: 2010

BeitragVerfasst am: 22.03.2005, 20:50    Titel: Dateimodus 'BINARY' Antworten mit Zitat

Hallo!

Ich bitte im Voraus für etwas Geduld, da ich nicht der beste Erklärer bin. zwinkern

Ich habe versucht, eine .EXE und eine .TXT-Datei in eine .PAK Datei zu packen.
Das soll so eine Art Komprimierung darstellen. Diese Datei wird im Binärmodus erstellt.

Nun muss der "Entpacker" ja auch wissen, wo er was abspeichern soll.
Deshalb steht in der .PAK-Datei der Dateiname am Anfang, umgeben (je rechts und links)
von dem Zeichen mit dem ASCII-Code 178.

Das Prog liest nun Byte für Byte ein, und überprüft jedesmal, ob sich eingelesene Byte
der ASCII-Code 178 ist.
Wenn dies so ist, addiert er alle nachfolgenden Zeichen (bis wiederum ein
ASCII-Code 178 folgt) dem Dateinamen Pfad$ hinzu.

Nun schreibt er alle nachfolgenden Zeichen in die entsprechende Datei.

Wenn nun ein "@" folgt, beendet der Entpacker.

Wenn ich aber den Dateinamen mit PRINT anzeige, sehe ich keinen Fehler
im selbigen.

Aber wenn nun die Datei geöffnet werden soll, steht da: 'Ungültiger
Dateiname', und nichts geht mehr.

Bsp: Vorher war Pfad$ = "A:\ABC.TXT"
und nachher eine hübsche Ansammlung wildfremder Zeichen (z.B. die ASCII-Codes von 1-31).

Wo liegt das Problem??

Hier der Code:

Code:

 DIM byte AS STRING * 1
 
 OPEN "A:\KOMP.PAK" FOR BINARY AS #1
 
 Pfad$ = "A:\"
 
 REM Der Pfadname wird "rausgefiltert"
 DO
  GET #1, , byte
  IF ASC(byte) <> 178 THEN Pfad$ = Pfad$ + byte ELSE EXIT DO
 LOOP
 
 REM Hier geht noch alles
 PRINT CHR$(34) + Pfad$ + CHR$(34) + " wird erstellt..."
 REM Aber HIER kommt der Fehler

 --> OPEN Pfad$ FOR BINARY AS #3 <--
 
 DO
   GET #1, , byte
   
   IF byte = "@" THEN EXIT DO
   
   PUT #3, , byte
 
   LOOP
  CLOSE #3


jb
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Stephan



Anmeldungsdatum: 05.10.2004
Beiträge: 358
Wohnort: Hessen - 20km Nördlich von Frankfurt am Main

BeitragVerfasst am: 22.03.2005, 23:20    Titel: Antworten mit Zitat

Öffne mal deine PAK datei mit einem Hex editor, und kontrolliere ob alles richtig geschrieben wurde.

Ich würde aber an deiner stelle den ganzen aufbau etwas Ändern.

Was passiert z.b. wenn du eine EXE datei hinzufügst, in der das Zeichen "@" im Hexcode vorkommt,
dann funktioniert dein programm schon nichtmehr.

Vielleicht ein kleiner ansatz, wie du soetwas einfacher hinbekommen kannst.

Erstmal einen Block für die Dateinamen & Größen Reservieren (im prinzip eine art TOC)

z.b.

50 Bytes Dateiname , 4 Byte Datei Anfang in der PAK Datei , 4 Byte Datei Größe

Du schreibst einfach den Dateinamen in Tabelle,und lässt die Reslichen Bytes (der 50 Bytes) leer (CHR$(0))
somit kannst du den Namen schonmal gut auslesen.
Und durch die Tabelarische Anordnung ist es auch kein problem mal schnell
eine Dateigröße auszulesen,um eine Datei weiter unten zu Extrahieren.

Dadurch kannst du dir z.b. ganz einfach eine Formel erstellen,mit der du zu jeden punkt in der Liste springen kannst.
_________________
'Wir schätzen die Zeit erst, wenn uns nicht mehr viel davon geblieben ist.'
Leo Tolstoi
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
jb



Anmeldungsdatum: 14.01.2005
Beiträge: 2010

BeitragVerfasst am: 23.03.2005, 10:35    Titel: Antworten mit Zitat

Die Datei ist korrekt aufgebaut, und in der .EXE und in der.TXT Datei sind
keine @-Zeichen enthalten.
Aber vielen Dank für den Tipp! lächeln

jb
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Stephan



Anmeldungsdatum: 05.10.2004
Beiträge: 358
Wohnort: Hessen - 20km Nördlich von Frankfurt am Main

BeitragVerfasst am: 23.03.2005, 10:59    Titel: Antworten mit Zitat

Nochmal zu den EXE Dateien,

Ich hab mal schnell nachgeschaut, und habe bei mir KEINE Win32 EXE Gefunden,
an der nicht an Position 24 ein "@" vorkahm.

Bei Dos EXE Dateien hatte ich im Header sogar noch viel mehr.
d.h. selbst wenn das Namen auslesen bei dir funktioniert,wirst du spätestens beim auslesen der EXE
riesen probleme bekommen.

Teste es selbst, Benutze mal die Windows Such Funktion,
gib als Namen *.EXE ein , und als Enthaltenen text ein "@" ein,
du wirst sehen.
(Ich hab auf C:\ 920 EXE dateien, davon enthalten 917 ein @)
_________________
'Wir schätzen die Zeit erst, wenn uns nicht mehr viel davon geblieben ist.'
Leo Tolstoi
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
jb



Anmeldungsdatum: 14.01.2005
Beiträge: 2010

BeitragVerfasst am: 23.03.2005, 13:30    Titel: Antworten mit Zitat

Okay, deine Methode ist wohl die bessere...

Ich habe das jetzt so gemacht:

1. Teil: Dateiname (Byte 1-100)
2. Teil: Dateigröße in Bytes (Bytes 101-500)
3. Teil: Daten (Bytes 500 bis ???)
4. Weiter

Alle Leerstellen habe ich mit CHR$(0) ausgefüllt.

Das Auslesen funktioniet so:

1. Öffne die "gepackte" Datei
2. Hole 100 mal je ein Byte, wenn es sich nicht um CHR$(0) handelt, hänge es dem Pfadnamen an.
3. Hole die Größe.

Hier steckt ein Problem. byte ist eine Variable vom TYpe STRING * 1, da ich vorher immer
einen Überlauf-Fehler bekam.
Nun wird hier genauso wie bem Dateinamen verfahren: Hole 500mal ein
Byte, wenn es sich nicht um CHR$(0) handelt, füge es dem Dateigrößen-String an.
Nun muss ich irgendwann den String in eine brauchbare Zahl umwandeln.
Doch genau hier steckt das Problem, da komme ich nicht weiter.
Da steht dann zum Beispiel: Ñ7☺.
Wie zum Teufel daraus eine Dateilänge ermitteln?

Weiß jemand Rat?

jb
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Mecki
Igel


Anmeldungsdatum: 10.09.2004
Beiträge: 985
Wohnort: Niederbayern

BeitragVerfasst am: 23.03.2005, 13:56    Titel: Antworten mit Zitat

Porbier vielleicht mal sachen durch wie MKI$ (CVI) oder so? Weiß jetzt nicht, wieviele Buchstaben das Forum geschluckt hat beim Anzeigen.
_________________
» Yodl.de: So sucht man gestern. verwundert
» Geld verdienen im Netz + ICQ.
» Firefox!
» 100€ zu gewinnen
» FreeBASIC.de
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen AIM-Name Yahoo Messenger MSN Messenger
Skilltronic



Anmeldungsdatum: 10.09.2004
Beiträge: 1148
Wohnort: Köln

BeitragVerfasst am: 23.03.2005, 14:51    Titel: Antworten mit Zitat

Hallo!

Wie wandelst du denn die Dateilänge beim Schreiben in ASCII-Zeichen um?

Wenn du Dateien hast, die grösser als 256 Byte sind, musst du die Grösse auf mehrere Byte verteilen. So wie eine Integer-Variable auch aus zwei Byte besteht um Zahlen von -32768 bis 32767 aufnehmen zu können. Beim Lesen diese Bytes dann wieder zusammensetzen. Vier, maximal 16 Byte sollten dafür auch genügen. 400 Sind etwas übertieben. Ich glaube, dass würde für Dateien ausreichen, die das gesamte Wissen der Menschheit enthalten.

Gruss
Skilltronic
_________________
Elektronik und QB? www.skilltronics.de !
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
jb



Anmeldungsdatum: 14.01.2005
Beiträge: 2010

BeitragVerfasst am: 23.03.2005, 22:37    Titel: Antworten mit Zitat

Hab's jetzt anders gelöst:
Die Dateigröße wird errechnet, dann im String Groesse$ abgespeichert,
dann wird der String abgescannt, und der ASCII-Code von MID$(Groesse$, i, 1) gespeichert.
Beim Lesen wird der String dann genauso zusammengesetzt und anschließend
wieder in eine Zahl umgewandelt.

Ist zwar etwas kompliziert, aber es klappt...

jb
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Skilltronic



Anmeldungsdatum: 10.09.2004
Beiträge: 1148
Wohnort: Köln

BeitragVerfasst am: 25.03.2005, 13:32    Titel: Antworten mit Zitat

Hallo!

Ich habe dir hier mal ein kleines Beispiel geschrieben, das die Länge einer Datei in 8 Byte zerlegt, daraus einen String erstellt und aus diesem wieder die Zahl. Man muss sich nur klarmachen, dass es dabei um den Stellenwert der einzelnen Bytes geht, ganau wie bei den Bits innerhalb des Bytes.

Code:
CLS
'Dateilaenge ermitteln
OPEN "datei.dat" FOR BINARY AS #1
dl# = LOF(1)
CLOSE 1
PRINT "Dateilaenge:"; dl#; "Byte"

'Diese Zahl in einen 8-stelligen String umwandeln
text$ = ""
FOR a = 7 TO 0 STEP -1
p# = 256 ^ a
byte = FIX(dl# / p#)
text$ = text$ + CHR$(byte)
dl# = dl# - byte * p#
NEXT
PRINT "String:"; text$
PRINT "Dateilaenge:"; dl#; "Byte"

'Und aus dem String wieder eine Zahl machen
FOR a = 7 TO 0 STEP -1
p# = 256 ^ a
byte = ASC(MID$(text$, 8 - a, 1))
dl# = dl# + byte * p#
NEXT
PRINT "Dateilaenge:"; dl#; "Byte"


Wenn eines der Zeichen zufälig einen Zeilenvorschub oder so enthält, kann es im Beispiel etwas seltsam aussehen, normalerweise lässt man sich den String aber ja nicht anzeigen.

Gruss
Skilltronic
_________________
Elektronik und QB? www.skilltronics.de !
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
jb



Anmeldungsdatum: 14.01.2005
Beiträge: 2010

BeitragVerfasst am: 26.03.2005, 15:52    Titel: Antworten mit Zitat

THX, Skilltronic! lächeln

Ich hab's inzwischen anders gelöst:

Code:

REM Speichern einer Zahl:

Zahl = 1785
z$ = RTRIM$(LTRIM$(STR$(Zahl$)))

DIM byte AS STRING * 1

FOR i = 1 TO LEN(z$)
 byte = MID$(z$, i, 1)
 PUT #1, , byte
NEXT i

REM *****************************

REM Laden einer Zahl:

DIM byte AS STRING * 1

DO
 GET #1, , byte
 IF byte > CHR$(9) THEN EXIT DO
 z$ = z$ + byte
LOOP

FOR i = 1 TO LEN(z$)
 Zahl$ = Zahl$ + STR$(ASC(MID$(z$, i, 1)))
NEXT i

GeladeneZahl = VAL(Zahl$)


Dabei wird beim Speichern immer ein Zeichen mit MID$ isoliert, dann
wird dieses als Byte geschrieben. Beim Lesen wird dann einem String solange
der ASCII-Wert des eben gelesenen Bytes zugeordnet, bis dieses größer
als 9 ist.
Nun muss man den String nur noch in eine Zahl umwandeln.

jb
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu QBasic. Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz