C语言函数库中访问文件需声明一个文件指针:
FILE *fp;
fp = fopen(name, mode);
这里fopen函数:
FILE *fopen(char *name, char *mode);
第一个参数是一个字符串,包含文件名。第二个参数为访问模式,有读"r"、写"w"、追加"a"。如果要读取或写入单个字符或行,要调用getc、putc、fgets、fputs函数。fgets并不是完全意义上的读取行,而是最多将n-1个字符读入数组中,当遇到换行符时将换行符读入到数组,读取过程终止。在UNIX\LINUX下可以用fread和fwrite函数进行读写。(第1次修改加)
在UNIX\LINUX系统中,对文件的输入、输出都是通过文件描述符标识文件,而不是通过文件名。当shell运行一个程序时,它将打开3个文件,对应的文件描述符分别为0、1、2,依次表示标准输入、标准输出、标准错误。
在在UNIX\LINUX系统中,访问文件用open函数,它与fopen不同,fopen返回一个文件指针,open返回一个文件描述符,是int类型的数值,若发生错误返回-1.
int fd;
fd = open(name, flags, perms);
open函数为:
int open(char *name, int flags, int perms);
第一个参数与fopen一样是包含文件名的字符串。第二个参数是一个int类型的值,主要如下:
O_RDONLY 只读打开
O_WRONLY 只写打开
O_RDWR 读写打开
perms一般为0,它是文件权限,书中并未在此深入探讨。
如果在linux下man 2 open,就会发现没有第三个参数也是可以的:(第1次修改加)
int open(const char *pathname, int flags);
生成一个文件用creat:
int creat(char *name, int perms);
若成功建立一个文件,则返回文件描述符,否则返回1.如果此文件已存在,creat将把该文件的长度截断为0,从而丢弃原先已有内容(相当于覆盖)。perms为指定生成文件的权限,详细请看linux下权限的讲解。
读写文件用read和write:
int read(int fd, char *buf, int n);
int write(int fd, char *buf, int n);
这里需要BUFSIZ这个参数,具体根据不同系统定义在不同的头文件中,详细请man read等。两个函数参数一样,第二个为程序中存放读或写的数据的字符数组,第三个参数要传输的字节数。一般为:
int n,fd1,fd2;
char buf[BUFSIZ];
fd1 = open(name, O_RDONLY, 0);
n = read(fd1, buf, BUFSIZ);
fd2 = creat(name2, perms);
write(f2, buf, n);
以上程序并不完整。
若read的第一个参数为0,则为从标注输入(从键盘);若write的第一个参数为1,则为标准输出(屏幕)。
close函数关闭已打开的函数,类似fclose,但它不需要清洗缓冲区。若程序通过exit函数退出或从主函数中返回,所有打开的文件将被关闭。
附练习8-1:
用read、write、open和close系统调用代替标准库中功能等价的函数,重写第7章的cat程序,并通过实验比较两个版本的相对执行速度。
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#define IN 0
void filew(int ifp);
void error(char *, ...);
main(int argc, char *argv[])
{
int fp, n;
char *prog = argv[0];
if (argc == 1)
filew(IN);
else
while (--argc > 0)
if ((fp = open(*++argv, O_RDONLY, 1)) == NULL) {
fprintf(stderr, "%s: can't open %s\n", prog, *argv);
exit(1);
}
else {
filew(fp);
close(fp);
}
exit(0);
}
void filew(int ifp)
{
int n;
char buf[BUFSIZ];
while ((n = read(ifp, buf, BUFSIZ)) > 0)
if (write(1, buf, n) != n)
error("can not output!\n");
}