Ftruncate: примеры (PHP)

Использование 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 предотвращает перезапись. Более проста для полной замены содержимого, но не подходит для точной обрезки открытого файлового дескриптора.

stream_set_write_buffer()

Устанавливает буферизацию для файлового потока. Может влиять на производительность операций записи, но не управляет размером файла напрямую.

Рекомендации по выбору

Функцию ftruncate() предпочтительно использовать при работе с уже открытыми файловыми дескрипторами, особенно при необходимости частичной обрезки или расширения файла. Для простой очистки файла подходит file_put_contents() с пустой строкой. При работе с очень большими файлами ftruncate эффективнее, так как не требует загрузки файла в память.

Аналоги в других языках

Python: truncate()

Метод файлового объекта, работающий аналогично. Может вызываться без аргумента для обрезки до текущей позиции.

with open('data.txt', 'r+') as f:
    f.truncate(100)  # Обрезать до 100 байт
    f.truncate()     # Обрезать до текущей позиции
JavaScript (Node.js): fs.ftruncate()

Асинхронная функция с 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();
}
MySQL: TRUNCATE TABLE

Оператор 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

PHP 8.0.0

Тип параметра $size изменен с int на int|float, но нецелочисленные значения округляются в меньшую сторону. Внутреннее преобразование стало более строгим.

Исторические изменения

В PHP 4.3.3 добавлена поддержка обрезки через сетевые потоки, если используемый протокол это позволяет. В ранних версиях функция могла работать только с локальными файлами.

Совместимость

Поведение функции остается стабильным на протяжении многих версий. Основное внимание при обновлении следует уделять типам передаваемых аргументов, так как в PHP 8 включен строгий режим типов.

Расширенные примеры

Обрезка с сохранением заголовка

Пример сохраняет первые 512 байт файла (например, заголовок), удаляя остальное содержимое.

Пример php
<?php
$filename = 'data.bin';
$handle = fopen($filename, 'r+');
ftruncate($handle, 512);
fflush($handle); // Сброс буферов на диск
fclose($handle);
echo 'Файл обрезан до 512 байт';
Файл обрезан до 512 байт
Создание файла фиксированного размера

Создание и заполнение файла нулевыми байтами заданного размера.

Пример php
<?php
$handle = fopen('placeholder.dat', 'w');
ftruncate($handle, 5 * 1024 * 1024); // 5 MB
fclose($handle);
echo 'Создан файл размером 5 МБ';
Создан файл размером 5 МБ
Очистка лог-файла при превышении размера
Пример php
<?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
<?php
$tempHandle = tmpfile(); // Создается временный файл
fwrite($tempHandle, 'Временные данные');
ftruncate($tempHandle, 0); // Быстрая очистка
fwrite($tempHandle, 'Новые данные');
rewind($tempHandle);
echo fread($tempHandle, 1024);
// Файл автоматически удалится при закрытии
Новые данные
Обработка ошибок через исключения
Пример php
<?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();
}
Операция успешна

PHP ftruncate function comments

En
Ftruncate Truncates a file to a given length