繁体   English   中英

PHP合并TXT文件,编码问题

[英]php merging txt files, issue with encoding

我从用户@Attgun在stackoverflow上找到了以下代码:

链接: 将目录中的所有文件合并为一个文本文件

<?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添加另一个字符。

大多数PHP字符串函数与编码无关。 他们只是将字符串视为字节的集合。 您可以将b附加到fopen()调用中,以确保换行不被破坏,但是代码中的任何内容都不应更改实际的编码。

UCS-2(以及它的后继UTF-16和UTF系列的其他一些成员)是一种特殊情况,因为Unicode标准定义了两个可能的方向来打印符合多字节字符(有花哨的字符)的各个字节。 字节顺序名称字符),然后根据字节顺序标记字符的存在来确定这种方向,然后根据字节的可变数量(取决于编码并确定文件的字节顺序)来确定。

这样的前缀会阻止原始文件串联工作。 但是,它仍然是一种非常简单的格式。 所需要做的就是从第一个文件中删除所有文件中的BOM。

坦白说,我找不到UCS-2的BOM表(这是一种过时的编码,并且在大多数Unicode文档中都不再存在),但是由于您有几个示例,您应该可以自己查看它。 假设它与UTF-16FF 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表的顶部,并且其他字节均未更改。 当然,这假设您所有的文本文件都具有相同的编码,而您认为的正是该编码。

@AlexHowansky促使我寻找其他方式。

在不干扰文件编码的情况下似乎可以解决的解决方案是:

蝙蝠文件:

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

现在,最终文件将保留读取文件的编码。 我的编译器没有显示任何错误消息!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM