The main content of this article:
Linux system application programming (1) file programming
1. Linux file I/O
1.Open the file
▲ Function prototype: int open(const char *pathname, int flagsmode_mode)
- Linux file permissions: three decimal digits represent the permissions of the user, group user, and other users on the file.
2.Write files
▲ Function prototype: ssize_t write(int fd, const void *buf, size_t count);
3. Read files
▲ Function prototype: ssize_t read(int fd, void *buf, size_t count);
4. Manipulate file pointers
▲ Function prototype: off_t lseek(int fd, off_t offset, int whence);
【4-1】Application: lseek() calculates file size
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc,char **argv){
if(argc != 2){
printf("error.Usage:count fileName\n");
exit(-1);
}
int fd;
fd = open(argv[1],O_RDONLY);
// lseek(fd,0,SEEK_SET); //默认打开文件时的文件指针在头
int fileSize = lseek(fd,0,SEEK_END); //lssek让指针偏移到文件尾,偏移了多少就是文件的大小
printf("%s size:%d\n",argv[1],fileSize);
close(fd);
return 0;
}
5. Implement the cp command
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc,char **argv){
if(argc != 3){
printf("copy:error.Usage:copy srcFile destFile\n");
exit(-1);
}
int srcFd = open(argv[1],O_RDONLY);
if(srcFd == -1){
perror("open");
exit(-1);
}
int destFd = open(argv[2],O_RDWR | O_CREAT,0600);
if(destFd == -1){
perror("open");
exit(-1);
}
/* 计算源文件的大小 */
off_t size = lseek(srcFd,0,SEEK_END);
lseek(srcFd,0,SEEK_SET); //让文件指针回到原位置
char *readBuffer = (char *)malloc(size); //文件多大就申请多大的空间
ssize_t cnt = read(srcFd,readBuffer,size);
write(destFd,readBuffer,cnt);
close(srcFd);
close(destFd);
return 0;
}
2. Standard I/O
1. What is the difference between file IO and standard IO?
- File IO: directly calls the system call function provided by the kernel, generally specific to Linux/Unix platforms. Its file operation mechanism does not go through the kernel's cache (no cache), and data is transmitted directly on the disk and application address space.
- Standard IO: Indirectly calling the system call function provided by the kernel (first calling the C library, then calling the kernel system call), it is not limited to the platform, and implements cross-platform caching (including line cache, full cache, and no cache types) , so its execution efficiency will be better than file IO.
2.Open the file
▲ Function prototype: FILE *fopen(const char *pathname, const char *mode, FILE *stream);
3. Read files
▲ 函数原型:size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
4.Write files
▲ 函数原型:size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
▲ Parameter explanation:
- pstr: storage space to store this read/write
- size: read/write the size of a data element
- nmemb: the data size read/written this time
- stream: file stream for reading/writing
▲Return value:
- Reading/writing success: Return nmemb, which is the number of elements that were read/written successfully
- Read/write failed: return 0
文档中所述,对于返回值为0的情况,不区分是读取/写入失败了还是文件结束了
5. Move the file pointer
▲ Function prototype: int fseek(FILE *stream, long offset, int whence);
-
fseek() is different from lseek(), fseek() returns value: if successful, the function returns zero, otherwise it returns a non-zero value.
When calculating the file size, it needs to be implemented in conjunction with ftell().
6. Implement the cp command
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc,char **argv){
if(argc != 3){
printf("Error.Usage:%s srcFile desFile\n",argv[0]);
return -1;
}
/* 打开源文件和目标文件 */
FILE *fpSrc = fopen(argv[1],"r"); //返回文件流指针
FILE *fpDes = fopen(argv[2],"w+");
if(fpSrc == NULL || fpDes == NULL){
perror("fopen");
exit(-1);
}
/* 计算源文件大小 */
fseek(fpSrc,0,SEEK_END);
long int srcSize = ftell(fpSrc);
printf("fileSize:%ld\n",srcSize);
fseek(fpSrc,0,SEEK_SET);
char *buffer = (char *)malloc(srcSize);
int readSize = 0;
while( (readSize = fread(buffer,4,1024*4,fpSrc)) != 0){
printf("readSize:%d\n",readSize);
fwrite(buffer,4,readSize,fpDes);
}
printf("copy done\n");
return 0;
}
7. Other functions fgetc(), fpurc(), feof()
3. Directory IO
1. Function prototype
- DIR *opendir(const char *name);
- DIR *fdopendir(int fd);
- int mkdir(const char *pathname, mode_t mode);
- struct dirent *readdir(DIR *dirp);
2. Application: Print out all file names and inode numbers in the specified directory
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdlib.h>
int main(int argc,char **argv){
DIR *dp = NULL;
char isCreate = 'n';
struct dirent *p = NULL;
if(argc != 2){
printf("error.Usage:%s [dirName]\n",argv[0]);
exit(-1);
}
reopen:
dp = opendir(argv[1]); //打开目标目录
if(dp == NULL){
//打开失败,如果是目录不存在,询问是否创建该目录
printf("No such direcory\nDo you want to create %s?[y/n] ",argv[1]);
scanf("%c",&isCreate);
if(isCreate == 'y'){
mkdir(argv[1],0666); //创建目录
goto reopen;
}else{
printf("done\n");
exit(-2);
}
}
/* 读出目录下所有文件的inode号和name(排除.和..) */
while((p = readdir(dp)) != NULL){
if( strcmp(p->d_name,".") && strcmp(p->d_name,"..")){
printf("Inode:%ld\t name:%s\n",p->d_ino,p->d_name);
}
}
closedir(dp);
return 0;
}