我们有一个巨大的文本文件(大约1个演出),我们想用php搜索它,
为此,我用一些线程打开了本文的某些部分,并在这部分中进行了搜索。
像下面这样:
class AsyncFileRequest extends Thread
{ public $from_line;
public $to_line;
public $line;
public $n;
public $ans;
public $handle;
public function __construct($handle,$from_line,$to_line) {
$this->handle =$handle = @fopen($handle, 'r');
$this->from_line =$from_line;
$this->to_line =$to_line;
}
public function run() {
if (($handle = $this->handle) &&
($from_line = $this->from_line) &&
($to_line = $this->to_line)
) {
$n=0;
$ans="";
while($line=stream_get_line($handle,65535,"\n")) {
$n++;
if($n>=$from_line){
$ans.=$line;
}
if ($n == $to_line) {
break;
}
}
fclose($handle);
$this->data=$ans;
} else printf("Thread #%lu was not provided a URL<br>\n", $this->getThreadId());
}
}
但是,如果我用更多的时间来打开它,要花很长时间来处理,我们该如何用php线程来逐步打开大文件?
最佳答案
您想要在run方法中打开该句柄,这样可以确保每个线程都对该文件具有唯一的句柄。
线程将起作用,但是优选使用Pools执行模型。让Pool决定要在哪个线程中执行,对硬件和任务使用合理大小的Pool,并继续提交任务,直到完成所有工作为止。
然后等待池关闭,您可以使用Pool::collect从任务中获取数据。
例如:
<?php
/* A pooled task to read specific lines from a file */
class LineReader extends Collectable {
public function __construct($file, $start, $lines) {
$this->file = $file;
$this->start = $start;
$this->lines = $lines;
}
public function run() {
/* don't write the handle to the object scope */
$handle = fopen($this->file, "r");
$line = 1;
$count = 0;
while (($next = fgets($handle))) {
if ($line >= $this->start) {
if ($count < $this->lines) {
$lines .= $next;
$count++;
} else break;
}
$line++;
}
$this->data = $lines;
/* close handle */
fclose($handle);
/* finished with object */
$this->setGarbage();
}
}
$pool = new Pool(8);
/* submit enough tasks to read entire file */
$pool->submit(
new LineReader(__FILE__, 1, 10));
$pool->submit(
new LineReader(__FILE__, 10, 10));
$pool->submit(
new LineReader(__FILE__, 20, 10));
$pool->submit(
new LineReader(__FILE__, 30, 10));
$pool->submit(
new LineReader(__FILE__, 40, 10));
$pool->submit(
new LineReader(__FILE__, 50, 10));
$pool->submit(
new LineReader(__FILE__, 60, 10));
/* force all reading to complete */
$pool->shutdown();
/* cleanup pool, and echo data to show working */
$pool->collect(function(LineReader $reader){
foreach(preg_split("~\n~", $reader->data) as $line) {
printf(
"%04d: %s\n", $reader->start++, $line);
}
/* allow object to be free'd */
return $reader->isGarbage();
});
?>
关于php - 用PHP线程打开文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27027542/