Ftruncate: примеры (PHP)
ftruncate(resource $stream, int $size): boolОписание функции ftruncate
Функция ftruncate() в PHP используется для обрезки или увеличения размера открытого файлового дескриптора до указанной длины. Эта функция работает с уже открытым файловым ресурсом, полученным через fopen().
Чаще всего ее применяют для очистки содержимого файла (установка длины в 0), сокращения размера лог-файлов, подготовки файла для последующей записи с определенной позиции или изменения размера файла без его повторного открытия.
ftruncate(resource $stream, int $size): bool
- $stream (ресурс) – Файловый указатель, полученный из функции fopen(). Должен быть открыт для записи.
- $size (целое число) – Новая длина файла в байтах. Если значение меньше текущего размера файла, данные после позиции $size удаляются. Если значение больше, файл расширяется нулевыми байтами (\x00).
- Возвращаемое значение: Функция возвращает true в случае успеха или false при неудаче.
Примеры использования
<?php
$handle = fopen('data.txt', 'r+');
if (ftruncate($handle, 0)) {
echo 'Файл очищен';
} else {
echo 'Ошибка обрезки';
}
fclose($handle);Файл очищен
<?php
$handle = fopen('empty.txt', 'r+');
ftruncate($handle, 1024); // Файл размером 1 КБ
$stat = fstat($handle);
echo 'Размер файла: ' . $stat['size'] . ' байт';
fclose($handle);Размер файла: 1024 байт
<?php
$handle = fopen('log.txt', 'r+');
// Оставляем только последние 100 байт файла
fseek($handle, -100, SEEK_END);
$pos = ftell($handle);
ftruncate($handle, $pos);
fclose($handle);
echo 'Оставлено 100 последних байт';
Оставлено 100 последних байт
Похожие функции в PHP
Позволяет записать данные в файл, при использовании флага FILE_APPEND предотвращает перезапись. Более проста для полной замены содержимого, но не подходит для точной обрезки открытого файлового дескриптора.
Устанавливает буферизацию для файлового потока. Может влиять на производительность операций записи, но не управляет размером файла напрямую.
Функцию ftruncate() предпочтительно использовать при работе с уже открытыми файловыми дескрипторами, особенно при необходимости частичной обрезки или расширения файла. Для простой очистки файла подходит file_put_contents() с пустой строкой. При работе с очень большими файлами ftruncate эффективнее, так как не требует загрузки файла в память.
Аналоги в других языках
Метод файлового объекта, работающий аналогично. Может вызываться без аргумента для обрезки до текущей позиции.
with open('data.txt', 'r+') as f:
f.truncate(100) # Обрезать до 100 байт
f.truncate() # Обрезать до текущей позицииАсинхронная функция с callback или promise-интерфейсом. В отличие от синхронной PHP-версии, требует обработки асинхронности.
const fs = require('fs/promises');
async function truncateFile() {
const handle = await fs.open('data.txt', 'r+');
await handle.truncate(512);
await handle.close();
}Оператор SQL для полной очистки таблицы. Не является прямым аналогом, так как работает с таблицами базы данных, а не с файлами файловой системы.
TRUNCATE TABLE logs; -- Быстро удаляет все записи из таблицыPHP функция работает синхронно и с файловыми дескрипторами. Python и Node.js предлагают аналогичные методы, но в Node.js они асинхронны по умолчанию. В языках без низкоуровневого доступа к файлам обычно используют перезапись всего файла.
Типичные ошибки
<?php
$handle = fopen('readonly.txt', 'r');
if (ftruncate($handle, 0)) {
echo 'Успех';
} else {
echo 'Ошибка: файл открыт не для записи';
}
fclose($handle);Ошибка: файл открыт не для записи
<?php
$result = @ftruncate('not_a_resource', 100);
var_dump($result);
if ($result === false) {
echo 'Первый аргумент должен быть ресурсом';
}bool(false) Первый аргумент должен быть ресурсом
<?php
$handle = fopen('test.txt', 'r+');
$result = ftruncate($handle, -10);
var_dump($result);
fclose($handle);bool(false)
<?php
$handle = fopen('test.txt', 'r+');
fclose($handle);
$result = @ftruncate($handle, 0);
var_dump($result);Warning: ftruncate(): supplied resource is not a valid stream resource bool(false)
Изменения в версиях PHP
Тип параметра $size изменен с int на int|float, но нецелочисленные значения округляются в меньшую сторону. Внутреннее преобразование стало более строгим.
В PHP 4.3.3 добавлена поддержка обрезки через сетевые потоки, если используемый протокол это позволяет. В ранних версиях функция могла работать только с локальными файлами.
Поведение функции остается стабильным на протяжении многих версий. Основное внимание при обновлении следует уделять типам передаваемых аргументов, так как в PHP 8 включен строгий режим типов.
Расширенные примеры
Пример сохраняет первые 512 байт файла (например, заголовок), удаляя остальное содержимое.
<?php
$filename = 'data.bin';
$handle = fopen($filename, 'r+');
ftruncate($handle, 512);
fflush($handle); // Сброс буферов на диск
fclose($handle);
echo 'Файл обрезан до 512 байт';
Файл обрезан до 512 байт
Создание и заполнение файла нулевыми байтами заданного размера.
<?php
$handle = fopen('placeholder.dat', 'w');
ftruncate($handle, 5 * 1024 * 1024); // 5 MB
fclose($handle);
echo 'Создан файл размером 5 МБ';
Создан файл размером 5 МБ
<?php
$logFile = 'application.log';
$maxSize = 1024 * 1024; // 1 MB
$handle = fopen($logFile, 'r+');
if (filesize($logFile) > $maxSize) {
// Оставляем последние 100 КБ лога
fseek($handle, -102400, SEEK_END);
$content = fread($handle, 102400);
ftruncate($handle, 0);
rewind($handle);
fwrite($handle, $content);
ftruncate($handle, strlen($content));
echo 'Лог-файл очищен';
} else {
echo 'Размер файла в норме';
}
fclose($handle);Лог-файл очищен
<?php
$tempHandle = tmpfile(); // Создается временный файл
fwrite($tempHandle, 'Временные данные');
ftruncate($tempHandle, 0); // Быстрая очистка
fwrite($tempHandle, 'Новые данные');
rewind($tempHandle);
echo fread($tempHandle, 1024);
// Файл автоматически удалится при закрытииНовые данные
<?php
function safeTruncate($handle, $size) {
if (!is_resource($handle)) {
throw new InvalidArgumentException('Ожидается ресурс файла');
}
if (!ftruncate($handle, $size)) {
throw new RuntimeException('Не удалось обрезать файл');
}
return true;
}
try {
$handle = fopen('test.txt', 'r+');
safeTruncate($handle, 100);
echo 'Операция успешна';
} catch (Exception $e) {
echo 'Ошибка: ' . $e->getMessage();
}Операция успешна