Passed
Push — master ( 516163...07b934 )
by 世昌
02:15
created

ReadLineIterator   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 49
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 26
dl 0
loc 49
rs 10
c 0
b 0
f 0
wmc 9

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
B getIterator() 0 24 8
1
<?php
2
namespace nebula\component\filesystem;
3
4
use Iterator;
5
use IteratorAggregate;
6
7
/**
8
 * 逐行读文件迭代器
9
 *
10
 */
11
class ReadLineIterator implements IteratorAggregate
12
{
13
    protected $path;
14
    protected $bufferSize;
15
    protected $offset;
16
17
    /**
18
     * 构建迭代器
19
     *
20
     * @param string $path 路径
21
     * @param integer|null $offset 起始偏移
22
     * @param integer $bufferSize
23
     */
24
    public function __construct(string $path, ?int $offset = 0, int $bufferSize = 1024)
25
    {
26
        $this->path = $path;
27
        $this->offset = $offset;
28
        $this->bufferSize = $bufferSize;
29
    }
30
31
    /**
32
     * 获取迭代器
33
     *
34
     * @return Iterator
35
     */
36
    public function getIterator():Iterator
37
    {
38
        if (file_exists($this->path) && ($fp = fopen($this->path, 'rb')) !== false) {
39
            $offset = $this->offset ?: 0;
40
            while (!feof($fp)) {
41
                fseek($fp, $offset);
42
                $content = fread($fp, $this->bufferSize);
43
                $content.=(feof($fp))? "\n":'';
44
                $size = strpos($content, "\n");
45
                $offset += $size;
46
                if ($content[$size - 1] === "\r") {
47
                    $content = substr($content, 0, $size -1);
48
                } else {
49
                    $content = substr($content, 0, $size);
50
                }
51
                if (is_null($this->offset)) {
52
                    yield $content;
53
                } else {
54
                    yield $offset => $content;
55
                }
56
            }
57
            fclose($fp);
58
        } else {
59
            throw new \Exception(sprintf('readline iterator: file note exists %s', $this->path));
60
        }
61
    }
62
}
63