PHP怎样修改文件行顺序_PHP改文件行顺序法【排序】

4次阅读

直接读取+重排+写入最稳妥:php无原生就地排序函数,file()+usort()适合中小文件,需用FILE_IGNORE_NEW_LINES等标志;大文件应流式处理或调用系统sort命令。

PHP怎样修改文件行顺序_PHP改文件行顺序法【排序】

直接读取+重排+写入是最稳妥的做法

PHP 没有原生“就地修改文件行顺序”的函数,fgets()file() 读出来的是数组,排序必须在内存中完成,再用 file_put_contents() 覆盖写回。试图用 fseek() + fwrite() 手动挪动行位置极易出错——换行符长度不一致(n vs rn)、编码空格、bom 头都会导致偏移错乱。

file() + usort() 是最常用组合

适用于中小文件(几百 MB 以内),代码简洁且可控。注意默认 file() 会保留换行符,排序后若需保持格式统一,建议先 rtrim() 再排序,最后手动补 n

$lines = file('data.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); usort($lines, function($a, $b) {     return strcmp($a, $b); // 字典序     // 或 intval($a) <=> intval($b); // 数值序(PHP 7+) }); file_put_contents('data.txt', implode("n", $lines) . "n");
  • FILE_IGNORE_NEW_LINES 避免每行末尾带 n 干扰比较
  • FILE_SKIP_EMPTY_LINES 过滤空行,防止 strcmp('', 'xxx') 返回意外结果
  • 数值排序别直接用 sort($lines, SORT_NUMERIC) —— 它对字符串数字(如 "10")排序不稳定,usort + 强制转换更可靠

大文件慎用 file(),改用流式逐行读取+临时文件

超过 500MB 的文件,file() 可能触发内存耗尽(Allowed memory size exhausted)。此时应放弃一次性加载,改用 fopen() + fgets() 流式读取,把行内容和原始位置(或哈希)存到外部索引(如 sqlite 或临时 CSV),排序后再按序读取源文件写入新文件:

$fp = fopen('big.txt', 'r'); $tempLines = []; while (($line = fgets($fp)) !== false) {     $tempLines[] = rtrim($line, "rn"); } fclose($fp); // 排序... file_put_contents('big_sorted.txt', implode("n", $tempLines) . "n");
  • 虽然仍全量载入内存,但至少避免了 file() 自动加 n 的副作用
  • 真超大文件(GB 级)需配合外部排序工具(如系统 sort 命令),PHP 只做调度:exec('sort -o sorted.txt big.txt');
  • 注意 fgets()windows 下对 rn 的处理比 file() 更干净,不易多出空行

按某列排序(如 CSV 第三列)要先解析再比

直接对 CSV 行字符串排序会出错(比如按字典序排数字列,“100” 会排在 “2” 前面)。必须用 str_getcsv() 拆解,提取目标字段再比较:

立即学习PHP免费学习笔记(深入)”;

$lines = file('data.csv', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); usort($lines, function($a, $b) {     $aCols = str_getcsv($a);     $bCols = str_getcsv($b);     return $aCols[2] <=> $bCols[2]; // 按第3列(索引2)数值排序 }); file_put_contents('data.csv', implode("n", $lines) . "n");
  • str_getcsv() 自动处理带引号、逗号转义的 CSV,比 explode(',', $line) 安全得多
  • 若列含空值,$aCols[2] 可能未定义,建议加 ?? ''array_key_exists(2, $aCols) 判断
  • UTF-8 编码下,str_getcsv() 默认按字节解析,遇到多字节字符(如中文)一般没问题;但若 CSV 用 BOM 开头,file() 读出的首行可能含 xEFxBBxBF,需提前 ltrim($line, "xEFxBBxBF")

实际改行序最常卡在换行符不一致和 CSV 字段嵌套上,这两处不处理,排序结果看着正常,一导入 excel 就错位。

text=ZqhQzanResources