1 Executable programs or shell commands 可执行程序或者shell命令
2 System calls (functions provided by the kernel) 系统调用,内核提供的函数
3 Library calls (functions within program libraries) 库函数调用(程序库中的函数)
4 Special files (usually found in /dev) 特殊文件
5 File formats and conventions eg /etc/passwd 文件格式和规范
6 Games 游戏
7 Miscellaneous (including macro packages and conventions), e.g. man(7),groff(7)
8 System administration commands (usually only for root) 系统管理命令
9 Kernel routines [Non standard] 内核例程
eg:man 2 open
#include
FILE *fopen(const char *path, const char *mode); 打开文件
int fclose(FILE *fp); 关闭文件
//mode参数
/*“r”:只读,文件必须存在。
“w”:只写,如果不存在则创建,存在则覆盖。
“a”:追加,如果不存在则创建。
“r+”:允许读和写,文件必须存在。
“w+”:允许读和写,文件不存在则创建,存在则覆盖。
“a+”:允许读和追加,文件不存在则创建*/
1、fopen函数
成功返回文件指针,失败返回NULL
2、fclose函数
成功返回0,失败返回-1
#include
int fgetc(FILE *stream);
int getchar(void);
int fputc(int c, FILE *stream);
int putchar(int c);
fgetc 函数从指定的文件中读一个字节。
getchar从标准输入读一个字节,调用 getchar() 相当于 fgetc(stdin)。
fputc 函数向指定的文件写入一个字节。
putchar 向标准输出写一个字节,调用 putchar() 相当于调用 fputc(c, stdout)。
1、stdin等是FILE *类型,属于标准I/O,在<stdio.h>。
2、STDIN_FILENO等是文件描述符,是非负整数,一般定义为0, 1, 2
属于没有buffer的I/O,直接调用系统调用,在<unistd.h>
3、上面的函数,成功返回0,错误或读到文件末尾时将返回 EOF,即 -1
#include
int fseek(FILE *stream, long offset, int whence);
void rewind(FILE *stream);
long int ftell(FILE *stream);
1、fseek函数:文件偏移
成功,返回0,失败返回非0值,并设置error的值,可以用perror()函数输出错误
whence:从何处开始移动,取值:SEEK_SET | SEEK_CUR | SEEK_END
offset:移动偏移量,取值:可取正 | 负
fseek(fp, 4, SEEK_SET); // 从文件头向后移动4个字节
fseek(fp, 4, SEEK_CUR); // 从当前位置向后移动4个字节
fseek(fp, -4, SEEK_END); // 从文件尾向前移动4个字节
2、rewind函数
返回到文件开头
rewind(fp)相当于 fseek(fp, 0, SEEK_SET)
3、ftell函数
返回当前文件位置
// 实现计算文件字节数的功能
fseek(fp, 0, SEEK_END);
ftell(fp);
char *fgets(char *s, int size, FILE *stream);
char *gets(char *s);
int fputs(const char *s, FILE *stream);
int puts(const char *s);
fgets 函数从 stream 所指文件读取以 ‘\n’ 结尾的一行,包括 ‘\n’ 在内,
存到缓冲区中,并在该行结尾添加一个 ‘\0’ 组成完整的字符串。
如果文件一行太长,fgets 从文件中读了 size-1 个字符还没有读到 ‘\n’,
就把已经读到的 size-1 个字符和一个 ‘\0’ 字符存入缓冲区,
文件行剩余的内容可以在下次调用 fgets 时继续读。
fputs 向指定文件写入一个字符串,
缓冲区保存的是以 ‘\0’ 结尾的字符串,
与 fgets 不同的是,fputs 不关心字符串中的 ‘\n’ 字符
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
参数:
ptr:存放文件内容地址
size 读取的块大小
nmemb 块数(读取文件大小 = 块数*每块大小)
stream 文件指针
返回值:
成功读取到文件块数
size_t fwrite(void *ptr, size_t size, size_t nmemb, FILE *stream);
参数:
ptr:写入文件内容地址
size 块大小
nmemb 块数(写入文件大小 = 块数*每块大小)
stream 文件指针
返回值:
成功:写入到文件块数
eg:
struct t{
int a;
short b;
};
struct t val = {1, 2};
FILE *fp = fopen("file.txt", "w");
fwrite(&val, sizeof(val), 1, fp);
fclose(fp);
使用头文件<fcntl.h>
int open(const char* pathname,int flags);
int open(const char* pathname,int flags,mode_t );
int close(int fd);
参数:
pathname 文件名
flag:打开权限
O_RDONLY(只读)、O_WRONLY(只写)、O_RDWR(可读可写)、
O_APPEND(追加)、C_CREAT(创建)、O_EXCL、O_TRUNC(截断)、O_NONBLOCK(非阻塞)
创建文件时,指定文件访问权限,权限同时受umask影响,
文件权限 = mode&~umask
返回值:
成功:文件描述符
失败:-1
size_t read(int fd,void* buf,size_t count);
参数:
fd 文件描述符
buf 存储数据缓冲区
count 缓冲区大小
返回值:
0 表示读到文件结尾
成功:读取到的文件字节数
失败:-1设置error
-1并且errno = EAGAIN 或 EWOULDBLOCK,
说明不是read 失败,而是以非堵塞方式读取一个设备文件(网络),并且文件无数据
size_t write(int fd,void* buf,size_t count);
参数:
fd 文件描述符
buf 要写入的数据
count 要写入的数据大小
返回值:
成功:成功写入的字符
失败:-1设置errno
int fcntl(int filedes,int cmd, ... /*int arg*/);
更改文件属性
int flgs = fcntl(fd, F_GETFL);
flgs |= O_NONBLOCK
fcntl(fd, F_SETFL, flgs);
cmd参数
获取文件状态: F_GETFL
设置文件状态: F_SETFL
off_t lseek(int fd,off_t offset,int whence);
参数:
fd 文件描述符
offset 偏移量
whence 起始偏移位置:SEEK_SET/SEEK_CUR/SEEK_END
返回值:
成功:较起始位置偏移量
失败:-1 errno
//使用lseek函数改变文件大小
lseek(fd, 9, SEEK_END); //将文件给扩展长度到10
write(fd, "\0", 1);
//使用lseek函数获取文件大小
int len = lseek(fd, 0, SEEK_END);//获取文件的长度
int truncate(const char* path,off_t length);//更改文件大小
int truncate(int fd,off_t length);//更改文件大小
返回值:成功返回0,错误返回-1
//使用truncate函数更改文件大小
int ret = truncate("dict.cp", 250);
int ret2 = ftruncate(fd,250);
int stat(const char *path, struct stat *buf);//stat 会拿到符号链接指向那个文件或目录的属性
int lstat(const char *path, struct stat *buf);//lstat不会穿透
int fstat(int fd, struct stat *buf);
参数:
path: 文件路径
buf:(传出参数) 存放文件属性,inode 结构体指针。
返回值:
成功: 0
失败: -1 errno
获取文件大小: buf.st_size
获取文件类型: buf.st_mode
获取文件权限: buf.st_mode
//stat结构体
struct stat {
dev_t st_dev; /* ID of device containing file 文件设备编号*/
ino_t st_ino; /* inode number 节点号*/
mode_t st_mode; /* protection 文件的类型和存取的权限*/
nlink_t st_nlink; /* number of hard links 连到该文件的硬连接数目,刚建立的文件值为1*/
uid_t st_uid; /* user ID of owner 用户ID*/
gid_t st_gid; /* group ID of owner 组ID*/
dev_t st_rdev; /* device ID (if special file) (设备类型)若此文件尾设备文件,则为其设备编号*/
off_t st_size; /* total size, in bytes 文件字节数(文件大小)*/
blksize_t st_blksize; /* blocksize for filesystem I/O 块大小(文件系统的I/O缓冲区大小),类型为unsigned long类型*/
blkcnt_t st_blocks; /* number of 512B blocks allocated ,分配的512字节的块数,类型为unsigned long类型*/
time_t st_atime; /* time of last access 最后一个访问时间*/
time_t st_mtime; /* time of last modification 最后更改的时间*/
time_t st_ctime; /* time of last status change inode的更改时间*/
};
//宏定义
S_ISREG(m) is it a regular file? 是否是一个常规文件
S_ISDIR(m) directory? 是否是一个目录
S_ISCHR(m) character device? 是否是一个字符设备
S_ISBLK(m) block device? 是否是一个块设备
S_ISFIFO(m) FIFO (named pipe)? 是否是输入输出(管道)
S_ISLNK(m) symbolic link? (Not in POSIX.1-1996.) 是否是符号链接
S_ISSOCK(m) socket? (Not in POSIX.1-1996.) 是否是socket
eg:
if(S_ISDIR(mystat.st_mode)){
printf("it is a dir");
}
int link(const char *oldpath, const char *newpath);
int unlink(const char *pathname);
函数在执行成功时则返回0,失败时则返回-1,错误原因存于errno。
#include
#include
DIR * opendir(char *name);
int closedir(DIR *dp);
struct dirent *readdir(DIR * dp);
返回结构:
struct dirent {
ino_t d_ino; / inode number /
off_t d_off; / offset to the next dirent /
unsigned short d_reclen; / length of this record /
unsigned char d_type; / type of file /
char d_name[256]; / filename */
};
//该三个函数主要是用于遍历目录使用,获取文件、目录名字
#include
int dup(int oldfd);
int dup2(int oldfd, int newfd);//oldfd 拷贝给 newfd。返回 newfd
oldfd: 已有文件描述符
返回:新文件描述符,这个描述符和 oldfd 指向相同内容。
//使用fcntl函数实现dup2
fcntl(fd,F_DUPFD,0);
fcntl(fd,F_DUPFD,7);
//被占用的,返回最小可用的。
//未被占用的, 返回=该值的文件描述符。
//其中的第三个参数0,这个表示 0 被占用,fcntl 使用文件描述符表中的最小文件描述符返回
//假设传一个 7,且 7 未被占用,则会返回 7
access函数:用于测试指定的文件是否存在/拥有某种权限
int access(const char *pathname,int mode);
mode:R_OK,W_OK,X_OK,F_OK
成功/具备该权限:0;失败/不具备 -1 设置errno为相应值。
int ret = access(""./nihao.txt",F_OK);
if(ret == 0){
printf("该文件存在\n");
}else{
printf("该文件不存在\n");
}
chmod函数:用于修改文件的属性
int chmod(const char *path, mode_t mode);
成功:0;失败:-1设置errno为相应值
int fchmod(int fd, mode_t mode);
成功:0;失败:-1设置errno为相应值
int ret = chmod("./nihao.txt", 0777);
int ret = fchmod(fd, 0777);
chdir函数:改变当前工作目录
int chdir(const char *path );
成功:0;失败:-1设置errno为相应值
if(chdir("..") == -1){
perror("Couldn`t change current working diretory!");
return 1;
}
getcwd函数:获取进程当前工作目录 (卷3,标库函数)
char *getcwd(char *buf, size_t size);
成功:buf中保存当前进程工作目录位置。失败返回NULL。
rename函数:重命名一个文件。
int rename(const char *oldpath, const char *newpath);
成功:0;失败:-1设置errno为相应值
symlink函数:创建一个符号链接
int symlink(const char *oldpath, const char *newpath);
成功:0;失败:-1设置errno为相应值
readlink函数:读取符号链接文件本身内容,得到链接所指向的文件名。
ssize_t readlink(const char *path, char *buf, size_t bufsiz);
成功:返回实际读到的字节数;失败:-1设置errno为相应值。
rewinddir函数:回卷目录读写位置至起始。
void rewinddir(DIR *dirp);
返回值:无。
telldir函数:获取目录读写位置
long telldir(DIR *dirp);
成功:与dirp相关的目录当前读写位置。失败-1,设置errno
seekdir函数:修改目录读写位置
void seekdir(DIR *dirp, long loc); 返回值:无
参数loc一般由telldir函数的返回值来决定。
#include
#include
#include
#include
#include
#include
int main(int argc,char* argv[]){
char buff[1024];
int n =0;
int fd1 = open(argv[1],O_RDONLY);//read
int fd2 = open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0664);//如果没有则创建
if(fd1 == -1){
perror("open argv[1] error");
exit(1);
}
if(fd2 == -1){
perror("open argv[2] error");
exit(1);
}
while((n = read(fd1,buff,1024)) != 0){//读到结尾会返回0
if(n < 0){
perror("read error");
break;
}
write(fd2,buff,n);
}
close(fd1);
close(fd2);
return 0;
}
#include
#include
#include
#include
int main(int argc,char* argv[]){
FILE *fp,*fp_out;
int n = 0;
fp = fopen(argv[1],"r");
if(fp == NULL){
perror("open argv1 error");
exit(1);
}
fp_out = fopen(argv[2],"w");
if(fp_out == NULL){
perror("open argv2 error");
}
while((n = fgetc(fp))!=EOF){
fputc(n,fp_out);
}
fclose(fp);
fclose(fp_out);
return 0;
}
#include
#include
#include
#include
#include
int main(int argc,char **argv){
link(argv[1],argv[2]);
unlink(argv[1]);
return 0;
}
/*执行结果
ubuntu@ubuntu:~/LearnCPP/linux_test/link_test$ ./link_test nihao.txt nihao2.txt
ubuntu@ubuntu:~/LearnCPP/linux_test/link_test$ ls
link_test link_test.c makefile nihao2.txt
*/
#include
#include
#include
#include
#include
#include
#include
#include
void read_dir(char* dir,void (*func)(char*));
//判断是否是目录,打印文件
void isFile(char* name){
int ret = 0;
struct stat mystat;
ret = stat(name,&mystat);//获取文件属性
if(ret == -1){
perror("stat error");
return;
}
if(S_ISDIR(mystat.st_mode)){//判断是否是目录
read_dir(name,isFile);
}
printf("%s\t\t%ld\n",name,mystat.st_size);//打印文件名字和大小
return;
}
//读取文件,更新目录
void read_dir(char* dir , void (*func)(char*)){
DIR* dp;
struct dirent *sdp;
char path[256];
dp = opendir(dir);
if(dp == NULL){
perror("opendir error");
return ;
}
while((sdp = readdir(dp)) != NULL){
if((strcmp(sdp->d_name,"."))==0 || strcmp(sdp->d_name,"..")==0){//防止出现死循环
continue;
}
//sdp->d_name表示的是文件或者目录的名称
sprintf(path,"%s/%s",dir,sdp->d_name);//更新路径
(*func)(path);//函数指针调用
}
}
int main(int argc,char* argv[]){
if(argc == 1){
isFile(".");
}else{
isFile(argv[1]);
}
return 0;
}
/*执行结果
ubuntu@ubuntu:~/LearnCPP/linux_test/ls_R_test$ ./ls_R_test
./makefile 88
./ls_R_test 9080
./ls_R.c 967
. 4096
*/