Unterschied zwischen Dateien, die im Binär- und im Textmodus geschrieben wurden

Lesezeit: 6 Minuten

Benutzer-Avatar
jholl

Welche Übersetzung findet statt, wenn in eine Datei geschrieben wird, die im Textmodus geöffnet wurde, die nicht im Binärmodus erfolgt? Speziell in MS Visual C.

unsigned char buffer[256];
for (int i = 0; i < 256; i++) buffer[i]=i;
int size  = 1;
int count = 256;

Binärmodus:

FILE *fp_binary = fopen(filename, "wb");
fwrite(buffer, size, count, fp_binary);

Im Vergleich zum Textmodus:

FILE *fp_text = fopen(filename, "wt");
fwrite(buffer, size, count, fp_text);

  • Die Motivation für die Frage war, dass ich Binärdaten wiederherstellen wollte, die versehentlich im Textmodus auf die Festplatte geschrieben wurden.

    – jholl

    23. Oktober 2008 um 17:44 Uhr

  • Eng verwandt: stackoverflow.com/q/11981434/183120

    – legends2k

    2. Juli 2015 um 15:18 Uhr


Benutzer-Avatar
Jon Trauntvein

Ich glaube, dass die meisten Plattformen die „t“-Option oder die „text-mode“-Option beim Umgang mit Streams ignorieren werden. Unter Windows ist dies jedoch nicht der Fall. Wenn Sie sich die Beschreibung der Funktion fopen() ansehen unter: MSDNwerden Sie sehen, dass die Angabe der Option “t” die folgende Wirkung hat:

  • Zeilenvorschübe (‘\n’) werden bei der Ausgabe in ‘\r\n’-Folgen übersetzt
  • Wagenrücklauf-/Zeilenvorschubsequenzen werden bei der Eingabe in Zeilenvorschübe übersetzt.
  • Wird die Datei im Append-Modus geöffnet, wird das Dateiende auf ein ctrl-z-Zeichen (Zeichen 26) untersucht und dieses Zeichen wenn möglich entfernt. Es wird auch das Vorhandensein dieses Zeichens als Dateiende interpretieren. Dies ist ein unglückliches Überbleibsel aus den Tagen von CPM (etwas über die Sünden der Eltern, die an ihren Kindern bis zur 3. oder 4. Generation heimgesucht werden). Entgegen der zuvor geäußerten Meinung wird das Strg-Z-Zeichen nicht angehängt.

  • Wagenrücklauf ist eigentlich ‘\r’, ‘\n’ ist Zeilenvorschub.

    – Christoffer Hammarström

    19. April 2010 um 12:05 Uhr

  • Hat es dieses Verhalten für alle Arten von Dateioperationen? Z.B. fread und fwrite (die hauptsächlich mit Binärdateien verwendet werden)?

    – Kalmarius

    18. Oktober 2013 um 16:34 Uhr

  • Die Übersetzung wird beim Öffnen des Dateihandles angegeben und findet auf niedriger Ebene statt. Dies erfolgt unabhängig von den Funktionen, die Sie zum Lesen (oder Schreiben) der Datei verwenden.

    – Jon Trauntvein

    21. Oktober 2013 um 18:18 Uhr

  • @Cheersandhth.-Alf -1 für die Wiederholung dessen, was bereits vor 4 Jahren gesagt wurde.

    – Virus721

    17. Februar 2016 um 10:11 Uhr

  • @Prakhar Agrawal: Soweit ich mich erinnere, stammen die CR- und LF-Codes aus den Tagen des Fernschreibers. Der Wagenrücklaufcode (“\r”) würde gesendet, um die Maschine dazu zu bringen, ihren Druckkopf in die Ausgangsposition auf der Zeile zurückzubringen, und der Zeilenvorschub (“\n”) würde gesendet, um die Platte um eine Zeile vorwärts zu bewegen. Diese Konzepte wurden in Terminalemulatoren weitergeführt, auch wenn sie ihre Bedeutung als physikalisches Äquivalent bisher weitgehend verloren hatten.

    – Jon Trauntvein

    17. April 2017 um 14:29 Uhr

Im Textmodus kann ein Zeilenumbruch “\n” in einen Wagenrücklauf + Zeilenumbruch “\r\n” umgewandelt werden

Normalerweise möchten Sie im Binärmodus öffnen. Der Versuch, Binärdaten im Textmodus zu lesen, funktioniert nicht, sie werden beschädigt. Sie können Text im Binärmodus jedoch gut lesen – es werden nur keine automatischen Übersetzungen von “\n” in “\r\n” durchgeführt.

Sehen föffnen

  • Beim Lesen funktioniert die Übersetzung umgekehrt zu dem, was Sie beschreiben – Umwandlung von “\r\n” in “\n”.

    – Markieren Sie Lösegeld

    23. Oktober 2008 um 15:19 Uhr

  • techtonik: Auf allen Plattformen können Sie den Textmodus angeben, aber unter Unix/Linux unterscheidet es sich nicht vom Binärmodus. Nur unter Windows macht es einen Unterschied. (Und möglicherweise einige obskurere Plattformen – Sie müssten Ihre Plattformdokumentation überprüfen, um sicher zu sein.)

    – HerrZebra

    7. Februar 2014 um 19:38 Uhr


Wenn Sie eine Datei mit “rt” öffnen, wird die Eingabe außerdem mit einem Strg-Z-Zeichen beendet.

  • Richtig – ich lasse meine eigenen Dateiformate mit so etwas wie “my-file-type^Z” beginnen, wenn Sie es dann von der Befehlszeile “tippen”/”cat”, gibt es Ihnen nur die “magischen Zahlen” der Datei und stoppt anstatt Binärdateien an Ihr Terminal zu senden.

    – HerrZebra

    23. Oktober 2008 um 14:46 Uhr

Benutzer-Avatar
Ming

Ein weiterer Unterschied besteht in der Verwendung fseek

Wenn der Stream im Binärmodus geöffnet ist, ist die neue Position genau Bytes versetzt, gemessen vom Anfang der Datei, wenn Ursprung SEEK_SET ist, von der aktuellen Dateiposition, wenn Ursprung SEEK_CUR ist, und vom Ende der Datei, wenn Ursprung SEEK_END ist. Einige Binärstreams unterstützen SEEK_END möglicherweise nicht.

Wenn der Stream im Textmodus geöffnet ist, sind die einzigen unterstützten Werte für offset Null (was mit jedem Ursprung funktioniert) und ein Wert, der von einem früheren Aufruf von std::ftell in einem Stream zurückgegeben wird, der mit derselben Datei verknüpft ist (was nur mit Ursprung von SEEK_SET.

Wir hatten ein interessantes Problem beim Öffnen von Dateien im Textmodus, wo die Dateien eine Mischung aus Zeilenendezeichen hatten:

1\n\r
2\n\r
3\n
4\n\r
5\n\r

Unsere Anforderung ist, dass wir unsere aktuelle Position in der Datei speichern können (wir haben fgetpos verwendet), die Datei schließen und später die Datei erneut öffnen und zu dieser Position suchen können (wir haben fsetpos verwendet).

Wenn jedoch eine Datei Mischungen von Zeilenenden aufweist, konnte dieser Prozess nicht nach der tatsächlich gleichen Position suchen. In unserem Fall (unser Tool analysiert C++) haben wir Teile der Datei erneut gelesen, die wir bereits gesehen hatten.

Gehen Sie mit binär – dann können Sie genau steuern, was aus der Datei gelesen und geschrieben wird.

Benutzer-Avatar
David Lopez

Auch wenn diese Frage bereits beantwortet und klar erklärt wurde, fände ich es interessant, das Hauptproblem (Übersetzung zwischen \n und \r\n) mit einem einfachen Codebeispiel zu zeigen. Beachten Sie, dass ich das Problem des Crtl-Z-Zeichens am Ende der Datei nicht anspreche.

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

int main() {
    FILE *f;
    char string[] = "A\nB";
    int len;
    
    len = strlen(string);
    printf("As you'd expect string has %d characters... ", len); /* prints 3*/
    f = fopen("test.txt", "w"); /* Text mode */
    fwrite(string, 1, len, f);  /* On windows "A\r\nB" is writen */
    printf ("but %ld bytes were writen to file", ftell(f)); /* prints 4 on Windows, 3 on Linux*/ 
    fclose(f);
    return 0;
}

Wenn Sie das Programm unter Windows ausführen, wird die folgende Meldung gedruckt:

As you'd expect string has 3 characters... but 4 bytes were writen to file

Natürlich können Sie die Datei auch mit einem Texteditor wie Notepad++ öffnen und sich die Zeichen selbst ansehen:

Geben Sie hier die Bildbeschreibung ein

Die umgekehrte Konvertierung wird unter Windows durchgeführt, wenn die Datei im Textmodus gelesen wird.

Benutzer-Avatar
Ajith Kumat

Im ‘w’-Modus wird die Datei im Schreibmodus geöffnet und die grundlegende Codierung ist ‘utf-8’ im ‘wb’-Modus, die Datei wird im Write-Binary-Modus geöffnet und ist für das Schreiben anderer Sonderzeichen und die Codierung verantwortlich kann ‘utf-16le’ oder andere sein

1013580cookie-checkUnterschied zwischen Dateien, die im Binär- und im Textmodus geschrieben wurden

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy