ZetCode

PHP rewind 函数

最后修改于 2025 年 4 月 3 日

PHP 的 rewind 函数将文件指针重置到文件的开头。当您需要多次读取文件或在操作后重置位置时,它至关重要。

基本定义

rewind 函数将文件指针的文件位置指示器设置为文件流的开头。它接受一个参数:文件指针资源。

语法:rewind(resource $stream): bool。该函数在成功时返回 true,失败时返回 false。它适用于使用 fopen 打开的文件。

基本 rewind 示例

这展示了使用 rewind 重置文件指针的最简单用法。

basic_rewind.php
<?php

declare(strict_types=1);

$file = fopen('example.txt', 'r');
fread($file, 10); // Read first 10 bytes
rewind($file); // Reset to beginning
$content = fread($file, filesize('example.txt'));

echo $content;
fclose($file);

这段代码读取 10 个字节,倒回到开始,然后读取整个文件。如果没有 rewind,第二次读取将从第 10 个字节开始。使用后务必关闭文件。

写入后使用 rewind

在写入后使用 rewind 可以立即读取已写入的内容。

rewind_after_write.php
<?php

declare(strict_types=1);

$file = fopen('temp.txt', 'w+');
fwrite($file, "Hello World");
rewind($file);
$content = fread($file, filesize('temp.txt'));

echo $content; // Outputs: Hello World
fclose($file);
unlink('temp.txt');

我们写入一个文件,倒回到开始,然后读取我们写入的内容。'w+' 模式允许读写操作。应清理临时文件。

使用 CSV 文件进行 rewind

在不重新打开的情况下,rewind 有助于多次处理 CSV 文件。

rewind_csv.php
<?php

declare(strict_types=1);

$file = fopen('data.csv', 'r');

// First pass: count lines
$lineCount = 0;
while (!feof($file)) {
    fgetcsv($file);
    $lineCount++;
}
rewind($file);

// Second pass: process data
while (($data = fgetcsv($file)) !== false) {
    print_r($data);
}

fclose($file);

这段代码计算行数,倒回,然后处理 CSV 数据。如果没有 rewind,第二个循环将不会运行,因为指针将位于 EOF。CSV 处理通常需要多次遍历。

在大文件处理中使用 rewind

Rewind 能够有效地分块处理大文件。

large_file.php
<?php

declare(strict_types=1);

$file = fopen('large.log', 'r');
$chunkSize = 1024; // 1KB chunks

// Process first chunk
$chunk1 = fread($file, $chunkSize);
processChunk($chunk1);

rewind($file);

// Process first chunk again differently
$chunk1a = fread($file, $chunkSize);
processChunkDifferently($chunk1a);

fclose($file);

function processChunk(string $data): void {
    echo "Processing chunk: " . strlen($data) . " bytes\n";
}

function processChunkDifferently(string $data): void {
    echo "Alternative processing: " . strlen($data) . " bytes\n";
}

这演示了以多种方式处理相同块,而无需重新打开。对于大文件,Rewind 比关闭/重新打开更有效。分块处理可以节省大文件的内存。

使用自定义流包装器进行 rewind

Rewind 适用于实现 seek 功能的自定义流包装器。

stream_wrapper.php
<?php

declare(strict_types=1);

class MemoryStream {
    private $position = 0;
    private $data = '';

    public function stream_open(string $path, string $mode, int $options, ?string &$opened_path): bool {
        return true;
    }

    public function stream_read(int $count): string|false {
        $ret = substr($this->data, $this->position, $count);
        $this->position += strlen($ret);
        return $ret;
    }

    public function stream_write(string $data): int {
        $this->data .= $data;
        return strlen($data);
    }

    public function stream_tell(): int {
        return $this->position;
    }

    public function stream_eof(): bool {
        return $this->position >= strlen($this->data);
    }

    public function stream_seek(int $offset, int $whence): bool {
        switch ($whence) {
            case SEEK_SET:
                $this->position = $offset;
                return true;
            case SEEK_CUR:
                $this->position += $offset;
                return true;
            case SEEK_END:
                $this->position = strlen($this->data) + $offset;
                return true;
            default:
                return false;
        }
    }
}

stream_wrapper_register('memory', 'MemoryStream');

$file = fopen('memory://test', 'w+');
fwrite($file, "Test data");
rewind($file);
echo fread($file, 4); // Outputs: Test
fclose($file);

此自定义流包装器演示了 rewind 实现。 stream_seek 方法启用了 rewind 功能。自定义包装器必须实现 seek 以支持 rewind。

最佳实践

来源

PHP rewind 文档

本教程涵盖了 PHP 的 rewind 函数,并提供了实际示例,展示了它在不同文件处理场景中的用法。

作者

我叫 Jan Bodnar,是一位充满激情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直在撰写编程文章。到目前为止,我撰写了 1,400 多篇文章和 8 本电子书。我拥有超过十年的编程教学经验。

列出 所有 PHP 文件系统函数