set_file_buffer() 函数自 PHP 5.4.0 起已废弃,并在 PHP 7.0.0 中被移除。现在推荐使用功能相同的 stream_set_write_buffer() 函数。本页面保留了该函数的文档以供历史参考。
set_file_buffer() 函数用于设置已打开文件的缓冲区大小。它允许控制写入操作在文件句柄上的缓冲行为。
文件缓冲可以减少实际的磁盘写入次数,从而提高文件写入性能。较小的缓冲区意味着更频繁的磁盘写入,但数据更及时;较大的缓冲区可以减少磁盘I/O,但可能增加数据丢失的风险。
stream_set_write_buffer() 代替。在 PHP 7.0.0 中,此函数已被完全移除。
set_file_buffer ( resource $stream , int $buffer ) : int
参数说明:
$stream:文件指针资源,由 fopen() 创建(必需)$buffer:缓冲区大小,以字节为单位(必需)现代替代语法:
stream_set_write_buffer ( resource $stream , int $buffer ) : int
| 参数 | 描述 |
|---|---|
stream |
文件指针资源。必需参数。
|
buffer |
缓冲区大小(字节)。必需参数。
|
stream_set_write_buffer() 的行为相同。
以下示例仅用于历史参考,在现代PHP版本中应使用 stream_set_write_buffer()。
为文件写入设置8KB的缓冲区:
<?php
// 打开文件用于写入
$file = fopen("output.log", "w");
if ($file) {
// 设置8KB缓冲区
$result = set_file_buffer($file, 8192);
if ($result === 0) {
echo "缓冲区设置成功(8KB)";
} else {
echo "缓冲区设置失败";
}
// 写入数据
fwrite($file, "这是一些日志数据\n");
fwrite($file, "这是更多日志数据\n");
// 手动刷新缓冲区(可选)
fflush($file);
fclose($file);
} else {
echo "无法打开文件";
}
?>
设置无缓冲写入(立即写入磁盘):
<?php
$file = fopen("critical.log", "a");
if ($file) {
// 禁用缓冲区(立即写入)
set_file_buffer($file, 0);
// 写入关键数据,确保立即保存
fwrite($file, date('Y-m-d H:i:s') . " - 系统启动\n");
fwrite($file, date('Y-m-d H:i:s') . " - 用户登录\n");
// 由于缓冲区为0,不需要调用fflush()
fclose($file);
echo "关键日志已立即写入磁盘";
}
?>
比较不同缓冲区大小的性能:
<?php
function test_buffer_performance($bufferSize, $iterations = 10000) {
$filename = "test_perf_" . $bufferSize . ".txt";
$file = fopen($filename, "w");
if (!$file) return false;
// 设置缓冲区
set_file_buffer($file, $bufferSize);
$start = microtime(true);
// 多次写入
for ($i = 0; $i < $iterations; $i++) {
fwrite($file, "Line $i: This is test data for buffer size $bufferSize\n");
}
// 确保所有数据写入磁盘
fflush($file);
fclose($file);
$end = microtime(true);
$duration = $end - $start;
// 清理测试文件
unlink($filename);
return $duration;
}
echo "<h4>不同缓冲区大小性能测试:</h4>";
$bufferSizes = [0, 1024, 4096, 8192, 16384, 32768];
$iterations = 5000;
foreach ($bufferSizes as $size) {
$time = test_buffer_performance($size, $iterations);
if ($time !== false) {
echo "缓冲区大小 " . number_format($size) . " 字节: " .
round($time, 4) . " 秒<br>";
}
}
?>
在现代PHP中使用 stream_set_write_buffer():
<?php
// 现代PHP写法(PHP 5.4.0+)
$file = fopen("data.txt", "w");
if ($file) {
// 使用stream_set_write_buffer替代
$result = stream_set_write_buffer($file, 16384); // 16KB缓冲区
if ($result === 0) {
echo "缓冲区设置成功(16KB)";
} else {
echo "缓冲区设置失败,错误代码: $result";
}
// 写入数据
$data = str_repeat("This is test data. ", 100);
fwrite($file, $data);
// 可以手动刷新
fflush($file);
fclose($file);
}
?>
这是 set_file_buffer() 的直接替代品,语法和功能完全相同:
<?php
// 打开文件
$file = fopen("output.txt", "w");
// 设置缓冲区(替代set_file_buffer)
$result = stream_set_write_buffer($file, 8192);
if ($result === 0) {
echo "缓冲区设置成功";
} else {
echo "缓冲区设置失败";
}
fclose($file);
?>
设置流操作的块大小,影响读取和写入:
<?php
$file = fopen("largefile.dat", "w");
// 设置块大小为8KB
$oldChunkSize = stream_set_chunk_size($file, 8192);
echo "之前的块大小: $oldChunkSize 字节<br>";
fwrite($file, str_repeat("x", 100000)); // 写入100KB数据
fclose($file);
?>
在打开文件时通过上下文设置缓冲区:
<?php
// 创建流上下文
$context = stream_context_create([
'http' => [
'buffer' => 8192 // 设置缓冲区大小
]
]);
// 使用上下文打开文件(注意:这只对某些包装器有效)
$file = fopen('http://example.com/data', 'r', false, $context);
?>
应用程序写入 → [缓冲区] → 磁盘写入
无缓冲 (buffer=0):
App: "Data1" → Disk: "Data1"
App: "Data2" → Disk: "Data2"
App: "Data3" → Disk: "Data3"
(每次写入都立即进行磁盘操作)
有缓冲 (buffer=4096):
App: "Data1" → [Buffer]
App: "Data2" → [Buffer]
App: "Data3" → [Buffer]
(缓冲区满或调用fflush()时)
[Buffer] → Disk: "Data1Data2Data3"
(减少磁盘I/O次数)
<?php
// 演示缓冲区的行为
function demonstrate_buffer($bufferSize) {
$filename = "demo_buffer_{$bufferSize}.txt";
$file = fopen($filename, "w");
// 设置缓冲区
stream_set_write_buffer($file, $bufferSize);
echo "缓冲区大小: " . number_format($bufferSize) . " 字节<br>";
echo "写入10次数据,每次1024字节<br>";
$start = microtime(true);
for ($i = 1; $i <= 10; $i++) {
$data = str_repeat("X", 1024); // 1KB数据
fwrite($file, $data);
echo "写入第 {$i} 次: " . number_format($i * 1024) . " 字节已缓冲<br>";
// 如果缓冲区大小小于写入数据,可能会触发磁盘写入
if ($bufferSize > 0 && ($i * 1024) >= $bufferSize) {
echo " → 缓冲区已满或超过,数据可能已写入磁盘<br>";
}
}
fflush($file);
fclose($file);
$end = microtime(true);
echo "总耗时: " . round(($end - $start) * 1000, 2) . " 毫秒<br><br>";
// 清理
unlink($filename);
}
demonstrate_buffer(0); // 无缓冲
demonstrate_buffer(2048); // 2KB缓冲区
demonstrate_buffer(8192); // 8KB缓冲区
?>
set_file_buffer() 已废弃,应使用 stream_set_write_buffer()fflush() 手动刷新缓冲区到磁盘fclose() 会自动刷新缓冲区| 应用场景 | 推荐缓冲区大小 | 说明 |
|---|---|---|
| 关键日志/事务数据 | 0(无缓冲) | 确保数据立即持久化,防止丢失 |
| 一般文件写入 | 4-16KB | 平衡性能和可靠性 |
| 批量数据处理 | 64-256KB | 最大化吞吐量,减少I/O操作 |
| 临时文件/缓存 | 8-32KB | 中等性能,可接受一定数据丢失风险 |
fflush()