文件的新建定位截短和读写操作

Posted 杨静远

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文件的新建定位截短和读写操作相关的知识,希望对你有一定的参考价值。

 

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;
}

 

以上是关于文件的新建定位截短和读写操作的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段15——git命令操作一个完整流程

VSCode自定义代码片段15——git命令操作一个完整流程

Go语言的文件操作:文件的读写,文件的新建打开和删除

VSCode自定义代码片段——git命令操作一个完整流程

Chrome 实用调试技巧

十文件和目录——文件操作函数(续)