缓冲:
setvbuf
#include <stdio.h>
int setvbuf(FILE *stream, char *buf, int mode, size_t size);
功能:更改缓冲区类型
返回值:0成功,非0失败
stream:流(输入流、输出流)
buf:指定缓冲区地址(默认为NULL)
mode:缓冲模式(全缓冲4096字节、行缓冲1024字节、无缓冲)_IOFBF、_IOLBF、_IONBF
size:缓冲区大小
fflush
#include <stdio.h>
int fflush(FILE *fp);
强制刷新一个流(清空)
标准流:
文件IO(int) 标准IO(FILE*)
标准输入: 0 stdin
标准输出: 1 stdout
标准出错: 2 stderr
标准IO库:
fopen
#include <stdio.h>
FILE *fopen(const char *pathname, const char *mode);
功能:内核打开一个文件,并以流的形式来标记
返回值:成功返回流指针,失败返回NULL
pathname:文件路径名
mode:打开方式
r 只读
r+ 读写
w 写(有内容会覆盖)(打开时就清空)
w+ 读写(不存在会创建,写入有内容会覆盖)(打开时就清空)
a 追加
a+ 追加读
b:以二进制的方式打开
freopen
FILE *freopen(const char *pathname, const char *mode, FILE *stream);
功能:修改当前的流(将老的流修改为新的流)(重定向)
pathname:新的文件路径名
mode:打开方式
stream:已经存在的流
fclose
#include <stdio.h>
int fclose(FILE *stream);
功能:通过流指针关闭打开的文件
返回值:成功为0,失败为EOF(实则为-1)
stream:已经打开的流指针
读:
#include <stdio.h>
int fgetc(FILE *stream);
功能:从流中读取一个字符
返回值:成功返回一个ASCII码(int),失败为EOF
stream:已经打开的流指针
char *fgets(char *s, int size, FILE *stream);
功能:从流中读取一个字符串(一行一行读,行末尾会自动添加'\n',字符串末尾添加'\0')
(当预计读的个数比实际字节个数多一个,只会有'\0')
(当预计读的个数比实际字节个数多两个,先有'\n',再有'\0')
(最短为2,为1时只有'\0')
返回值:成功返回字符指针(字符串),失败为NULL
s:用来存储字符串
size:字符串长度
stream:已经打开的流指针
#include <string.h>
void *memset(void *s, int c, size_t n);
memset(arr,0,sizeof(arr));//清空字符串
写:
#include <stdio.h>
int fputc(int c, FILE *stream);
功能:向流中输出一个字符
返回值:成功返回ASCII码,失败为EOF
c:字符ASCII码
stream:已经打开的流指针
int fputs(const char *s, FILE *stream);
功能:向流中输出一个字符串(按行写)
返回值:成功返回1,失败为EOF
s:输出的字符串
stream:已经打开的流指针
int fprintf(FILE *stream, const char *format, ...);//其后的参数与printf一致
功能:向流中输出内容,将数据转为字符写入
返回值:成功返回打印的字符的个数,失败为负
stream:要写的流
format:字符指针
int sprintf(char *str, const char *format, ...);//其后的参数与printf一致
功能:向缓冲区中输出内容,将数据转为字符写入
返回值:成功返回打印的字符的个数,失败为负
str:缓冲区地址
format:字符指针
按对象读写:
读:
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:从流中读取内容,按对象读
返回值:成功返回实际读到的对象个数,失败返回非正数
ptr:缓冲区地址(存放读入内容的地址)
size:每个对象有几个字节
nmemb:预计要读多少个对象
stream:要读的流
写:
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:向流中输出内容,按对象写(一个字节一个字节写入)
返回值:成功返回实际输出的对象个数,失败返回非正数
ptr:缓冲区地址(存放输出内容的地址)
size:每个对象有几个字节
nmemb:预计要写多少个对象
stream:要写的流
报告文件内光标位置:
long ftell(FILE *stream);//返回当前光标位置
文件偏移:
int fseek(FILE *stream, long offset, int whence);
功能:光标移动
返回值:成功返回0,失败为-1
offset:偏移量
whence:基础位置(SEEK_SET 头, SEEK_CUR 当前位置, SEEK_END 尾)
文件IO:
直接的系统调用
open/close/read/write/lseek
#include <fcntl.h>
int open(const char *pathname, int flags, mode_t mode);
功能:站在内核的角度打开一个文件,并产生一个文件描述符
(文件描述符:内核用于标记已打开的文件的数字,类似与流,其值为最小的非负整数)
0-->标准输入
1-->标准输出
2-->标准出错
pathname:文件路径
flags:打开方式或权限(可以多选必须包括前三O_RDONLY 只读, O_WRONLY 只写, O_RDWR 读写, O_CREAT 不存在则创建,O_TRUNC 覆盖)
mode:创建时的权限( 当选择O_CREAT时需要填写)(如0777,使用这个权限 与上 umask取反 才是实际的权限)(先对umask取反再与)
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
功能:从打开的文件描述符中读取内容
返回值:成功返回读到的字节数,失败为-1
fd:文件描述符
buf:存放读取的内容
count:预计读到的字节(不能超过buf的大小)
ssize_t write(int fd, void *buf, size_t count);
功能:往打开的文件描述符中写内容
返回值:成功返回写入的字节数,失败为-1
fd:文件描述符
buf:存放将要写入的内容
count:预计写到的字节(不能超过buf的大小)
int close(int fd);
功能:关闭已经打开的文件描述符
返回值:成功返回0,失败为-1
fd:文件描述符
off_t lseek(int fd, off_t offset, int whence);
功能:光标移动
返回值:成功返回非负整数,失败为-1
fd:文件描述符
offset:偏移量
whence:基础位置(SEEK_SET 头, SEEK_CUR 当前位置, SEEK_END 尾)
#include <dirent.h>
DIR *opendir(const char *name);
功能:打开一个目录文件,并产生一个专用于目录的流
返回值:成功返回目录指针,失败为NULL
name:目录路径
struct dirent *readdir(DIR *dirp);
功能:读一次目录流,得到一个文件的信息
返回值:成功一个dirent结构体指针类型,失败为NULL
dirp:已经打开的目录流
动态库和静态库的分析(默认动态库)
静态库:包含所有文件(加密后的二进制文件)
gcc -c hello.c -o hello.o//生成二进制文件
ar crs libmyhello.a hello.o//将二进制文件转为静态库
gcc main.c -L. -lmyhello(-L库的路径,-l库的名字,要去掉lib与.a)//编译(若动态库静态库重名-static改为静态库)
-I(i) :指定头文件的路径
-L:指定库文件的路径
-l:链接某个具体的库(库名字)
动态库:在运行时才链接相关文件(要有相应环境)
gcc -fPIC -Wall -c test.c(-fPIC创建与地址无关的编译程序)//使二进制与地址无关,方便链接库时直接插入
gcc -shared -o libmytest.so test.o//创建动态库
gcc main.c -L. -lmytest//编译
//需要系统能够在运行程序的时候找到动态库
可以把动态库文件放在/lib或者/usr/lib/目录下,这样可以直接找到。
也可以创建一个临时的文件:/etc/ld.so.conf.d/my.conf 在这个文件中写上动态库的路径
保存后ldconfig刷新库的环境变
补充:
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *pathname, struct stat *statbuf);//若路径为一个链接文件,实际上是返回被链接文件的信息
int fstat(int fd, struct stat *statbuf);//文件描述符
int lstat(const char *pathname, struct stat *statbuf);//若路径为一个链接文件,返回链接文件的自身的信息
功能:获取文件信息
返回值:成功0,失败-1
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 */
/* Since Linux 2.6, the kernel supports nanosecond
precision for the following timestamp fields.
For the details before Linux 2.6, see NOTES. */
struct timespec st_atim; /* Time of last access */
struct timespec st_mtim; /* Time of last modification */
struct timespec st_ctim; /* Time of last status change */
#define st_atime st_atim.tv_sec /* Backward compatibility */
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
};
部分代码示例
标准IO
//fopen
#include <stdio.h>
int main()
{
FILE *fp=fopen("text01.txt","w+");
if(fp==NULL)
{
perror("text01.txt");
return -1;
}
}
//fgetc fputc 拷贝文件
#include <stdio.h>
int main(int argc, char *argv[])
{
if(argc<3)
{
printf("%s src_file dest_file",argv[0]);
return -1;
}
FILE *fp01 = fopen(argv[1],"r");
if(fp01==NULL)
{
perror("src_file");
return -1;
}
FILE *fp02 = fopen(argv[2],"w");
if(fp02==NULL)
{
perror("dest_file");
return -1;
}
char ch;
while(1)
{
ch=fgetc(fp01);
if(ch==EOF)
{
break;
}
fputc(ch,fp02);
}
return 0;
fclose(fp01);
fclose(fp02);
}
//fread fwrite 拷贝文件
#include <stdio.h>
int main(int argc, char *argv[])
{
if(argc<3)
{
printf("%s file_src file_dest\n",argv[0]);
return -1;
}
FILE *fp_src = fopen(argv[1],"r");
if(fp_src==NULL)
{
perror("fp_src");
return -1;
}
FILE *fp_dest = fopen(argv[2],"w");
if(fp_dest==NULL)
{
perror("fp_dest");
return -1;
}
int ret = -1;
int arr[50];
while(1)
{
ret = fread(arr,1,sizeof(arr),fp_src);
if(ret<=0)
{
perror("fread");
break;
}
fwrite(arr,1,ret,fp_dest);
}
return 0;
}
文件IO
//open read write 拷贝文件
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int fd01 = open(argv[1],O_RDONLY);
int fd02 = open(argv[2],O_WRONLY);
char buf[50];
int ret;
while(1)
{
ret = read(fd01,buf,sizeof(buf));
if(ret<=0)
{
break;
}
write(fd02,buf,ret);
}
return 0;
}
//lseek 在当前光标位置写入(覆盖)
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int fd = open(argv[1],O_RDWR);
char buf[10];
read(fd,buf,10);
lseek(fd,0,SEEK_CUR);
write(fd,"start_insert:",14);
write(fd,buf,10);
return 0;
}