it-swarm.com.de

Kann sich die Dateicodierung ändern, wenn FTP verwendet wird?

Ich entwickle eine Webanwendung, die eine Reihe von Webseiten mit PHP curl herunterlädt. Anschließend werden die Dateien mit diff verglichen, wenn sie sich täglich ändern.

Ich habe vor einigen Wochen ein Problem gemeldet, bei dem scheinbar identische Dateien von diff als unterschiedlich gekennzeichnet wurden: https://stackoverflow.com/questions/42552239/different-versions-of-diff-giving -gemischte-Ergebnisse-beim-Vergleichen-von-2-identischen-Dateien

Die Antwort auf das oben Gesagte war, dass wenn diff mit dem -w -Flag verwendet wurde, Leerzeichen ignoriert werden.

Allerdings habe ich jetzt ein separates Problem bemerkt. Wenn ich eine der Dateien, die ich vergleiche, herunterlade und über einen FTP-Client erneut hochlade (überschreibe), ändert sich die Ausgabe.

Zum Beispiel: Vergleichen Sie file1.html mit file2.html mit diff file1.html file2.html

12159,12161c12159,12161
<   
< 
< 
---
>   
> 
> 
12163,12172c12163,12172
< 
< 
< 
< 
< 
< 
< 
< 
< 
< 
---

Wenn ich jedoch file2.html auf meinen Desktop herunterlade und es über FTP erneut hochlade, diff ohne das -w Flag gibt an, dass es überhaupt keine Unterschiede gibt, d. h. es wird jetzt gesagt, dass die Dateien identisch sind.

Ich habe versucht, die Kodierung der Datei mit file -bi file2.html zu überprüfen, sie wird jedoch vor und nach dem Upload über FTP gleich gemeldet. Die Kodierung ist text/html; charset=us-ascii

Wenn die Kodierung nicht anders ist und der Inhalt der Datei nicht geändert wurde, wie kann das erneute Hochladen der Datei über FTP etwas ändern? Ich habe es mit FileZilla und auch über Netbeans versucht.

Ich verwende macOS Sierra lokal und der Remote-Server ist Apache 2/PHP 7/centOS.

4
Andy

Sie sehen wahrscheinlich einen Unterschied in den Zeilenenden. Beim Übertragen einer Datei im ASCII/Text-Modus (im Gegensatz zum "Binärmodus") konvertieren/normalisieren die meisten FTP-Clients die Zeilenenden in das Betriebssystem, in das übertragen wird.

Unter Classic Mac OS (9.x und früher) ist das Zeilenendezeichen einfach \r (ASCII 13), unter Mac OS X wurde es in \n (ASCII 10) geändert, unter Linux ist es \n (ASCII 10). Und Windows ist \r\n oder ASCII 13 + 10. (Danke @ 8bittree für die Mac-Korrektur.)

Beim Herunterladen von einem Betriebssystem auf ein anderes werden alle Zeilenenden stillschweigend konvertiert. Die Konvertierung wird beim Hochladen rückgängig gemacht. (Wie in @ Joshua's answer angegeben, kann dies jedoch zu einer Beschädigung führen, abhängig von der Zeichenkodierung der Datei und den in der Datei enthaltenen bestimmten Zeichen.) Wenn es einen Mischmasch von Zeilenenden gibt, ist das möglich Die FTP-Software normalisiert/repariert die Zeilenenden. Dies würde erklären, warum das Herunterladen und Hochladen der Datei zu einer "anderen" Datei führt als ursprünglich auf dem Server (dh "behoben"). Oder wird eine zuvor falsch konvertierte Datei wiederhergestellt? Die EOL-Konvertierung ist jedoch möglicherweise nicht so intelligent und es kann vorkommen, dass doppelte Zeilenabstände oder fehlende Zeilenumbrüche auftreten (z. B. geringfügig verfälscht).

Standardmäßig sind die meisten FTP-Clients auf den Übertragungsmodus "Automatisch" eingestellt und verfügen über eine Liste bekannter Dateitypen, die im ASCII/Text-Modus übertragen werden sollen. Andere Dateitypen werden im Modus "Binär" übertragen. Wenn Sie zwischen demselben Betriebssystem übertragen oder ohne Konvertierung übertragen möchten, sollten Sie nur den Modus "Binär" verwenden.

Normalerweise ändert die FTP-Software die Zeichenkodierung der übertragenen Datei nur, wenn die Quell-/Zielbetriebssysteme eine ganz andere Zeichenkodierung für die Darstellung von Textdateien verwenden. Wie @KeithDavies in Kommentaren angemerkt hat, ist ein solches Beispiel das Herunterladen von einem Großrechner, der EBCDIC verwendet, auf einen lokalen Windows-Computer. EBCDIC wird von Windows nicht nativ unterstützt, daher ist eine Konvertierung erforderlich, um dies in ASCII zu konvertieren. Das Übertragen im "Binärmodus" vermeidet eine solche Umwandlung. (Danke an @KeithDavies für den Hinweis zur Zeichenkodierung.)

Die Antwort auf das Obige war, dass wenn diff mit dem Flag -w verwendet wurde, es Leerzeichen ignoriert.

Ja, Zeilenenden (Whitespace) werden im Vergleich ignoriert.

Wenn ich eine der Dateien, die ich vergleiche, herunterlade und über einen FTP-Client erneut hochlade (überschreibe), ändert sich die Ausgabe.

Wenn die ursprüngliche Datei eine Mischung aus Zeilenenden enthält, kann das Herunterladen und erneute Hochladen im ASCII -Modus die inkonsistenten Zeilenenden beheben. Die Dateien sind nun also "gleich".

6
MrWhite

Ja. Übertragen Sie keine UTF-16-Dateien im ASCII -Modus. Verwenden Sie den Binärmodus, um hier eine Beschädigung der Daten zu vermeiden.

Durch die FTP-Umwandlung von\r\n in\n wird der Rest der Datei beschädigt, wenn das einzelne Zeichen character oder die Sequenz ㄍ ㄍ oder viele andere derselben Klasse enthalten sind.

Bitte beachten Sie, dass dies keine intelligente Transformation ist und die umgekehrte Transformation auch existiert und noch einige weitere Fälle abdeckt.

3
Joshua

Ja, FTP führt einige Kodierungsänderungen durch. Daten werden von einem Speichergerät im sendenden Host zu einem Speichergerät im empfangenden Host übertragen. Häufig müssen bestimmte Transformationen für die Daten durchgeführt werden, da die Datenspeicherdarstellungen in den beiden Systemen unterschiedlich sind. Beispielsweise verfügt NVT-ASCII über unterschiedliche Datenspeicherdarstellungen in unterschiedlichen Systemen. PDP-10 speichern NVT-ASCII im Allgemeinen als fünf 7-Bit ASCII -Zeichen, linksbündig in einem 36-Bit-Wort. In 360's wird NVT-ASCII als 8-Bit-EBCDIC-Code gespeichert. Multics speichert NVT-ASCII als vier 9-Bit-Zeichen in einem 36-Bit-Wort. Es kann wünschenswert sein, Zeichen in die Standard-NVT-ASCII-Darstellung zu konvertieren, wenn Text zwischen verschiedenen Systemen übertragen wird. Die sendenden und empfangenden Sites müssten die erforderlichen Transformationen zwischen der Standarddarstellung und ihren internen Darstellungen durchführen (weitere Einzelheiten finden Sie im Abschnitt Datendarstellung und -speicherung von RFC 765 ).

2
Pramod_Para

Die Antwort, die ich darauf gegeben habe, ist richtig, aber ich füge einige Anmerkungen dazu hinzu, wie ich diese Informationen verwendet habe, um herauszufinden, was vor sich ging.

Die Frage verwendet der Einfachheit halber file1.html und file2.html. In Wirklichkeit repräsentiert file1.html eine "Masterkopie" einer in der Vergangenheit heruntergeladenen Webseite. file2.html ist der neueste Download des Webseiteninhalts. Mit der Anwendung soll die Masterkopie der Datei mit der neuesten Version (diff file1.html file2.html) verglichen werden.

In der realen Anwendung gibt es Hunderte dieser Dateien.

Beim Erstellen der Masterdateien hatte ich alle file1.html -Äquivalente auf meinen Desktop heruntergeladen. Ich habe sie dann über FileZilla erneut in ein "Master" -Verzeichnis auf dem Server hochgeladen. Dies geschah vor einiger Zeit (ungefähr am 1. März) und ich hatte erst darüber nachgedacht, als mir klar wurde, was passiert war.

Durch das Hochladen über FileZilla von einem Mac wurden Änderungen am Zeilenumbruch vorgenommen, wie in der akzeptierten Antwort beschrieben. Insbesondere wird \r verwendet, während auf dem Linux-Webserver (centOS) \n verwendet wird.

Also, als ich diff file1.html file2.html sagte, dass die Dateien unterschiedlich sind. Dies liegt daran, dass sich zu diesem Zeitpunkt zwischen den Dateien zwei verschiedene neue Zeilenzeichen befinden: \r in file1.html und \n in file2.html

Ich habe damals file2.html heruntergeladen und mit FileZilla von meinem Desktop auf den Server hochgeladen (überschrieben). Dies ist der Punkt, an dem ich die ursprüngliche Frage gestellt habe.

Wie die Antwort vermuten lässt, besteht ein Unterschied in der Zeichenkodierung, bis file2.html hochgeladen wird. Zu diesem Zeitpunkt sind die Dateien identisch, da beide denselben Prozess durchlaufen haben. Aus meiner Sicht war es, als ob das bloße Hochladen von file2.html das Problem "behoben" hätte, konnte aber nicht verstehen, warum.

Mit https://stackoverflow.com/questions/3569997/view-line-endings-in-a-text-file konnte ich feststellen, welche Dateien welche neuen Zeilenzeichen verwenden

Meine Lösung für das gesamte Problem besteht darin, nichts über FTP herunterzuladen - da dies lediglich zum Überprüfen der Dateien verwendet wurde - und beim Erstellen des "Master" -Dateiverzeichnisses auf dem Server stattdessen cp zu verwenden. Da dies alles unter Linux durchgeführt wird, gibt es keine Unterschiede bei den neuen Zeilenzeichen. Die Kopie jeder Datei bedeutet, dass immer \n verwendet wird.

Grundsätzlich besteht die Lösung für dieses Problem darin, dass das neue Zeilenzeichen für alle Dateien gleich sein muss, andernfalls werden sie von diff als unterschiedlich gekennzeichnet, aber die Ausgabe ist nicht hilfreich, um Sie anzuzeigen Was dieser Unterschied ist, da diese Zeichen "unsichtbar" sind, wenn die Datei angezeigt wird (es sei denn, Sie verwenden den obigen Link, um sie in einem Editor anzuzeigen).

2
Andy