我在stackoverflow上找到了这个代码,来自用户@Attgun:
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);
?>
代码正常但在合并时,php会在复制的每个文件的开头插入一个字符。我使用的文件编码是UCS-2 LE。 当我将编码更改为ANSI时,我可以查看该字符。
我的问题是我不能使用其他编码而不是UCS-2 LE。
有人可以帮我解决这个问题吗?
编辑:我不想改变文件编码。我想保持相同的编码,而不添加PHP添加另一个字符。
答案 0 :(得分:0)
大多数PHP字符串函数与编码无关。它们只是将字符串视为字节集合。您可以在b
来电附加fopen()
,以确保换行不会受损,但代码中的任何内容都不应更改实际编码。
UCS-2(以及它的继承者UTF-16和UTF系列的其他成员)是一种特殊情况,因为Unicode标准定义了两个可能的方向来打印符合多字节字符的单个字节(有一个奇特的名称 endianness ),这种方向取决于byte order mark字符的存在,后跟可变数量的字节,这取决于编码并确定字节序的字节顺序。文件。
此类前缀是防止原始文件串联工作的原因。但是,它仍然是一种非常简单的格式。所需的只是从所有文件中删除BOM,但第一个。
说实话,我找不到UCS-2的BOM是什么(它是一个过时的编码,它在大多数Unicode文档中都不再存在)但是由于你有几个样本,你应该能够自己看到它。假设它是the same as in UTF-16(FF FE
)你只需要省略两个字节,例如:
$Data = file_get_contents ($Dir."/".$v);
fwrite ($Open, substr($Data, 2));
我编写了一个自成一体的例子。我没有任何能够处理UCS-2的编辑器所以我使用了UTF-16 LE。 BOM为0xFFFF
(您可以使用像hexed.it这样的十六进制编辑器检查BOM:
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"
正如您所看到的,我们最终在顶部有一个BOM,并且没有其他字节被更改。当然,这假设您的所有文本文件具有相同的编码,编码正是您所想的编码。
答案 1 :(得分:0)
@AlexHowansky激励我去寻找其他方式。
它似乎工作的解决方案没有弄乱文件编码是这样的:
bat文件:
@echo on
copy *.txt all.txt
@pause
现在,最终文件保留了读取文件的编码。 我的编译器没有像以前那样显示任何错误消息!