【1】复习:
通过标准IO操作文件的流程:
1. 打开文件:fopen/freopen
FILE *fp;
fopen(path, mode);
2. 读写操作:流
1)每次一个字符的读写
fgetc fputc
2)每次一行的读写
fgets fputs
fgets(buf, size, fp);
3)直接IO
fread fwrite
3. 关闭文件
fclose
练习:测试标准输出缓存区的大小
1. for
2. 结构体中有两个成员:stdout->_IO_buf_end - stdout->_IO_buf_base
FILE *
练习:用fgetc和fputc实现cat的功能,从命令行输入文件名.
1)先定义指针FILE *fp
2)打开文件:fopen
3)读文件
int ch;
while((ch = fgetc(fp)) != EOF)
fputc(ch, stdout);
4)关闭文件
练习:用fgets实现wc –l的功能,文件名从命令行输入
1)先定义指针FILE *fp
2)打开文件:fopen
3)读文件
while(fgets(buf, size, fp) != NULL)
{
if(buf[strlen(buf)-1] == '\n')
n++;
}
4)关闭文件
==========================================================
【2】文件的偏移:
int fseek(FILE *stream, long offset, int whence);
功能:设定stream流的文件位置
参数: stream 要偏移的流指针
offset 偏移量
正数:向文件结尾位置移动 负数:向文件开始位置
whence 相对位置
SEEK_SET 开始位置
SEEK_CUR 当前位置
SEEK_END 结尾位置
返回值:成功:0 失败:-1
long ftell(FILE *stream);
功能:取得当前的文件位置
参数:要检测的流
返回值:当前的文件位置,出错则为-1L
void rewind(FILE *stream);
功能:设定流的文件位置指示为文件开始
注意:rewind(fp)的功能和fseek(fp, 0, SEEK_SET)的功能相同
【3】文件IO:
1.定义:
posix(可移植操作系统接口)定义的一组函数
2.特点:
不带缓冲机制,每次操作都引起系统调用
通过文件描述符来访问文件
可以访问Linux下各种类型文件
3.文件描述符:
每个打开的文件都对应一个文件描述符。
文件描述符是一个非负整数。Linux为程序中每个打开的文件分配一个文件描述符。
文件描述符从0开始分配,依次递增。
在文件IO中默认打开了三个文件描述符0,1,2对应标准输入、标准输出、标准出错
【4】打开文件:
int open(const char *pathname, int flags);
功能:打开文件
参数:pathname:文件路径名
flags:打开文件的方式
O_RDONLY:只读
O_WRONLY:只写
O_RDWR:可读可写
O_CREAT:文件不存在创建
O_TRUNC:清空文件内容
O_APPEND:追加
返回值:成功:文件描述符
失败:-1
当open函数的第二个参数指定为O_CREAT时,
需要用下面的函数,给他指定文件权限
int open(const char *pathname, int flags, mode_t mode);
标准IO 文件IO:
r O_RDONLY
r+ O_RDWR
w O_WRONLY|O_CREAT|O_TRUNC,0666
w+ O_RDWR|O_CREAT|O_TRUNC,0666
a O_WRONLY|O_CREAT|O_APPEND,0666
a+ O_RDWR|O_CREAT|O_APPEND,0666
【5】关闭文件:
close(int fd);
【6】读写文件:
#include
ssize_t read(int fd, void *buf, size_t count);
功能:从一个已打开的可读文件中读取数据
参数:fd 文件描述符
buf 存放位置
count 期望的个数
返回值:成功:实际读到的个数
返回-1:表示出错,并设置errno号
返回0:表示读到文件结尾
ssize_t write(int fd, const void *buf, size_t count);
功能:向指定文件描述符中,写入 count个字节的数据。
参数:fd 文件描述符
buf 要写的内容
count 期望值
返回值:成功:实际写入数据的个数
-1:失败
练习:用文件IO实现cp功能,文件名从命令行输入
【7】文件的偏移:
off_t lseek(int fd, off_t offset, int whence);
功能:设定文件的偏移位置
参数:fd:文件描述符
offset偏移量
正数:向文件结尾位置移动
负数:向文件开始位置
whence 相对位置
SEEK_SET 开始位置
SEEK_CUR 当前位置
SEEK_END 结尾位置
返回值:成功:文件的当前位置
失败:-1
练习:
1-- 打开一个文件,不存在创建,存在清零
2-- 向文件中第 10 位置处写一个字符,
3-- 在文件此时的位置,后20个位置处,写一行字符串hello进去
4-- 求文件的长度。
【8】获取文件属性:
int stat(const char *path, struct stat *buf);
功能:获取文件属性
参数:path:文件路径名
buf:保存文件属性信息的结构体
返回值:成功:0
失败:-1
struct stat {
ino_t st_ino; /* inode number */
mode_t st_mode; /* protection */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
off_t st_size; /* total size, in bytes */
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 */
};
S_IRUSR 00400
00400 --> 000 000 100 000 000
if(st_mode & S_IRUSR)
putchar('r');
else
putchar('-');
结果为非0,说明有用户读权限
为0,说明没有读权限
struct group *getgrgid(gid_t gid);
功能:将用户组id转换成组名
struct passwd *getpwuid(uid_t uid);
功能:将用户id转换成用户名
char *ctime(const time_t *timep);
功能:将时间转换成字符串
"Wed Jun 30 21:49:08 1993\n"
练习:编程实现"ls -l file"功能。
【9】目录的操作:
DIR *opendir(const char *name);
功能:获得目录流
参数:要打开的目录
返回值:成功:目录流
失败:NULL
struct dirent *readdir(DIR *dirp);
功能:读目录
参数:要读的目录流
返回值:成功读到的信息 失败NULL
返回值为结构体,该结构体成员为描述该目录下的文件信息
struct dirent {
ino_t d_ino; /* 索引节点号*/
off_t d_off; /*在目录文件中的偏移*/
unsigned short d_reclen; /* 文件名长度*/
unsigned char d_type; /* 文件类型 */
char d_name[256]; /* 文件名 */
};
int chdir(const char *path); 将调用进程当前的工作目录改为path指定的目录。
int closedir(DIR *dirp);
关闭目录流
练习:编程实现ls的功能
作业:
1.复习这两天学习内容
2.编程实现ls -l file功能
3.预习进程