文件的新建、定位、截短和读写操作
1.创建一个新文件,创建新文件除了可以使用open函数之外还可以用creat()函数。
创建文件函数 creat(const char * pathname, mode_t mode)
头文件 :#include <fcntl.h>
参数说明:第一个参数pathname同open函数的第一个参数具有同样的意义,区别在于这是需要创建的文件的地址而不是需要打开文件的地址,第二个参数mode是新建文件的访问权限。
返回值:成功返回1,失败返回-1。
函数说明:creat()函数能够创建一个新的文件,并且创建的同时设置文件的访问权限。需要注意的是crete函数只能以只写的方式打开新创建的文件,如果需要对文件进行读操作需要先关闭文件,再重新以读的方式打开。
应用实例:使用creat()函数创建一个空文件
#include <stdio.h> #include <stdlib.h> #include <fcntl.h> int main(void) { int fd; fd = creat("test.txt", 0700); /* 创建一个新文件,使用权限字为700 */ if(fd == -1){ perror("fail to creat"); exit(1); }else printf("creat OK\n"); /* 输出提示信息 */ return 0; }
2.文件的定位操作,每打开一个文件都有一个与其相关的文件偏移量,一般是一个非负整数,所有的操作都是从当前文件的偏移量开始的,并且使偏移量增加。系统默认下,打开文件的偏移量为0,在Linux系统中使用lseek()函数更改文件的偏移量。
lseek(int filedes, off_t offset, int whence) 函数:
头文件 #include <unistd.h>
参数:第一个参数filedes是已经打开文件的描述符,第二个参数offset的意义与第三个参数有关,第三个参数whence:
如果whence 是 SEEK_SET,文件偏移量将被设置为offset。
如果 whence 是 SEEK_CUR,文件偏移量将被设置为当前文件偏移位置加offset,offset可以为正也可以为负。
如果 whence 是 SEEK_END,文件偏移量将被设置为文件长度加上 offset,offset 可以为正也可以为负。
返回值:成功返回新的偏移量,失败返回-1。
应用实例:下面实例使用lseek得到当前文件的偏移值,得到未进行任何操作的偏移值;然后读取5个字节内容,再调用lseek函数得到文件的读写位置。
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <fcntl.h> #include <unistd.h> #define MAX 1024 int main(void) { int fd; off_t off; char buf[MAX]; fd = open("test.txt", O_RDWR); /* 打开一个文件 */ if(fd == -1){ perror("fail to open"); exit(1); } printf("before reading\n"); /* 输出提示信息 */ off = lseek(fd, 0, SEEK_CUR); /* 调用lseek函数得到当前文件的读写位置 */ if(off == -1){ perror("fail to lseek"); exit(1); } printf("the offset is : %d\n", (int)off); /* 输出提示信息 */ if(read(fd,buf, 5 ) == -1){ /* 读取5个字节的文件内容 */ perror("fail ot read"); exit(1); } printf("after reading\n"); /* 输出提示信息 */ off = lseek(fd, 0, SEEK_CUR); /* 再次调用lseek函数得到当前文件的读写位置 */ if(off == -1){ perror("fail to lseek"); exit(errno); } printf("the offset is : %d\n", (int)off); /* 输出结果 */ close(fd); /* 关闭文件 */ return 0; }
3.文件的截短操作,截短文件是为了保证某一个文件大小在一定的范围内,超过该字节数就要对文件进行截短操作。在Linux系统中使用truncate函数截短一个文件。
truncate(const char * pathname, off_t length) 函数:
头文件 #include <unistd.h>
参数说明:第一个参数pathname表示文件路径,与open函数相同,第二个参数length表示截短的字节数,超过该字节的部分被系统放弃。
返回值:成功返回0,石板返回-1。
函数说明:如果要截短的文件超过要截短的字节数,超过的部分被系统放弃;如果文件的实际大小小于指定的值,系统会自动拓展该文件,形成一个文件空洞。
应用实例:下面实例程序演示截短一个已经存在的文件,该文件实际大小小于指定值,先拓展该文件,再向文件空洞中填充内容,并写到外围设备中。
#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #define MAX 32 int main(int argc, char *argv[ ]) { int fd; int len; int rest; int i; char buf[MAX]; if(argc != 3){ /* 根据命令行参数设置扩展后的文件字节数和需要填充的字节数 */ len = MAX; rest = 0; }else{ len = atoi(argv[1]); rest = atoi(argv[2]); } if(truncate("test.txt", len) == -1){ /* 截短操作,将文件拓展为指定字节数 */ perror("fail to truncate"); exit(1); } /* 添加写方式打开文件,每次写的内容会自动添加到文件的结尾 */ fd = open("test.txt", O_RDWR | O_APPEND); if(fd == -1){ perror("fail to open"); exit(1); } i = 0; while(i < rest){ /* 设置填充内容,余下的文件内容填充为字符‘0’ */ buf[i] = '0'; i++; } if(write(fd, buf, rest) == -1){ /* 填充文件 */ perror("fail to write"); exit(1); } close(fd); /* 关闭文件 */ return 0; }
4.文件的读写操作
Linux系统中使用 read(int filedes, void * buf, size_t nbytes) 函数进行文件的读操作:
头文件: #include <unistd.h>
参数说明:第一个参数是文件描述符,表示是从哪个文件中读取,该文件一定是一个具有读打开的文件。第二个参数buf是缓冲区,将文件内容读入到该缓冲区,第三个参数nbytes表示需要读的字节数。
返回值:返回值是实际读出的字节数,分三种情况:
从指定文件中读入nb个字节,返回值与参数nb相等;文件剩余字节小于nb,返回值是实际读出的字节数,如果文件已经达到末尾则返回0;读操作出现错误,返回-1。
Linux系统中使用 write(int int filedes, void * buf, size_t nbytes) 函数进行文件的写操作:
头文件: #include <unistd.h>
参数说明:第一个参数是文件描述符,表示是写到哪个文件中,该文件一定是一个具有写打开的文件。第二个参数buf是缓冲区,将该缓冲区内容写入到文件中,第三个参数nbytes表示需要写的字节数。
返回值:成功返回实际写到文件中的字节数,出错返回-1。
应用实例:下面用文件读写操作实现一个简单的cp命令,也就是复制。
#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> /* linux cp命令的简单实现,命令格式:cp des src * 成功返回0,失败返回-1,失败原因保存在errno中 * argv[1] : 目标文件名des(本例使用绝对路径) * argv[2]: 源文件名src(本例使用绝对路径) */ #define MAX 30 int main(int argc, char *argv[]) { char buf[MAX]; int in, out; /* 输入文件和输出文件 */ int n; if(argc != 3) exit(1); if((in = open(argv[2], O_RDONLY)) == -1) {/* 源文件,“只读”打开 */ perror("fail to open"); exit(1); } /* 目标文件,该文件不存在则创建,该文件存在则覆盖且只写打开 */ if((out = open(argv[1], O_WRONLY | O_TRUNC | O_CREAT)) == -1){ perror("fail to open"); exit(1); } while((n = read(in, buf, MAX)) > 0) /* 读入文件 */ if((write(out, buf, n)) != n){ /* 实际写出字节数不等于n,写出错 */ perror("fail to write"); exit(1); } if(n < 0){ /* 读入出错 */ perror("fail to read"); exit(1); } printf("copy done\n"); /* 输出提示信息 */ close(in); /* 关闭两个文件 */ close(out); return 0; }