В строго соответствующем коде C вы не можете.Стандарт C очень плохо понимает, что такое файл.Даже получить размер файла невозможно с помощью строго соответствующего C, кроме как открыть файл в двоичном режиме и прочитать его побитово и посчитать. * Просто не существует способа указать, каким будет файлхранится в соответствующем коде C.
Таким образом, вы можете использовать системные методы.
POSIX предоставляет posix_fallocate()
функцию :
ОБОЗНАЧЕНИЕ
#include <fcntl.h>
int posix_fallocate(int fd, off_t offset, off_t len); [Option End]
ОПИСАНИЕ
Функция posix_fallocate()
должна гарантировать, что любое необходимое хранилище для обычных данных файла начинается со смещенияи продолжение для длинных байтов выделяется на носителе хранения файловой системы.Если posix_fallocate()
успешно возвращается, последующие записи в указанный файл не должны завершаться сбоем из-за недостатка свободного места на носителе файловой системы.
Обратите внимание, однако, что пути нетчтобы гарантировать, как базовая система гарантирует, что последующие записи в файл будут успешными.
Это все еще "определяется реализацией", если файловое пространство будет смежным.Вероятно, более вероятно, что зарезервированное пространство будет выделено файловой системой как непрерывный блок, но нет абсолютно никаких гарантий.
Linux предоставляет fallocate()
функция :
SYNOPSIS
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <fcntl.h>
int fallocate(int fd, int mode, off_t offset, off_t len);
ОПИСАНИЕ
Это непереносимый системный вызов для Linux.Для портативного, определенного POSIX.1 метода обеспечения выделения места для файла см. posix_fallocate(3)
.
fallocate()
, позволяющий вызывающей стороне напрямую манипулировать выделенным дисковым пространством для файла, на который ссылаетсяfd для диапазона байтов, начинающегося со смещения и продолжающегося для длинных байтов.
...
Обратите внимание, как это явно указано как "непереносимый, специфичный для Linux".
И даже непереносимая специфичная для Linux функция fallocate()
не дает абсолютно никаких гарантий относительно непрерывного размещения файлов.
Поскольку фактическое выделение пространства является зависимой от файловой системы операцией.
XFS, например, пытается предварительно выделить файловое пространство , чтобы данные хранились в смежных блоках.
Но опять же, без гарантий.
Только высокопроизводительные файловые системытакие как Oracle HSM (Sun SAM-QFS) и IBM Spectrum Scale (первоначально называвшийся GPFS), обеспечивают уровень контроля, необходимый для того, чтобы у вас даже был реальный шанс получить продолжениеиспользуя выделение пространства в файле.
Например, функция Oracle HSM / QFS setfa()
:
NAME
sam_setfa - Sets attributes on a file or directory
ОПИСАНИЕ
cc [ flag ... ] file ... -L/opt/SUNWsamfs/lib -lsam [library ... ]
#include "/opt/SUNWsamfs/include/lib.h"
int sam_setfa(const char *path, const char *ops);
ОПИСАНИЕ
sam_setfa() sets attributes on a file or directory using a
SAM-QFS system call. path is the file on which to set the
attributes. ops is the character string of options, for
example: "ds1". Individual options are described below.
ОПЦИИ
A n Specifies the number of bytes to be allocated ahead of
a write to the file. The n must be an integer and must
be greater than or equal to one kilobyte and less than
4 terabytes. The n is rounded down to units of kilo-
bytes. This option is only valid for a regular file.
This option should be used when writing large files
where more sequential allocation is desired. Note,
when the file is closed the blocks are reset to the
size of the file.
...
l n Specifies the number of bytes to be preallocated to the
file. The n must be an integer. This option can only
be applied to a regular file. If an I/O event attempts
to extend a file preallocated with the L option, the
caller receives an ENXIO error. The l option allocates
using extent allocation. This means striping is not
supported and the file is allocated on 1 disk device or
1 striped group. The L and l options are mutually
exclusive. If the file has existing disk blocks, this
option is changed to the L option.
L n Specifies the number of bytes to be preallocated to the
file. The n must be an integer. This option is only
valid for a regular file. The L option allocates using
standard allocation. This means striping is supported.
This also means the file can be extended. The L and l
options are mutually exclusive.
...
Даже в высокопроизводительных, сложных, проприетарных файловых системах, которые предлагают множество опций для того, как файлы хранятся на диске, невозможно гарантировать непрерывное выделение пространства внутри файла.
Это одна из причин, по которой высокопроизводительная база данных может использовать необработанные устройства для хранения данных - это действительно единственный способ гарантировать непрерывное хранение данных.
* Нет, fseek()
/ ftell()
не строго соответствует Cкод.fseek( fp, 0, SEEK_END )
- это явно неопределенное поведение в двоичном потоке , и ftell()
нельзя использовать для получения количества байтов в текстовом файле .