Fread: примеры (PHP)
fread(resource $stream, int $length): string|falseФункция fread в языке PHP предназначена для чтения данных из файла или другого потока в бинарно-безопасном режиме. Её применение актуально при работе с бинарными файлами, такими как изображения, или когда требуется контролировать размер считываемого блока данных, например, при чтении больших файлов частями.
Сигнатура функции: fread(resource $stream, int $length): string|false.
Функция принимает два аргумента:
- $stream (resource) — ресурс (указатель) файла, полученный с помощью функций
fopen(),fsockopen()илиpopen(). Этот ресурс должен быть открыт для чтения. - $length (int) — максимальное количество байт для чтения. Чтение останавливается после прочтения указанного количества байт, при достижении конца файла (EOF) или в случае ошибки (например, при разрыве сетевого соединения для сокетов).
Функция возвращает прочитанную строку или false в случае ошибки.
<?php
$handle = fopen('example.txt', 'rb');
if ($handle) {
$content = fread($handle, filesize('example.txt'));
fclose($handle);
echo $content;
}
?>
Содержимое файла example.txt
<?php
$handle = fopen('large_file.bin', 'rb');
if ($handle) {
while (!feof($handle)) {
$chunk = fread($handle, 8192); // Чтение блоками по 8 КБ
// Обработка блока данных $chunk
echo strlen($chunk) . ' байт прочитано\n';
}
fclose($handle);
}
?>
8192 байт прочитано 8192 байт прочитано ... 1200 байт прочитано (последний блок)
<?php
$fp = fsockopen('example.com', 80, $errno, $errstr, 30);
if ($fp) {
$request = "GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n";
fwrite($fp, $request);
$responseHeader = '';
// Чтение ответа построчно до пустой строки (конец заголовков)
while (!feof($fp)) {
$line = fread($fp, 1024);
$responseHeader .= $line;
if (strpos($responseHeader, "\r\n\r\n") !== false) {
break;
}
}
echo $responseHeader;
fclose($fp);
}
?>
HTTP/1.1 200 OK Content-Type: text/html; charset=UTF-8 ... (остальные заголовки)
- file_get_contents() — считывает весь файл в строку. Используется для простого чтения небольших файлов целиком. Не требует явного открытия и закрытия файла.
$content = file_get_contents('file.txt'); - fgets() — читает файл построчно. Удобна для обработки текстовых файлов, где важны границы строк.
while ($line = fgets($handle)) { echo $line; } - stream_get_contents() — считывает оставшуюся часть потока в строку. Может быть аналогом
fread($handle, filesize(...)), но работает с любым потоком и позволяет указывать максимальную длину и смещение.$content = stream_get_contents($handle); - fgetc() — читает один символ из файла. Используется для посимвольной обработки.
Выбор функции зависит от задачи: fread применяется для бинарно-безопасного чтения данных заданного размера, особенно для бинарных файлов или потоковых данных. file_get_contents предпочтительнее для простого чтения текстовых файлов целиком. fgets лучше подходит для построчного анализа.
Fread в Python
Метод read(size) у файловых объектов. Аналогичен fread, но интегрирован в объект файла.
with open('example.txt', 'rb') as f:
data = f.read(1024) # Чтение 1024 байт
print(data)
b'Содержимое файла...'
Модуль fs предлагает несколько методов: fs.readSync(fd, buffer, offset, length, position) для синхронного чтения в буфер и fs.readFile для чтения всего файла.
const fs = require('fs');
const fd = fs.openSync('file.txt', 'r');
const buffer = Buffer.alloc(1024);
const bytesRead = fs.readSync(fd, buffer, 0, 1024, null);
console.log(buffer.toString('utf8', 0, bytesRead));
fs.closeSync(fd);
Содержимое файла...
Fread в MySQL
Функция LOAD_FILE() считывает весь файл и возвращает его содержимое как строку. Работает на уровне СУБД, а не в языке приложения.
SELECT LOAD_FILE('/tmp/data.txt') AS file_content;
+-------------------+ | file_content | +-------------------+ | Текст из файла | +-------------------+
Основное отличие от PHP в том, что в Python и JS работа с файлами чаще объектно-ориентированная, а fread в PHP использует ресурсы. Кроме того, в PHP больше акцента на бинарную безопасность по умолчанию.
<?php
$data = fread(false, 10); // Предупреждение и возврат false
?>
Warning: fread() expects parameter 1 to be resource, bool given
<?php
$handle = fopen('/tmp', 'r');
$data = fread($handle, 100); // Чтение невозможно
?>
Warning: fread(): read of 8192 bytes failed with errno=21 Is a directory
При повторном вызове fread после достижения EOF функция вернет пустую строку, что можно ошибочно принять за данные.
<?php
$handle = fopen('empty.txt', 'r');
$content = fread($handle, 10);
var_dump($content);
?>
string(0) ""
Попытка вывести бинарные данные (например, изображение) как строку может привести к краху вывода или искажению.
<?php
$handle = fopen('image.jpg', 'rb');
$header = fread($handle, 100);
echo $header; // Может вывести "мусор"
?>В PHP 8.0 и 8.1 значительных изменений в поведении функции fread не было. Однако, общий контекст типизации в PHP становится строже. Например, передача аргумента неверного типа теперь вызывает TypeError вместо предупреждения. В PHP 8.1.0 появилась возможность использовать читаемые ресурсы (stream resources) в качестве ключей в массивах, что косвенно может влиять на код, манипулирующий множеством потоков.
Важно отметить, что в PHP 8 улучшена обработка ошибок ввода-вывода, что делает работу с файловой системой более предсказуемой.
<?php
$fp = fopen('image.bmp', 'rb');
if ($fp) {
// Чтение заголовка файла BMP (14 байт)
$fileHeader = fread($fp, 14);
// Проверка сигнатуры 'BM'
if (substr($fileHeader, 0, 2) === 'BM') {
echo 'Это файл BMP.\n';
// Чтение размера файла из заголовка (байты 2-6)
$fileSize = unpack('V', substr($fileHeader, 2, 4))[1];
echo 'Размер файла: ' . $fileSize . ' байт\n';
}
fclose($fp);
}
?>
Это файл BMP. Размер файла: 1275624 байт
<?php
function readFileChunked($filePath, $chunkSize = 8192, $delay = 100000) {
$handle = fopen($filePath, 'rb');
if ($handle) {
while (!feof($handle)) {
echo fread($handle, $chunkSize);
flush();
usleep($delay); // Искусственная задержка для ограничения скорости
}
fclose($handle);
return true;
}
return false;
}
// readFileChunked('large_video.mp4', 65536, 50000);
?>
<?php
$fp = fopen('http://example.com/large', 'r');
if ($fp) {
// Отключаем буферизацию чтения
stream_set_read_buffer($fp, 0);
$data = fread($fp, 1024); // Будет читать непосредственно из сетевого потока
// ...
fclose($fp);
}
?>
<?php
$handle = popen('ls -la /tmp', 'r');
if ($handle) {
echo '<pre>';
while (!feof($handle)) {
$output = fread($handle, 4096);
echo htmlspecialchars($output);
}
echo '</pre>';
pclose($handle);
}
?>
total 24 drwxrwxrwt 8 root root 4096 Dec 1 10:00 . drwxr-xr-x 20 root root 4096 Nov 15 08:30 .. ...
<?php
$filename = 'user_data.json';
$handle = @fopen($filename, 'rb');
if ($handle === false) {
die('Не удалось открыть файл');
}
// Получаем размер безопасно
$fileSize = @filesize($filename);
if ($fileSize === false || $fileSize > 10 * 1024 * 1024) {
die('Файл слишком большой или недоступен');
}
// Читаем с контролем размера
$content = $fileSize > 0 ? fread($handle, $fileSize) : '';
fclose($handle);
$data = json_decode($content, true);
?>