IO and IO standard system calls

1. The system call IO (unbuffered IO)

System calls

Everything is a file, the file operation is in Linux in Linux is very important. For this reason, Linux kernel provides a set of user processes to interact with the kernel interfaces for file and device access control, these interfaces are called system calls.

System calls for maximum impact applications that:

  • In a uniform manner, provides a set of files for the application to access the abstract interface, application does not need specific types of files concerned, it does not care about its internal implementation details.

Common system calls the IO functions

IO functions commonly used system call has five: open, close, read, write, ioctl, in addition to a non-call system IO functions lseek, system calls are not buffered IO IO.

open

open for creating a new file or open an existing file and returns a non-negative file descriptor fd.
0,1,2 system predefined file descriptors, representing STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO.

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

//成功返回文件描述符,失败返回-1
int open(const char *pathname, int flags, ... /* mode_t mode */);

flags parameter is generally selected at a specified O_RDONLY, O_WRONLY O_RDWR and in the following may also be required or a constant:

  • O_CREAT: If the file does not exist, create it, this case requires a third mode parameter, the value and meaning of the mode can be set as shown in FIG.
  • O_APPEND: are appended to the end of the file each time you write
  • O_NONBLOCK: If the pathname is corresponding to the FIFO, block special character special file or document, so that the open operation command and a subsequent operation setting non blocking IO

close

close to close an open file.

#include <unistd.h>

//成功返回0,失败返回-1
int close(int fd);

When the process terminates, the kernel will automatically close all its open files, applications often use it without explicitly close the file.

read

read for reading data from the opened file.

#include <unistd.h>

//成功返回读到的字节数;若读到文件尾则返回0;失败返回-1
ssize_t read(int fd, void *buf, size_t count);

read operation starts from the current offset of the file, before a successful return, increases the file offset number of bytes actually read.
Several conditions can cause the number of bytes read is less than the actual number of bytes read request:

  • When reading an ordinary file, the number of bytes required before read reaches the end. For example, there are 30 bytes from the end of the file is required to read 100 bytes, the read returns 30, when the next read directly call returns 0
  • When reading from the network, the network buffering mechanism may result in the return value of less than the required number of bytes read, the solution revisit the topic in network programming

write

write for writing data to a file.

#include <unistd.h>

//成功返回写入的字节数,失败返回-1
ssize_t write(int fd, const void *buf, size_t count);
  • write the return value is usually the same as the argument count, otherwise, it indicates an error.
  • For ordinary files, write operation starts from the current offset of the file
  • If the O_APPEND option is specified, each file before writing the first offset to the end of file
  • After a successful write file offset increase in the number of bytes actually written.

lseek

lseek provided for opening a file offset.

#include <sys/types.h>
#include <unistd.h>

//成功返回新的文件偏移量,失败返回-1
off_t lseek(int fd, off_t offset, int whence);

Interpretation of the offset depends on the value of whence:

  • If whence == SEEK_SET, the file is set to the offset from the beginning of the file byte offset, this time offset must be non-negative
  • If whence == SEEK_CUR, then the file offset as the current value + offset, this time offset may be either positive or negative
  • If whence == SEEK_END, the file is set to the file offset length + offset, this time offset may be either positive or negative

note:

  • lseek only records new file offset in the kernel, it does not cause any operation IO, IO so it is not a system call, but the offset is used for the next read / write operation
  • Pipes, FIFO, and the socket does not support setting file offset, you can not call lseek

ioctl

ioctl provides an interface for controlling the device and a descriptor behavior and configuration of the underlying services.

#include <sys/ioctl.h>

//出错返回-1,成功返回其他值
int ioctl(int fd, int cmd, ...);
  • ioctl on the object descriptor fd designated by the reference operating parameter cmd
  • Each device driver can define its own dedicated set of ioctl command

2. Standard IO (buffered IO)

Outline

In fact, the standard IO IO interface stdio.h header file is provided, but may have specific internal implementation in a particular system.
IO system calls and the like, but also standard IO three predefined file pointer stdin, stdout, stderr, respectively corresponding to the standard input, standard output and standard error.

And wash buffer

IO IO standard is buffered, a total of three types of buffer:

  • Fully Buffered: IO operation performed after the buffer is filled, such as disk files
  • Line buffer: newline only for IO operations, such as command line terminal (stdin and stdout)
  • Unbuffered: unbuffered, IO operation performed immediately, as stderr

In general, the following types of system default buffer:

  • stderr is unbuffered
  • The terminal apparatus directed flow line buffered, otherwise it is fully buffered

For an open stream, or can call setbuf setvbuf change buffer type.

//成功返回0,失败返回非0
void setbuf(FILE *fp, char *buf);
int setvbuf(FILE *fp, char *buf, int mode, size_t size);
  • setbuf buffering mechanism for closing or opening of fp, when open, must point to a length of buf BUFSIZ buffer; if closed, buf is set to NULL
  • setvbuf precisely set the buffer type parameter mode,_IOLBF==全缓冲, _IOLBF==行缓冲,_IONBF==无缓冲
  • When the set is buffered setvbuf, buf must point to a length of the buffer size, the recommended buf to NULL to automatically allocate buffer length, size can be set to 0 at this time

For the full buffer and line buffered, regardless of whether or not to meet the IO conditions, fflush function can be used to force IO operation, we call it flushing.

//成功返回0,失败返回EOF
//若fp为NULL,将导致冲洗所有输出流
int fflush(FILE *fp);

Common standard IO functions

Commonly used standard IO functions are divided into the following categories:

  • Open and close the stream
  • Positioning stream
  • Read stream, including text IO, IO binary format, and three kinds of IO

Open and close the stream

//成功返回文件指针,失败返回NULL
FILE *fopen(const char *pathname, const char *type);

//成功返回0,失败返回EOF
void fclose(FILE *fp);

fopen opens the file specified by the pathname, type specify read-write mode:

  • B using the character type as part of that standard IO can distinguish between text and binary files
  • Linux kernel does not distinguish between text and binary files, use the character b in Linux virtually no effect, read-only, write-only, read-write designated as "r", "w", "rw" to
  • Windows, text files read-only, write-only, read and write were "r", "w", "rw", binary files read-only, write-only, read and write were "rb", "wb", "rb +"
  • Read-only approach requires file must exist, write-only or read-write mode is created when the file does not exist

close the file fclose to close the output data before the buffer is flushed, the output data is discarded.

Positioning stream

Similar positioning system stream acquired call IO current file offset, ftell and fseek bitstream functions can be used.

//成功返当前文件位置,出错返回-1
int ftell(FILE *fp);

//成功返回0,失败返回-1
void fseek(FILE *fp, long offset, int whence);

IO in the lseek offset and whence the meaning and value can be set with the same system calls will not be repeated, but if it is in a non-Linux systems, there is one caveat:

  • For a binary file, the file location is calculated in strict accordance with the byte offset, but this may not be a text file
  • When positioning the text file, whence must be SEEK_SET, and offset can only return value is 0 or ftell

Text IO

There are two text IO:

  • Every time a character to read and write
  • Every read and write his string
/*
 * 每次读写一个字符
*/

//成功返回下一个字符,到达文件尾或失败返回EOF
int getc(FILE *fp);          //可能实现为宏,因此不允许将其地址作为参数传给另一个函数,因为宏没有地址
int fgetc(FILE *fp);         //一定是函数
int getchar();               //等价于getc(stdin)

//成功返回c,失败返回EOF
int putc(int c, FILE *fp);   //可能实现为宏,因此不允许将其地址作为参数传给另一个函数,因为宏没有地址
int fputc(int c, FILE *fp);  //一定是函数
int putchar(int c);          //等价于putc(c, stdout)
/*
 * 每次读写一行字符串
*/

//成功返回str,到达文件尾或失败返回EOF
char *fgets(char *str, int n, FILE *fp); //从fp读取直到换行符(换行符也读入),str必须以'\0'结尾,故包括换行符在内不能超过n-1个字符

//成功返回非负值,失败返回EOF
int fputs(const char *str, FILE *fp);    //将字符串str输出到fp,str只要求以'\0'结尾,不一定含有换行符

Binary IO

Binary IO is fread and fwrite.

//返回读或写的对象数
size_t fread(void *ptr, size_t size, size_t nobj, FILE *fp);
size_t fwrite(const void *ptr, size_t size, size_t nobj, FILE *fp);

Binary IO Common uses include:

  • Read and write a binary array
  • A write structure

Use of the two together, may also read and write an array of structures.

struct Item
{
    int id;
    char text[100];
};

int data[10];
struct Item item;
struct Item item[10];

//读写二进制数组
fread(&data[2], sizeof(int), 4, fp);
fwrite(&data[2], sizeof(int), 4, fp);

//读写结构
fread(&item, sizeof(item), 1, fp);
fwrite(&item, sizeof(item), 1, fp);

//读写结构数组
fread(&item, sizeof(item[0]), sizeof(item) / sizeof(item[0]), fp);
fwrite(&item, sizeof(item[0]), sizeof(item) / sizeof(item[0]), fp);

Format IO

IO input function includes formatting and output functions aromatic group, we have not excluded the common file pointer FP, the API related file descriptor fd, leaving only three common output functions and input functions 2.

//成功返回输出或存入buf的字符数(不含'\0'),失败返回负值
int printf(const char *format, ...);
int sprintf(char *buf, const char *format, ...);
int snprintf(char *buf, size_t n, const char *format, ...);
  • sprintf and snprintf end of string is automatically added at the end of buf '\ 0', but the character is not included in the return value
  • snprintf requires the caller to ensure a sufficiently large buffer buf length n
//成功返回输入的字符数,到达文件尾或失败返回EOF
int scanf(const char *format, ...);
int sscanf(const char *buf, const char *format, ...);

PS: sscanf have in the actual project a practical tips: serial port to receive one of the messages, according to the serial protocol, using sscanf to extract the various fields, so as to quickly and easily perform message parsing.

Guess you like

Origin www.linuxidc.com/Linux/2019-09/160746.htm