File IO programming under Linux

Keywords: Linux Programming Unix

Linux system call refers to a set of "special interfaces" provided by the operating system to user programs through which user programs can obtain special services provided by the operating system.
To better protect kernel space, programs are divided into kernel space and user space, which run at different levels and are logically isolated from each other.In Linux, user programs cannot access services provided by the kernel directly, and they must use the services provided by the kernel through system calls.
The user programming interface (API) in Linux follows the most popular application programming interface standard in UNIX, POSIX.These system call programming interfaces are mainly implemented through the C library (libc).
Expiration portal:
        The most complete summary of Linux common commands ever (super detailed!Ultra-comprehensive) Collection of this one is enough
        Are you clear about these operations of standard IO on Linux (with detailed descriptions and routines)

Article Directory

Introduction to File I/O

  • A set of functions defined by POSIX (Portable Operating System Interface)
  • No buffering mechanism is provided and system calls are made for each read/write operation
  • The core concept is the file descriptor
  • Accessing various types of files

File Descriptor

  • One file descriptor for each open file
  • The file descriptor is a non-negative integer, and Linux assigns a file descriptor to each open file in the program
  • File descriptors are allocated from 0, increasing in order
  • File IO operations are done using file descriptors

Note: Open file systems in each program will be assigned file descriptors individually, without interacting with each other

File I/O differs from standard I/O

Standard I/O File I/O
ANSIC POSIX
Buffered (reduces system calls) No buffer (system calls are required to read and write files)
Stream (FILE structure) Open File A file descriptor represents an open file

open File

The open function creates or opens a file:

#include <fcntl.h>
int open(const char *path,int oflag,...);
//Parameter 1: Open file path parameter 2: Open mode
  • Return file descriptor on success; return EOF on error
  • Use two parameters when opening a file
  • Permissions for the new file specified by the third parameter when creating the file
  • Only device files can be opened

Example 1:
Open 1.txt in a write-only manner.Create if the file does not exist and empty if it does exist.
int fd;
if((fd=open("1.txt",O_WRONLY|O_CREAT|O_TRUNC,0666))<0
{
	perror("open");
	return -1;
}
Example 2:
Open file 1.txt read-write.Create if file does not exist and error if file exists:
int fd;
if((fd=open("1.txt",O_RDWR|O_CREAT|O_EXCL,0666))<0)
{
	if(errno==EEXIST)
	{
		perror("exist error");
	}
	else
	{
		perror("other error");
	}
}

close file

The close function closes an open file:

#include <unistd.h>
int close(int fd);
  • Return 0 on success; EOF on error
  • Close all open files automatically at program end
  • File cannot be manipulated after it has been closed

read File

The read function reads data from a file:

#include <unistd.h>
ssize_t read(int fd,void *buf,size_t count);
  • Returns the actual number of bytes read on success; returns EOF on error
  • Return 0 when reading to the end of the file
  • buf is the buffer to receive data
Example
Read content from specified files (text files) and size them
#include <stdio.h>
#include <unistd.h>
int main(int argc,char *argv[])
{
	int fd,n,total=0;
	char buff[64];
	if(argc<2){
		prinff("Usage:%s<file>\n",argv[0];
		return -1;
	}
	if((fd=open(argv[1],O_RDONLY))<0){
		perror("open";
		return -1;
	}
	while((n=read(fd,buf,64))>0){//Read 64 bytes into buf and save the return value to n
		total+=n;//The value of total is the size of the file
	}
	printf("size:%d\n",total);
	return 0;
}

write to file

The write function is used to write data to a file:

#include <unistd.h>
ssize_t write(int fd,void *buf,size_t count);//buf writes; count writes size
  • Returns the actual number of bytes written on success; returns EOF on error
  • buf is the buffer to send data
  • count should not exceed buf size
Example
Write keyboard input to a file until quit ends:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main(int argc,char *argv[])
{
	int fd;
	char buf[20];
	//Open file as write-only, empty if file does not exist to create, and empty if file exists
	if((fd =open(argv[1],O_WRONLY|OCREAT|O_TRUNC,0666))<0{
		perror("open");
		return -1;
	}
	while(fgets(buf,20,stdin)!=NULL){
		if(strcmp(buf,"quit\n")==0)break;
		write(fd,buf,strlen(buf));
	}

Locate file (lseek)

The lseek function is used to locate files:

#include <unistd.h>
off_t lseek(int fd,off_t offset,intt whence);
  • Return the read and write location of the current file on success; return EOF on error
  • The offset and whence parameters are exactly the same as flook

Access directory (opendir/readdir)

The opendir function opens a directory file:

#include <dirent.h>
DIR *opendir(const char *name);
  • DIR is the structure type used to describe an open directory file
  • Return directory stream pointer on success; NULL on error

The readdir function reads the contents of the directory stream:

#include <dirent.h>
struct sirent *readdir(DIR *dirp);
  • struct dirent is the type of structure used to describe a catalog item in a catalog stream
  • Include char d_Member such as name[256]
  • Return to next directory item in directory stream dirp on success
  • Error or return to NULL at end

Close directory

closedir closes a directory file:

#include <dirent.h>
int closedir(DIR *drip);
Example:
Print the names of all files in the specified directory:
#include <stdio.h>
#include <dirent.h>
int main(int argc,char *argv[])
{
	DIR *drip;
	struct dirent *dp;
	if(argc<2){
		printf("Usage :%s<directory>\n"argc[0]);return -1;
	}
	if((dirp=opendir(argv[1]))==NULL){
		perror("opendir");
		return -1;
	}
	while((dp=readdir(dirp))!=NULL){
		printf("%s\n",dp->d_name);
	}
	closedir(dirp);
	return 0;
}

Modify File Properties (chmod/fchmod)

The chmod/fchmod function is used to modify file access rights:

#include <sys/stat.h>
int chmod(const char *path,mode_t mode);
int fchmod(int fd,mode_t mode);
  • Return 0 on success; EOF on error
  • root and file owner can modify file access

Get file properties (stat/lstat/fstat)

#include <stdio.h>
int stat(const char *path,struct stat *buf);
int lstat(const char *path,struct stat *buf);
int fstat(int fd,struct stat *buf);
  • Return 0 on success and EOF on error;
  • If path is a symbolic link stat, it gets the properties of the target file; lstat gets the properties of the link file

Strct stat is the type of structure that holds file attributes:

Structural type Effect
mode_t st_mode Types and access rights
uid_t st_uid Owner id
uid_t st_gid User id
off_t st_size file size
time_t st_mtime Last Modified Time

St_The model uses the macros provided by the system to determine the file type:
Through (st_Mode&0170000) The calculated values match the following

file type calculated value
S_ISREG(st_mode) Normal file 0100000
S_ISDIR(st_mode) catalog file 0040000
S_ISCHR(st_mode) 0020000
S_ISBLK(st_mode) 0060000
Example
Get and display file properties:
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc,char *argv[])
{
	struct stat buf;
	struct tm *tp;//Pointer to get local time
	int n;
	if(argc<2)
	{
		printf("Usage:%s <file>\n",argv[0]);
		return -1;
	}
	if(lstat(argv[1],&buf)<0)
	{
		perror("lstat");
		return -1;
	}
	switch(buf.st_mode&S_IFMT)
	{
		case S_IFRGE:
			printf("-");
			break;
		case S_IFDIR:
			printf("d");//Is a directory file
			break;
	}
	for(n=8;n>=0;n--)
	{
		if(buf.st_mode&(1<<n))
		{
			switch(n%3)
			{
			case 2:
				printf("r");
			case 1:
				printf("w");
				break;
			case 0:
				printf("x");
				break;
			}
		}
		else
		{
			printf("-");			
		}
	}
	printf("%lu",buf.st_size);
	tp=localtime(buf.st_mtime);//Convert to Local Time
	printf("%d-%02d-%02d",tp->tm_year+1900,tp->tm_mon+1,tp->tm_mday);//Years, months, days
	printf("%s\n",argc[1]);
	return 0;
}

There is no river without small streams and no miles without stumbling.And if I want to be a Wanliyang, I must insist on learning to acquire more knowledge, change my fate with knowledge, witness my growth with blog, and prove my efforts with action.
If my blog is helpful to you and if you like my blog content, remember to "compliment", "comment" and "collect" one click at a time!I've heard that people who like it won't have bad luck. They'll be full of energy every day!If you really want to express your words, I wish you a happy day and welcome you to visit my blog often.

Posted by locomotive on Tue, 16 Jun 2020 18:34:54 -0700