我有一个包含数百万行文字的.txt文件
下面的代码删除.txt文件中的特定行(.com域名)。但是大文件无法做到:(
<?php
$fname = "test.txt";
$lines = file($fname);
foreach($lines as $line) if(!strstr($line, ".com")) $out .= $line;
$f = fopen($fname, "w");
fwrite($f, $out);
fclose($f);
?>
我想删除某些行并将它们放在另一个文件中
例如,网站的域名列表。切断.com域并将其粘贴到另一个文件中......
答案 0 :(得分:0)
这是一种使用http://php.net/manual/en/class.splfileobject.php并使用临时文件的方法。
$fileName = 'whatever.txt';
$linesToDelete = array( 3, 5 );
// Working File
$file = new SplFileObject( $fileName, 'a+' );
$file->flock( LOCK_EX );
// Temp File
$temp = new SplTempFileObject( 0 );
$temp->flock( LOCK_EX );
// Wite the temp file without the lines
foreach( $file as $key => $line )
{
if( in_array( $key + 1, $linesToDelete ) === false )
{
$temp->fwrite( $line );
}
}
// Write Back to the main file
$file->ftruncate(0);
foreach( $temp as $line )
{
$file->fwrite( $line );
}
$file->flock( LOCK_UN );
$temp->flock( LOCK_UN );
虽然这可能很慢,但是在我的Windows xampp设置上,一个40兆的文件和140000行需要2.3秒。这可以通过写入临时文件并执行文件移动来加速,但我不想在您的环境中踩到文件权限。
编辑:使用重命名/移动而非第二次写入的解决方案
$fileName = __DIR__ . DIRECTORY_SEPARATOR . 'whatever.txt';
$linesToDelete = array( 3, 5 );
// Working File
$file = new SplFileObject( $fileName, 'a+' );
$file->flock( LOCK_EX );
// Temp File
$tempFileName = tempnam( sys_get_temp_dir(), rand() );
$temp = new SplFileObject( $tempFileName,'w+');
$temp->flock( LOCK_EX );
// Write the temp file without the lines
foreach( $file as $key => $line )
{
if( in_array( $key + 1, $linesToDelete ) === false )
{
$temp->fwrite( $line );
}
}
// File Rename
$file->flock( LOCK_UN );
$temp->flock( LOCK_UN );
unset( $file, $temp ); // Kill the SPL objects relasing further locks
unlink( $fileName );
rename( $tempFileName, $fileName );
答案 1 :(得分:0)
可能是因为文件太大而占用了太多空间。
执行file('test.txt')
时,它会将整个文件读入数组。
相反,您可以尝试使用Generators
。
GeneratorsExample.php
<?php
class GeneratorsExample {
function file_lines($filename) {
$file = fopen($filename, 'r');
while (($line = fgets($file)) !== false) {
yield $line;
}
fclose($file);
}
function copyFile($srcFile, $destFile) {
foreach ($this->file_lines($srcFile) as $line) {
if(!strstr($line, ".com")) {
$f = fopen($destFile, "a");
fwrite($f, $line);
fclose($f);
}
}
}
}
callingFile.php
<?php
include('GeneratorsExample.php');
$ob = new GeneratorsExample();
$ob->copyFile('file1.txt', 'file2.txt')
答案 2 :(得分:-3)
虽然您可以使用数十行PHP代码,但一行shell代码可以使用。
$ grep Bar.com stuff.txt > stuff2.txt
或作为PHP
system ("grep Bar.com stuff.txt > stuff2.txt");