Бинарные файлы

Использование fread() и fwrite()

Как только файл открыт для работы с двоичными данными, fread() и fwrite() соответственно могут читать и записывать информацию любого типа. Например, следующая программа записывает в дисковый файл данные типов double, int и long, a затем читает эти данные из того же файла

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

/* Запись несимвольных данных в дисковый файл
   и последующее их чтение.  */
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
  FILE *fp;
  double d = 12.23;
  int i = 101;
  long l = 123023L;

  if((fp=fopen("test", "wb+"))==NULL) {
    printf("Ошибка при открытии файла.\n");
    exit(1);
  }

  fwrite(&d, sizeof(double), 1, fp);
  fwrite(&i, sizeof(int), 1, fp);
  fwrite(&l, sizeof(long), 1, fp);

  rewind(fp);

  fread(&d, sizeof(double), 1, fp);
  fread(&i, sizeof(int), 1, fp);
  fread(&l, sizeof(long), 1, fp);

  printf("%f %d %ld", d, i, l);

  fclose(fp);

  return 0;
}

Как видно из этой программы, в качестве буфера можно использовать (и часто именно так и делают) просто память, в которой размещена переменная. В этой простой программе значения, возвращаемые функциями fread() и fwrite(), игнорируются. Однако на практике эти значения необходимо проверять, чтобы обнаружить ошибки.

Одним из самых полезных применений функций fread() и fwrite() является чтение и запись данных пользовательских типов, особенно структур. Например, если определена структура

struct struct_type {
  float balance;
  char name;
} cust;

то следующий оператор записывает содержимое cust в файл, на который указывает fp:

fwrite(&cust, sizeof(struct struct_type), 1, fp);

Возвращаемое значениеReturn Value

fread возвращает число фактически считанных полных элементов, которое может быть меньше, Если возникает ошибка или если конец файла обнаружен до достижения количестваобращений.fread returns the number of full items actually read, which may be less than count if an error occurs or if the end of the file is encountered before reaching count. Используйте функцию feof или ferror , чтобы отличать ошибку чтения от условия конца файла.Use the feof or ferror function to distinguish a read error from an end-of-file condition. Если параметр size или Count имеет значение 0, fread возвращает 0, а содержимое буфера не изменяется.If size or count is 0, fread returns 0 and the buffer contents are unchanged. Если Stream или buffer является пустым указателем, fread вызывает обработчик недопустимого параметра, как описано в разделе Проверка параметров.If stream or buffer is a null pointer, fread invokes the invalid parameter handler, as described in Parameter Validation. Если выполнение может быть продолжено, эта функция устанавливает еинвал и возвращает 0.If execution is allowed to continue, this function sets errno to EINVAL and returns 0.

Дополнительные сведения об этих кодах ошибок см. в разделе _досеррно, _код ошибки,_sys еррлист и _sys_Нерр .See _doserrno, errno, _sys_errlist, and _sys_nerr for more information on these error codes.

DESCRIPTION top

       The functionality described on this reference page is aligned with
       the ISO C standard. Any conflict between the requirements described
       here and the ISO C standard is unintentional. This volume of
       POSIX.1‐2008 defers to the ISO C standard.

       The fwrite() function shall write, from the array pointed to by ptr,
       up to nitems elements whose size is specified by size, to the stream
       pointed to by stream.  For each object, size calls shall be made to
       the fputc() function, taking the values (in order) from an array of
       unsigned char exactly overlaying the object. The file-position
       indicator for the stream (if defined) shall be advanced by the number
       of bytes successfully written. If an error occurs, the resulting
       value of the file-position indicator for the stream is unspecified.

       The last data modification and last file status change timestamps of
       the file shall be marked for update between the successful execution
       of fwrite() and the next successful completion of a call to fflush()
       or fclose() on the same stream, or a call to exit() or abort().

The fwrite() function

The fwrite() function is used to write records (sequence of bytes) to the file. A record may be an array or a structure.

Syntax of fwrite() function


              fwrite( ptr, int size, int n, FILE *fp );

The fwrite() function takes four arguments.
ptr : ptr is the reference of an array or a structure stored in memory.
size : size is the total number of bytes to be written.
n : n is number of times a record will be written.
FILE* : FILE* is a file where the records will be written in binary mode.

Example of fwrite() function


       #include<stdio.h>

       struct Student
       {
              int roll;
              char name;
              float marks;
       };

       void main()
       {
              FILE *fp;
              char ch;
              struct Student Stu;

              fp = fopen("Student.dat","w");            //Statement   1

              if(fp == NULL)
              {
                     printf("\nCan't open file or file doesn't exist.");
                     exit(0);
              }

              do
              {
                      printf("\nEnter Roll : ");
                      scanf("%d",&Stu.roll);

                      printf("Enter Name : ");
                      scanf("%s",Stu.name);

                      printf("Enter Marks : ");
                      scanf("%f",&Stu.marks);

                      fwrite(&Stu,sizeof(Stu),1,fp);

                      printf("\nDo you want to add another data (y/n) : ");
                      ch = getche();

              }while(ch=='y' || ch=='Y');

              printf("\nData written successfully...");

              fclose(fp);
       }

   Output :

              Enter Roll : 1
              Enter Name : Ashish
              Enter Marks : 78.53

              Do you want to add another data (y/n) : y

              Enter Roll : 2
              Enter Name : Kaushal
              Enter Marks : 72.65

              Do you want to add another data (y/n) : y

              Enter Roll : 3
              Enter Name : Vishwas
              Enter Marks : 82.65

              Do you want to add another data (y/n) : n

              Data written successfully...


NOTES top

       The types size_t and ssize_t are, respectively, unsigned and signed
       integer data types specified by POSIX.1.

       A successful return from write() does not make any guarantee that
       data has been committed to disk.  On some filesystems, including NFS,
       it does not even guarantee that space has successfully been reserved
       for the data.  In this case, some errors might be delayed until a
       future write(), fsync(2), or even close(2).  The only way to be sure
       is to call fsync(2) after you are done writing all your data.

       If a write() is interrupted by a signal handler before any bytes are
       written, then the call fails with the error EINTR; if it is
       interrupted after at least one byte has been written, the call
       succeeds, and returns the number of bytes written.

       On Linux, write() (and similar system calls) will transfer at most
       0x7ffff000 (2,147,479,552) bytes, returning the number of bytes
       actually transferred.  (This is true on both 32-bit and 64-bit
       systems.)

       An error return value while performing write() using direct I/O does
       not mean the entire write has failed. Partial data may be written and
       the data at the file offset on which the write() was attempted should
       be considered inconsistent.

EXAMPLES top

       The program below demonstrates the use of fread() by parsing /bin/sh
       ELF executable in binary mode and printing its magic and class:

           $ ./a.out
           ELF magic: 0x7f454c46
           Class: 0x02

   Program source

       #include <stdio.h>
       #include <stdlib.h>

       int
       main(void)
       {
           FILE *fp = fopen("/bin/sh", "rb");
           if (!fp) {
               perror("fopen");
               return EXIT_FAILURE;
           }

           unsigned char buffer;

           size_t ret =
               fread(buffer, sizeof(buffer) / sizeof(*buffer), sizeof(*buffer),
                     fp);
           if (ret != sizeof(*buffer)) {
               fprintf(stderr, "fread() failed: %zu\n", ret);
               exit(EXIT_FAILURE);
           }

           printf("ELF magic: %#04x%02x%02x%02x\n", buffer, buffer,
                  buffer, buffer);

           ret = fread(buffer, 1, 1, fp);
           if (ret != 1) {
               fprintf(stderr, "fread() failed: %zu\n", ret);
               exit(EXIT_FAILURE);
           }

           printf("Class: %#04x\n", buffer);

           fclose(fp);

           exit(EXIT_SUCCESS);
       }

ERRORS top

       EAGAIN The file descriptor fd refers to a file other than a socket
              and has been marked nonblocking (O_NONBLOCK), and the write
              would block.  See open(2) for further details on the
              O_NONBLOCK flag.

       EAGAIN or EWOULDBLOCK
              The file descriptor fd refers to a socket and has been marked
              nonblocking (O_NONBLOCK), and the write would block.
              POSIX.1-2001 allows either error to be returned for this case,
              and does not require these constants to have the same value,
              so a portable application should check for both possibilities.

       EBADF  fd is not a valid file descriptor or is not open for writing.

       EDESTADDRREQ
              fd refers to a datagram socket for which a peer address has
              not been set using connect(2).

       EDQUOT The user's quota of disk blocks on the filesystem containing
              the file referred to by fd has been exhausted.

       EFAULT buf is outside your accessible address space.

       EFBIG  An attempt was made to write a file that exceeds the
              implementation-defined maximum file size or the process's file
              size limit, or to write at a position past the maximum allowed
              offset.

       EINTR  The call was interrupted by a signal before any data was
              written; see signal(7).

       EINVAL fd is attached to an object which is unsuitable for writing;
              or the file was opened with the O_DIRECT flag, and either the
              address specified in buf, the value specified in count, or the
              file offset is not suitably aligned.

       EIO    A low-level I/O error occurred while modifying the inode.
              This error may relate to the write-back of data written by an
              earlier write(), which may have been issued to a different
              file descriptor on the same file.  Since Linux 4.13, errors
              from write-back come with a promise that they may be reported
              by subsequent.  write() requests, and will be reported by a
              subsequent fsync(2) (whether or not they were also reported by
              write()).  An alternate cause of EIO on networked filesystems
              is when an advisory lock had been taken out on the file
              descriptor and this lock has been lost.  See the Lost locks
              section of fcntl(2) for further details.

       ENOSPC The device containing the file referred to by fd has no room
              for the data.

       EPERM  The operation was prevented by a file seal; see fcntl(2).

       EPIPE  fd is connected to a pipe or socket whose reading end is
              closed.  When this happens the writing process will also
              receive a SIGPIPE signal.  (Thus, the write return value is
              seen only if the program catches, blocks or ignores this
              signal.)

       Other errors may occur, depending on the object connected to fd.

RemarksRemarks

Функция fread считывает до подсчета размера байтов из входного потока и сохраняет их в буфер.The fread function reads up to count items of size bytes from the input stream and stores them in buffer. Указатель файла, связанный с потоком (при его наличии), увеличивается на число фактически считанных байтов.The file pointer associated with stream (if there is one) is increased by the number of bytes actually read. Если данный поток открыт в текстовом режиме, то символы новой строки в стиле Windows преобразуются в символы новой строки в стиле UNIX.If the given stream is opened in text mode, Windows-style newlines are converted into Unix-style newlines. То есть пары символов возврата каретки и перевода строки (CRLF) заменяются символами перевода строки (LF).That is, carriage return-line feed (CRLF) pairs are replaced by single line feed (LF) characters. Замена не влияет на указатель файла или возвращаемое значение.The replacement has no effect on the file pointer or the return value. В случае ошибки позиция указателя файла будет неопределенной.The file-pointer position is indeterminate if an error occurs. Значение частично считанного элемента не может быть определено.The value of a partially read item cannot be determined.

При использовании в потоке текстового режима, если объем запрошенных данных (то есть число размеров * ) больше или равен размеру внутреннего буфера файла * (по умолчанию это 4096 байт, настраиваемый с помощью setvbuf), потоковые данные копируются непосредственно в предоставленный пользователем буфер, а в этом буфере выполняется преобразование новой строки.When used on a text mode stream, if the amount of data requested (that is, size * count) is greater than or equal to the internal FILE * buffer size (by default this is 4096 bytes, configurable by using setvbuf), stream data is copied directly into the user-provided buffer, and newline conversion is done in that buffer. Поскольку преобразованные данные могут быть короче, чем данные потока, скопированные в буфер, данные за буфер (где RETURN_VALUE является возвращаемым значением из fread) могут содержать непреобразованные данные из файла.Since the converted data may be shorter than the stream data copied into the buffer, data past buffer (where return_value is the return value from fread) may contain unconverted data from the file. По этой причине мы советуем использовать символьные данные, заканчивающиеся нулем, в буфере, если цель буфера — использовать в качестве строки в стиле C.For this reason, we recommend you null-terminate character data at buffer if the intent of the buffer is to act as a C-style string. Дополнительные сведения о влиянии текстового и двоичного режимов см. в разделе fopen .See fopen for details on the effects of text mode and binary mode.

Эта функция блокирует работу других потоков.This function locks out other threads. Если требуется версия без блокировки, используйте _fread_nolock.If you need a non-locking version, use _fread_nolock.

По умолчанию глобальное состояние этой функции ограничивается приложением.By default, this function’s global state is scoped to the application. Чтобы изменить это, см. раздел глобальное состояние в CRT.To change this, see Global state in the CRT.

The fread() function

The fread() function is used to read bytes form the file.

Syntax of fread() function


              fread( ptr, int size, int n, FILE *fp );

The fread() function takes four arguments.
ptr : ptr is the reference of an array or a structure where data will be stored after reading.
size : size is the total number of bytes to be read from file.
n : n is number of times a record will be read.
FILE* : FILE* is a file where the records will be read.

Example of fread() function


       #include<stdio.h>

       struct Student
       {
              int roll;
              char name;
              float marks;
       };

       void main()
       {
              FILE *fp;
              char ch;
              struct Student Stu;

              fp = fopen("Student.dat","r");            //Statement   1

              if(fp == NULL)
              {
                     printf("\nCan't open file or file doesn't exist.");
                     exit(0);
              }

              printf("\n\tRoll\tName\tMarks\n");

              while(fread(&Stu,sizeof(Stu),1,fp)>0)
                  printf("\n\t%d\t%s\t%f",Stu.roll,Stu.name,Stu.marks);

              fclose(fp);
       }

   Output :

              Roll     Name       Marks
              1         Ashish      78.53
              2         Kaushal    72.65
              3         Vishwas    82.65

Related topics

  • Write a program to count total number of blank spaces in a file.
  • Write a program to count total number of consonant in a file.
  • Write a program to copy one file to another.
  • Write a program to copy all even numbers from one file to another.
  • Write a menu driven program to add, display, search, update and delete the student record.

Advertisement

Возвращаемое значениеReturn Value

fread_s возвращает количество (целых) элементов, которые были считаны в буфер, что может быть меньше числа , если ошибка чтения или конец файла обнаружены до достижения количества .fread_s returns the number of (whole) items that were read into the buffer, which may be less than count if a read error or the end of the file is encountered before count is reached. Используйте функцию feof или ferror , чтобы отличить ошибку от условия конца файла.Use the feof or ferror function to distinguish an error from an end-of-file condition. Если параметр size или Count имеет значение 0, fread_s возвращает 0, а содержимое буфера не изменяется.If size or count is 0, fread_s returns 0 and the buffer contents are unchanged. Если Stream или buffer является пустым указателем, fread_s вызывает обработчик недопустимого параметра, как описано в разделе Проверка параметров.If stream or buffer is a null pointer, fread_s invokes the invalid parameter handler, as described in Parameter Validation. Если выполнение может быть продолжено, эта функция устанавливает еинвал и возвращает 0.If execution is allowed to continue, this function sets errno to EINVAL and returns 0.

Дополнительные сведения об этих кодах ошибки см. в разделе _doserrno, errno, _sys_errlist и _sys_nerr.For more information about error codes, see _doserrno, errno, _sys_errlist, and _sys_nerr.

Description

writecountbuffd

The number of bytes written may be less than count if, for example, there is insufficient space on the underlying physical medium, or the
RLIMIT_FSIZE resource limit is encountered (see setrlimit(2)), or the call was interrupted by a signal handler after having written less
than count bytes. (See also pipe(7).)

For a seekable file (i.e., one to which lseek(2) may be applied, for example, a regular file) writing takes place at the current file offset,
and the file offset is incremented by the number of bytes actually written. If the file was open(2)ed with O_APPEND, the file offset is
first set to the end of the file before writing. The adjustment of the file offset and the write operation are performed as an atomic step.

POSIX requires that a read(2) which can be proved to occur after a write() has returned returns the new data. Note that not all file
systems are POSIX conforming.

COLOPHON top

       This page is part of release 5.08 of the Linux man-pages project.  A
       description of the project, information about reporting bugs, and the
       latest version of this page, can be found at
       https://www.kernel.org/doc/man-pages/.

Linux                            2019-10-10                         WRITE(2)

Pages that refer to this page:
pv(1), 
strace(1), 
telnet-probe(1), 
close(2), 
creat(2), 
epoll_ctl(2), 
eventfd2(2), 
eventfd(2), 
fcntl(2), 
fcntl64(2), 
fdatasync(2), 
fsync(2), 
getpeername(2), 
getrlimit(2), 
lseek(2), 
memfd_create(2), 
mmap(2), 
munmap(2), 
_newselect(2), 
open(2), 
openat(2), 
pipe2(2), 
pipe(2), 
prctl(2), 
pread(2), 
pread64(2), 
preadv2(2), 
preadv(2), 
prlimit(2), 
prlimit64(2), 
pselect(2), 
pselect6(2), 
pwrite(2), 
pwrite64(2), 
pwritev2(2), 
pwritev(2), 
read(2), 
readv(2), 
seccomp(2), 
select(2), 
select_tut(2), 
send(2), 
sendfile(2), 
sendfile64(2), 
sendmsg(2), 
sendto(2), 
setrlimit(2), 
socket(2), 
socketpair(2), 
sync(2), 
syncfs(2), 
syscalls(2), 
ugetrlimit(2), 
writev(2), 
aio_error(3), 
aio_return(3), 
aio_write(3), 
curs_print(3x), 
db(3), 
dbopen(3), 
eventfd_read(3), 
eventfd_write(3), 
fclose(3), 
fd_clr(3), 
FD_CLR(3), 
fd_isset(3), 
FD_ISSET(3), 
fdopen(3), 
fd_set(3), 
FD_SET(3), 
fd_zero(3), 
FD_ZERO(3), 
fflush(3), 
fgetc(3), 
fgets(3), 
fopen(3), 
fputc(3), 
fputs(3), 
fread(3), 
freopen(3), 
fwrite(3), 
getc(3), 
getchar(3), 
gets(3), 
libexpect(3), 
mcprint(3x), 
mkfifo(3), 
mkfifoat(3), 
mmap64(3), 
mpool(3), 
putc(3), 
putchar(3), 
puts(3), 
stdio(3), 
ungetc(3), 
vlimit(3), 
xdr(3), 
xdr_array(3), 
xdr_bool(3), 
xdr_bytes(3), 
xdr_char(3), 
xdr_destroy(3), 
xdr_double(3), 
xdr_enum(3), 
xdr_float(3), 
xdr_free(3), 
xdr_getpos(3), 
xdr_inline(3), 
xdr_int(3), 
xdr_long(3), 
xdrmem_create(3), 
xdr_opaque(3), 
xdr_pointer(3), 
xdrrec_create(3), 
xdrrec_endofrecord(3), 
xdrrec_eof(3), 
xdrrec_skiprecord(3), 
xdr_reference(3), 
xdr_setpos(3), 
xdr_short(3), 
xdrstdio_create(3), 
xdr_string(3), 
xdr_u_char(3), 
xdr_u_int(3), 
xdr_u_long(3), 
xdr_union(3), 
xdr_u_short(3), 
xdr_vector(3), 
xdr_void(3), 
xdr_wrapstring(3), 
xfsctl(3), 
dsp56k(4), 
fuse(4), 
lirc(4), 
st(4), 
proc(5), 
procfs(5), 
systemd.exec(5), 
aio(7), 
cgroups(7), 
cpuset(7), 
epoll(7), 
fanotify(7), 
inode(7), 
inotify(7), 
pipe(7), 
sched(7), 
signal(7), 
signal-safety(7), 
socket(7), 
spufs(7), 
tcp(7), 
time_namespaces(7), 
udp(7), 
vsock(7), 
x25(7), 
netsniff-ng(8), 
xfs_io(8)

RemarksRemarks

Функция fread_s считывает количество элементов elementSize байт из входного потока и сохраняет их в буфер.The fread_s function reads up to count items of elementSize bytes from the input stream and stores them in buffer. Указатель файла, связанный с потоком (при его наличии), увеличивается на число фактически считанных байтов.The file pointer that is associated with stream (if there is one) is increased by the number of bytes actually read. Если данный поток открыт в текстовом режиме, пары переводов строки возврата каретки заменяются символами однострочного перевода строки.If the given stream is opened in text mode, carriage return-line feed pairs are replaced with single line feed characters. Замена не влияет на указатель файла или возвращаемое значение.The replacement has no effect on the file pointer or the return value. В случае ошибки позиция указателя файла будет неопределенной.The file-pointer position is indeterminate if an error occurs. Значение частично считанного элемента не может быть определено.The value of a partially read item cannot be determined.

Эта функция блокирует работу других потоков.This function locks out other threads. Если требуется версия без блокировки, используйте _fread_nolock.If you require a non-locking version, use _fread_nolock.

По умолчанию глобальное состояние этой функции ограничивается приложением.By default, this function’s global state is scoped to the application. Чтобы изменить это, см. раздел глобальное состояние в CRT.To change this, see Global state in the CRT.

Errors

EAGAIN
The file descriptor fd refers to a file other than a socket and has been marked nonblocking (O_NONBLOCK), and the write would block.
EAGAIN or EWOULDBLOCK
The file descriptor fd refers to a socket and has been marked nonblocking (O_NONBLOCK), and the write would block. POSIX.1-2001 allows either
error to be returned for this case, and does not require these constants to have the same value, so a portable application should check for both possibilities.
EBADF
fd is not a valid file descriptor or is not open for writing.
EDESTADDRREQ
fd refers to a datagram socket for which a peer address has not been set using connect(2).
EDQUOT
The user’s quota of disk blocks on the file system containing the file referred to by fd has been exhausted.
EFAULT
buf is outside your accessible address space.
EFBIG
An attempt was made to write a file that exceeds the implementation-defined maximum file size or the process’s file size limit, or to write at a position
past the maximum allowed offset.
EINTR
The call was interrupted by a signal before any data was written; see signal(7).
EINVAL
fd is attached to an object which is unsuitable for writing; or the file was opened with the O_DIRECT flag, and either the address specified
in buf, the value specified in count, or the current file offset is not suitably aligned.
EIO
A low-level I/O error occurred while modifying the inode.
ENOSPC
The device containing the file referred to by fd has no room for the data.
EPIPE
fd is connected to a pipe or socket whose reading end is closed. When this happens the writing process will also receive a SIGPIPE signal.
(Thus, the write return value is seen only if the program catches, blocks or ignores this signal.)

Other errors may occur, depending on the object connected to fd.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector