背景
工作中有遇到一些场景,处理某些文件时因为数据量太多太大了而导致处理时间非常长,并且大概率会处理失败。所以参考了网上的一些资料:php 处理拆分文件,不会从行中间切断。
先看效果
大文件拆分为4个文件
[root@iZt4nijo6mcpzvyciap0kaZ HongXunPan]# ll -h
total 4.1M
-rw-r--r-- 1 root root 4.1M May 23 17:19 test.txt
[root@iZt4nijo6mcpzvyciap0kaZ HongXunPan]# vim test.php
-rw-r--r-- 1 root root 961 May 23 17:20 test.php
-rw-r--r-- 1 root root 4276536 May 23 17:19 test.txt
[root@iZt4nijo6mcpzvyciap0kaZ HongXunPan]# /usr/local/php/bin/php test.php
[root@iZt4nijo6mcpzvyciap0kaZ HongXunPan]# ll -h
total 8.2M
-rw-r--r-- 1 root root 961 May 23 17:20 test.php
-rw-r--r-- 1 root root 4.1M May 23 17:19 test.txt
-rw-r--r-- 1 root root 1.1M May 23 17:21 test.txt_0
-rw-r--r-- 1 root root 1.1M May 23 17:21 test.txt_1
-rw-r--r-- 1 root root 1.1M May 23 17:21 test.txt_2
-rw-r--r-- 1 root root 1.1M May 23 17:21 test.txt_3
拆分为10个文件
[root@iZt4nijo6mcpzvyciap0kaZ HongXunPan]# /usr/local/php/bin/php test.php
[root@iZt4nijo6mcpzvyciap0kaZ HongXunPan]# ll -h
total 8.2M
-rw-r--r-- 1 root root 962 May 23 17:29 test.php
-rw-r--r-- 1 root root 4.1M May 23 17:28 test.txt
-rw-r--r-- 1 root root 418K May 25 19:45 test.txt_0
-rw-r--r-- 1 root root 418K May 25 19:45 test.txt_1
-rw-r--r-- 1 root root 418K May 25 19:45 test.txt_2
-rw-r--r-- 1 root root 418K May 25 19:45 test.txt_3
-rw-r--r-- 1 root root 418K May 25 19:45 test.txt_4
-rw-r--r-- 1 root root 418K May 25 19:45 test.txt_5
-rw-r--r-- 1 root root 418K May 25 19:45 test.txt_6
-rw-r--r-- 1 root root 418K May 25 19:45 test.txt_7
-rw-r--r-- 1 root root 418K May 25 19:45 test.txt_8
-rw-r--r-- 1 root root 418K May 25 19:45 test.txt_9
源码
test.php
<?php
$filename = './test.txt';
$file = fopen($filename,'r+') or die('fail');
$filenum = 4; //拆分成新文件的数量
$filelen = ceil(filesize($filename)/$filenum); //每个新文件的长度
rewind($file); //指针设置到文件开头0的位置
$lastlen = 0;
for ($i = 0; $i< $filenum ; $i++)
{
$content = fread($file, $filelen + $lastlen); //等长字符串,加上上一个字符串不足一行的部分
$lastn = strrchr($content, "\n"); //不足一行的字符串
$lastlen = strlen($lastn); //不足一行的字符串长度
$complete = substr($content, 0, strlen($content) - $lastlen); //减去当前字符串不足一行的部分,得到每一行都完整的字符串
//写入新文件
$newfile = fopen($filename. '_' . $i, 'w+');
fwrite($newfile, $complete);
fseek($file, ftell($file) - $lastlen + 1); //将文件指针返回到不足一行的开头,使下一个文件能得到完整行
}
fclose($file);