普通文件: -
目录文件: d
符号链接文件:l
套接字: s
管道: p
块设备: b
字符设备: c
文件描述符: 非负整数,是打开的文件的标识符(编号) --- 用于文件IO
文件流: FILE * (标准IO)
进程中有三个文件已打开:
文件描述符 文件流
标准输入 : 0 stdin
标准输出 : 1 stdout
标准错误输出 : 2 stderr
printf(char *format, ....); ---- 把...按照格式输出到标准输出(终端)
sprintf(char *str, char *format, ....); --- 把...按照格式输出到str中
fprintf(FILE *fp, char *format, ....); --- 把...按照格式输出到文件流中
```
#include
void perror(const char *s); --- 打印系统错误信息
参数: 提示符(一般函数名)
#include
char *strerror(int errnum); ---- 返回错误码对应的错误信息
标准IO: 带缓冲的IO
全缓冲:缓冲区满/fflush(强制刷新)
行缓存:'\n'/缓冲区满/fflush(强制刷新)
不缓冲
```
- #include
- #include
- #include
-
- int main(int argc, char *argv[])
- {
- FILE *fp=fopen("file_3","w+");
- if(NULL==fp)
- {
- perror("fopoen");
- return -1;
- }
- printf("fopne success!\n");
-
- fclose(fp);
- return 0;
- }
- #include
- #include
- #include
-
- int main(int argc, char *argv[])
- {
- FILE *fp=fopen("test.c","r");
- if(NULL==fp)
- {
- perror("fopen");
- return -1;
- }
- printf("fopen success!\n");
-
- int ch;
- while(1)
- {
- ch=fgetc(fp); //从fp中读取一个字符,文件末尾为EOF
- if(EOF==ch)
- break;
- fputc(ch,stdout); //向标准输出写入一个字符
- }
-
-
- fclose(fp);
- return 0;
- }
- #include
-
- int main(int argc, char *argv[])
- {
- char buf[100];
- //gets(buf);
- //fgets(buf, sizeof(buf), stdin);
- //printf("%s", buf);
-
- if (argc < 2)
- {
- fprintf(stderr, "Usage: %s
" , argv[0]); - return -1;
- }
- FILE *fp = fopen(argv[1], "r");
- if (NULL == fp)
- {
- perror("fopen");
- return -1;
- }
-
- while (1)
- {
- if (NULL == fgets(buf, sizeof(buf), fp))
- break;
- fputs(buf, stdout);
- }
-
- fclose(fp);
-
-
- return 0;
- }
char *fgets(char *s, int size, FILE *stream); //从流中读取size-1个字符装在s中
注:fgets用于读取一行,遇'\n'结束,且=='\n'==也会被装在s中
fgets最多只能输入size-1个字符,末尾装null
当读取到文件末尾时返回NULL
#include
int fseek(FILE *stream, long offset, int whence); //定位
参数: stream: 文件流
offset: 偏移量
whence: 基准(SEEK_SET文件头, SEEK_CUR当前位置S, SEEK_END文件尾)
返回值:
成功: 0
失败: -1, 并设置errno
long ftell(FILE *stream); //获取当前流的偏移量
void rewind(FILE *stream); //偏移到文件头位置
#include
#include
#include
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
- #include
- #include
- #include
- #include
- #include
- #include
- #include
-
- int main(int argc, char *argv[])
- {
- //int fd=open("1.txt",O_RDONLY); //"r"
- int fd=open("1.txt",O_WRONLY|O_CREAT|O_TRUNC,0664);
- if(fd<0)
- {
- perror("open");
- return -1;
- }
- printf("fd=%d\n",fd);
- close(fd);
- return 0;
- }
pathname: 路径 + 文件名
flags: 打开方式
O_RDONLY: 只读打开
O_WRONLY: 只写打开
O_RDWR: 可读写打开
O_CREAT: 当文件不存在时创建文件,此时需要第三个参数mode
O_TRUNC: 当文件存在时清空文件内容
O_APPEND: 追加打开
mode: 创建的文件的权限,一般0664
返回值:
成功: 文件描述符(非负整数)
失败: -1, 并设置errno
#include
int close(int fd); //参数: 文件描述符
#include
ssize_t read(int fd, void *buf, size_t count); //从fd文件中读取count字节放在buf中
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- int main(int argc, char *argv[])
- {
- int fd=open("./1.txt",O_RDONLY);
- if(fd<0)
- {
- perror("open");
- return -1;
- }
-
- lseek(fd,100,SEEK_SET); //lseek函数,从文件头开始偏移量100
- char buf[64];
- int ret;
- while(1)
- {
- ret=read(fd,buf,sizeof(buf));
- if(ret<0)
- {
- perror("read");
- break;
- }
- else if(0==ret)
- {
- printf("read file end!\n");
- break;
- }
- if(0>write(1,buf,ret))//向标准输出写入数据
- {
- perror("write");
- break;
- }
- }
- close(fd);
- return 0;
- }
参数:
fd --- 文件描述符
buf --- 内存中用于存放读取数据的空间首地址
count --- 想要读取的字节数
返回值:
成功:成功读取的字节数
0(当读取到文件末尾时)
失败:-1, 并设置errno
#include
ssize_t write(int fd, const void *buf, size_t count); //把buf中的count字节数据写入文件fd中去
参数:
fd --- 文件描述符
buf --- 想要写入数据的首地址
count --- 想要写入的字节数
返回值:
成功:成功写入的字节数
失败:-1, 并设置errno
```
off_t lseek(int fd, off_t offset, int whence); //定位
参数:
fd: 文件描述符
offset: 偏移量
whence: 基准(SEEK_SET文件头, SEEK_CUR当前位置, SEEK_END文件尾)
返回值:
成功: 当前的偏移量
失败: -1, 并设置errno
#include
#include
#include
int stat(const char *pathname, struct stat *statbuf); //获取文件属性
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* Inode number */
mode_t st_mode; /* File type and mode */
nlink_t st_nlink; /* Number of hard links */
uid_t st_uid; /* User ID of owner */
gid_t st_gid; /* Group ID of owner */
dev_t st_rdev; /* Device ID (if special file) */
off_t st_size; /* Total size, in bytes */
blksize_t st_blksize; /* Block size for filesystem I/O */
blkcnt_t st_blocks; /* Number of 512B blocks allocated */
};
注:使用下面的宏函数可以判断文件的类型:参数为struct stat的st_mode成员
S_ISREG(st_mode); --- 判断是否是普通文件
S_ISDIR(st_mode) directory?
S_ISCHR(st_mode) character device?
S_ISBLK(st_mode) block device?
S_ISFIFO(st_mode) FIFO (named pipe)?
S_ISLNK(st_mode) symbolic link? (Not in POSIX.1-1996.)
S_ISSOCK(st_mode) socket? (Not in POSIX.1-1996.)
```
int system(char *commad); //执行shell命令
int chdir(char *path); //切换当前的工作路径,类似与cd命令
参数:
path: 要切换的路径
返回值:
成功: 0
失败: -1, 并设置errno
#include
#include
DIR *opendir(const char *name); //打开目录
参数:
name: 目录名
返回值:
成功:目录流指针
失败:NULL, 并设置errno
int closedir(DIR *dirp); //关闭目录
参数:
dirp: 目录流指针
struct dirent *readdir(DIR *dirp); //读取目录
struct dirent {
ino_t d_ino; /* Inode number */
off_t d_off; /* Not an offset; see below */
unsigned short d_reclen; /* Length of this record */
unsigned char d_type; /* Type of file; not supported
by all filesystem types */
char d_name[256]; /* Null-terminated filename */
};
- #include
- #include
- #include
- #include
- #include
-
- int main(int argc, char *argv[])
- {
- DIR *dirp=opendir(".");//打开目录
- if(NULL==dirp)
- {
- perror("dirp");
- return -1;
- }
- struct dirent *p=NULL;
- while(1)
- {
- p=readdir(dirp);//读取目录下的内容
- if(NULL==p)
- {
- break;
- }
- if('.'==p->d_name[0])//跳过所有的隐藏文件
- continue;
- printf("name:%s\n",p->d_name);//关闭目录
-
- }
-
- closedir(dirp);//
- return 0;
- }
返回值:
读取的文件dirent结构体指针
当读取到目录流结束时,返回NULL
```
(1)把常用的复杂的功能封装成库,用户只需要使用库,不需要理解内部原理
(2)库是别人写好的现有的,成熟的,可以复用的代码,你可以使用但要记得遵守许可协议
(1)静态库与动态库链接进目标代码的时机不同,静态库在编译时期,动态库在执行时期
(2)静态库占空间大,但是移植方便
(3)动态库占空间小
gcc -c 源文件 ---- 生成目标文件.o
ar crs lib库名.a 目标文件 ---- 把目标文件生成静态库文件
注: 静态库的库前缀lib,后缀.a
gcc 源文件 -L库路径 -l库名 --- 静态库的使用
gcc -fPIC -Wall -c 源文件 ---- 生成与地址无关的目标文件.o
gcc -shared -o libmytest.so 目标文件 --- 把目标文生成动态库文件
注: 动态库的库前缀lib,后缀.so
编译:gcc 源文件 -L库路径 -l库名
为了让执行程序顺利找到动态库,有三种方法 :
(1)把库拷贝到/usr/lib和/lib目录下。
(2)在LD_LIBRARY_PATH环境变量中加上库所在路径。
export LD_LIBRARY_PATH=库路径
(3) 添加/etc/ld.so.conf.d/*.conf文件,把库所在的路径加到文件末尾,并执行ldconfig刷新。这样,加入的目录下的所有库文件都可见。