PHP 使用 iconv 转换大文件

标签 php performance file large-files iconv

我需要在不占用服务器内存的情况下转换文本文件的字符编码,而输入文件是用户配置的并且其大小不受限制。

使用 exec() 包装 unix 的 iconv 命令(我宁愿避免,尽管我已经在应用程序中使用它进行其他文件操作)会更有效,还是应该逐行读取文件并将其输出到另一个文件中?

我想这样工作:

$in = fopen("in.txt", "r");
$out = fopen("out.txt", "w+");
while(($line = fgets($in, 4096)) !== false) {
    $converted = iconv($charset["in"], $charset["out"], $line);
    fwrite($out, $converted);
}
rename("out.txt", "in.txt");

有没有更好的方法来快速有效地转换文件?我认为这可能相当消耗 CPU 资源,但我相信 iconv 本身是一项昂贵的任务,所以我不确定是否可以让它实际上根本不占用服务器太多资源。

谢谢!

最佳答案

好吧, 感谢您的输入,我根据它做了“我的作业”并得到了结果,使用了 50MB 的实际 CSV 数据样本:

首先,使用 PHP 迭代文件:

$in = fopen("a.txt", "r");
$out = fopen("p.txt", "w+");

$start = microtime(true);

while(($line = fgets($in)) !== false) {
    $converted = iconv("UTF-8", "EUC-JP//TRANSLIT", $line);
    fwrite($out, $converted);
}

$elapsed = microtime(true) - $start;
echo "<br>Iconv took $elapsed seconds\r\n";


Iconv took 2.2817220687866 seconds

我想这还不错,所以我在 #bash 中尝试了完全相同的方法,因此不必加载所有文件,而是迭代每一行(这可能不会完全发生,因为我了解 Lajos Veres回答)。事实上,这种方法效率并不高(CPU 一直处于重负载状态)。另外,输出文件比其他 2 个小,尽管快速查看后看起来是一样的,所以我一定在 bash 脚本中犯了一个错误,但是,无论如何,这都不会对性能产生这样的影响:

#!/bin/bash
echo "" > b.txt
time echo $(
    while read line
    do
        echo $line |iconv -f utf-8 -t EUC-JP//TRANSLIT >> b.txt
    done < a.txt
)

real 9m40.535s user 2m2.191s sys 3m18.993s

然后是我本以为会占用内存的经典方法,但是,检查 CPU/内存使用情况,它似乎没有比任何其他方法占用更多的内存,因此是赢家:

#!/bin/bash
time echo $(
    iconv -f utf-8 -t EUC-JP//TRANSLIT a.txt -o b2.txt
)

real 0m0.256s user 0m0.195s sys 0m0.060s

我将尝试获取更大的文件样本来测试两种更有效的方法,以确保内存使用量不会变得很大,但是,结果似乎足够明显,可以假设在 bash 中单次传递整个文件是最有效的(我没有在 PHP 中尝试过,因为我相信在 PHP 中将整个文件加载到数组/字符串中并不是一个好主意)。

关于PHP 使用 iconv 转换大文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19071546/

相关文章:

phpmyadmin 创建触发器错误且没有任何提示

performance - Delphi 6 应用程序在 Windows 7 上运行缓慢

performance - solr 查询 - 无需扫描文件即可获得结果

objective-c - 按创建日期排序文件 - iOS

php - Curl:保存文件而不是打开文件

php - 如何正确转义 JSON 字符串以便与 MySQL INSERT INTO 命令一起使用?

php - SQL/PHP : Joins with no matches on the other table (multiple tables)

java - Java程序帮助(Swing+数据库)

php - 使用 HTML 在 PHP 中对齐 3 个元素

.net - 使用通过 LINQ 查询的 SQL Server 中的超时异常