2017-06-28 1 views
2

Verschmelzung fand ich diesen Code auf Stackoverflow, von Benutzer @Attgun:php txt-Dateien, die Ausgabe mit Codierung

Link: merge all files in directory to one text file

<?php 

//Name of the directory containing all files to merge 
$Dir = "directory"; 

//Name of the output file 
$OutputFile = "filename.txt"; 

//Scan the files in the directory into an array 
$Files = scandir ($Dir); 

//Create a stream to the output file 
$Open = fopen ($OutputFile, "w"); //Use "w" to start a new output file from 
zero. If you want to increment an existing file, use "a". 

//Loop through the files, read their content into a string variable and 
write it to the file stream. Then, clean the variable. 

foreach ($Files as $k => $v) { 
    if ($v != "." AND $v != "..") { 
     $Data = file_get_contents ($Dir."/".$v); 
     fwrite ($Open, $Data); 
    } 
    unset ($Data); 
} 

//Close the file stream 
fclose ($Open); 
?> 

Der Code funktioniert richtig, aber wenn es verschmilzt, PHP fügt ein Zeichen am Anfang jeder kopierten Datei. Die Dateicodierung, die ich verwende, ist UCS-2 LE. Ich kann dieses Zeichen anzeigen, wenn ich die Codierung zu ANSI ändere.

Mein Problem ist, dass ich keine andere Codierung als UCS-2 LE verwenden kann.

Kann mir jemand bei diesem Problem helfen?

Edit: Ich möchte die Dateicodierung nicht ändern. Ich möchte die gleiche Codierung ohne PHP ein weiteres Zeichen hinzufügen.

+0

Wie wäre es nur mit 'cat/pfad/zu/dir/*> dateiname.txt' in bash? –

+0

Sam Onela, kein Kumpel, ist nicht doppelt, weil ich hier die aktuelle Kodierung behalten möchte (UCS-2 LE). – MimisK

+1

Diese Zeichen sind wahrscheinlich die Unicode-Stückliste (Byte Order Marker). Entferne sie nur aus allen Dateien, außer aus der ersten. –

Antwort

0

Die meisten PHP-String-Funktionen sind coding-agnostic. Sie sehen Strings nur als eine Ansammlung von Bytes. Sie können einen b an den fopen() Aufruf anhängen, um sicherzustellen, dass Zeilenvorschübe nicht verändert werden, aber nichts in Ihrem Code sollte die tatsächliche Kodierung ändern.

UCS-2 (ebenso wie sein Nachfolger UTF-16 und einige andere Mitglieder der UTF-Familie) ist ein Sonderfall, weil der Unicode-Standard zwei mögliche Richtungen definiert, um die einzelnen Bytes zu drucken, die einem Multi-Byte-Zeichen entsprechen (das hat den fancy Namen endianness), und eine solche Richtung wird durch das Vorhandensein des byte order mark-Zeichen bestimmt, gefolgt von einer variablen Anzahl von Bytes, die von der Codierung abhängt und die Endianität der Datei bestimmen.

Ein solches Präfix verhindert, dass die rohe Dateiverkettung funktioniert. Es ist jedoch immer noch ein ziemlich einfaches Format. Sie müssen lediglich die Stückliste aus allen Dateien entfernen, außer aus der ersten.

Um ehrlich zu sein, ich konnte nicht finden, was die Stückliste für UCS-2 ist (es ist eine veraltete Codierung und es ist nicht mehr in den meisten Unicode-Dokumentation vorhanden), aber da Sie mehrere Beispiele haben, sollten Sie in der Lage sein, es selbst zu sehen . Unter der Annahme, dass es the same as in UTF-16 (FF FE) ist müssen Sie würden nur zwei Bytes wegzulassen, z.B .:

$Data = file_get_contents ($Dir."/".$v); 
fwrite ($Open, substr($Data, 2)); 

ich ein wenig in sich geschlossene Beispiel zusammengesetzt habe. Ich habe keinen Editor, der mit UCS-2 umgehen kann, daher habe ich UTF-16 LE verwendet. Die BOM ist 0xFFFF (Sie Ihre Stückliste mit einem Hex-Editor wie hexed.it inspizieren können):

file_put_contents('a.txt', hex2bin('FFFE6100')); 
file_put_contents('b.txt', hex2bin('FFFE6200')); 

$output = fopen('all.txt', 'wb'); 

$first = true; 
foreach (scandir(__DIR__) as $position => $file) { 
    if (pathinfo($file, PATHINFO_EXTENSION)==='txt' && $file!=='all.txt') { 
     $data = file_get_contents($file); 
     fwrite($output, $first ? $data : substr($data, 2)); 
     $first = false; 
    } 
} 
fclose($output); 

var_dump(
    bin2hex(file_get_contents('a.txt')), 
    bin2hex(file_get_contents('b.txt')), 
    bin2hex(file_get_contents('all.txt')) 
); 
string(8) "fffe6100" 
string(8) "fffe6200" 
string(12) "fffe61006200" 

Wie Sie sehen können, wir mit einem einzigen BOM am oberen Ende und kein anderes Byte geändert wurde. Dies setzt natürlich voraus, dass alle Ihre Textdateien die gleiche Kodierung haben, die Kodierung ist genau die, die Sie denken.

+0

Leider ruiniert diese Version die gesamte Dateicodierung. Trotzdem danke für Ihre Mühe, mir zu helfen! – MimisK

+0

Dann wenden Sie entweder die Korrektur falsch an oder Ihre ursprüngliche Annahme, dass alle Dateien die gleiche Kodierung teilen, ist falsch (tatsächlich ist UCS-2 ziemlich veraltet, so dass es merkwürdig ist, dass jemand es 2017 noch benutzt). Vertrauen Sie mir: PHP ist kein JavaScript, PHP-Strings sind binäre Streams. –

0

@AlexHowansky motivierte mich, nach einem anderen Weg zu suchen.

Die Lösung, die es ohne Messing mit Dateicodierung zu funktionieren scheint, ist dies:

bat-Datei:

@echo on 
copy *.txt all.txt 
@pause 

Nun ist die letzte Datei die Codierung aus den Dateien hält, der liest. Mein Compiler zeigt keine Fehlermeldung wie zuvor!

+0

Das funktioniert, weil der Befehl [copy] (https://ss64.com/nt/copy.html) Dateien standardmäßig als Nur-Text behandelt (gegen Binärdateien) und es intelligent genug ist, die Codierung automatisch nach BOM zu erkennen. –