文件IO及常用函数

发布于:2023-10-25 ⋅ 阅读:(76) ⋅ 点赞:(0)
  • 一、文件IO

  • 1、概念

posix(可移植操作系统)提供的一组用于输入输出的函数接口

2、特点:

      没有缓冲机制,每一次读写文件都会进行一次系统调用,

   操作文件用的是文件描述符。

      可以操作linux下的所有文件类型。

    文件IO指的就是系统调用函数接口,不同的操作系统系统调用函数接口不同,标准IO是在文件IO之前封装的libc库函数。

1) 没有缓冲机制,每次调用都会引起系统调用

2) 围绕文件描述符进行操作,非负整数 (>=0),依次分配

3) 文件IO默认打开了三个文件描述符,分别是 0(标准输入),1(标准输出),2(标准错误)

4)操作任意类型的文件b c - l s p   不能操作d

3、文件描述符:

int fileno:文件描述符存储

      用于描述打开文件无符号整型的一个数,取值从0开始,

  (取值范围是0-1023  最多能打开文件个数1024个)。

  默认情况下打开三个文件描述符:

    0、1、2--》标准输入,标准输出,标准出错

 文件描述符的值是连续的,关闭之后可以分配给其他打开的文件使用。

 4、标准IO的操作函数

 open / close   打开文件/关闭文件

read / write   读/写

lseek          文件指针偏移

二、文件IO的函数接口

不同进程打开相同文件,文件指针各不相同

1打开文件 open

int open(const char *pathname, int flags);
当第二个参数中有O_CREAT选项时,需要给open函数传递第三个参数,指定创建文件的权限 
int open(const char *pathname, int flags, mode_t mode);
创建出来的文件权限为指定权限值&(~umask)  //umask为文件权限掩码0002

功能:打开文件
参数:pathname:文件路径名
      flags:打开文件的方式
            O_RDONLY:只读
            O_WRONLY:只写
            O_RDWR:可读可写
            O_CREAT:创建
            O_TRUNC:清空
            O_APPEND:追加 
      mode: 文件权限 八进制表示
返回值:成功:文件描述符
        失败:-1

r:O_RDONLY
R+:O_RDWR
W:只写,文件不存在创建,存在清空:O_WRONLY|O_CREAT|O_TRUNC
W+:可读可写,文件不存在创建,存在清空:O_RDWR|O_CREAT|O_TRUNC
a:追加,在文件末尾写,文件不存在创建:O_APPEND|O_CREAT|O_WRONLY
a+:可读可写可追加,在末尾写,文件不存在创建:O_RDWR|O_APPEND|O_CREAT

系统自动降低文件权限:mode&(~umask) (不同系统:umask大小不同)

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main(int argc, char const *argv[])
{
    int fd=open("./a.txt",O_WRONLY|O_CREAT|O_TRUNC,0666);
    if(fd<0)
    {
        perror("open err");
        return -1;  
    }
    printf("fd = %d\n",fd);
    return 0;
}

2、关闭文件 close -10.24

 #include <unistd.h>
 int close(int fd);

3、读操作 read

#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
功能:从一个已打开的可读文件中读取数据
参数:fd  文件描述符
          buf  存放位置
         count  期望的个数
返回值:成功:实际读到的个数
              返回-1:表示出错,并设置errno号
              返回0:表示读到文件结尾	
使用注意:
read读文件,一般期待读取多少个字节就会读多少个字节,不会补'\0',遇到'\n'不会停止读取,会继续读取下一行数据。遇到'\0'才会停止读取
'\0'需要自己补充,考虑预留一个字节补'\0'.
1、通过返回值作为实际读到字符个数,后补'\0'
   char buf[32];
    ret=read(fd, buf, 31);
    buf[ret]='\0';
2每次读内容放到数组之前先清空数组。

清空函数 memset  bzero

清空函数:memset
#include <string.h>
void *memset(void *s, int c, size_t n);
  功能:清空数组
  参数:
       s:要清空内容的首地址
       c:一般写0;数组空间设置为其他值
       n:清空的字节数
  返回值:清空内容的首地址,失败NULL
清空函数:bzero
       #include <strings.h>
       void bzero(void *s, size_t n);
功能: bzero()函数将从s开始的区域的前n个字节设置为零(包含'\o'的字节)
参数:
    s:要清空内容的首地址
    n:清空的字节数

4、写操作 write

#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
功能:向指定文件描述符中,写入 count个字节的数据。
参数:fd   文件描述符
          buf   要写的内容
          count  期望值
返回值:成功:实际写入数据的个数
              失败  : -1 更新error
练习:利用read和write函数实现cp功能。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{
    int fd_src,fd_test;
    fd_src=open(argv[1],O_RDONLY);
    if(fd_src<0)
    {
       perror("open src err.");
       return -1;
    }
   fd_test=open(argv[2],O_WRONLY|O_CREAT|O_TRUNC,0777);
   if(fd_test<0)
   {
       perror("open test err.");
       return -1;
   }
    char buf[32];
    int ret;
   //循环读源文件,写到复制生成的文件
   #if 0
   while(ret=read(fd_src,buf,sizeof(buf)))
   {
        write(fd_test,buf,ret);//ret:读多少写多少
   }
   #endif
   #if 1
   while(ret=read(fd_src,buf,sizeof(buf)-1))
   {
       buf[ret]='\0';
        write(fd_test,buf,strlen(buf));
   }
   #endif
    close(fd_src);
    close(fd_test);
    return 0;
}

5、定位操作 lseek

#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
功能:设定文件的偏移位置	
参数:fd:文件描述符
	offset偏移量  				
		正数:向文件结尾位置移动
		负数:向文件开始位置
	whence  相对位置
		SEEK_SET   开始位置
		SEEK_CUR   当前位置
		SEEK_END   结尾位置
返回值:成功:文件的当前位置相对于开头位置的字节数
	      失败:-1

/*
O_RDONLY :只读
O_WRONLY:只写
O_RDWR:可读可写

O_CREAT:创建
O_TRUNC:清空
O_APPEND:追加

r:只读.O_RDONLY
r+:可读可写,文件不存在报错。O_RDWR
w:只写,文件不存在创建,存在清空,O_WRONLY|O_CREAT|O_TRUNC
w+:可读可写,文件不存在创建,存在清空 O_RDWR|O_CREAT|O_TRUNC
a:文件不存在创建,存在追加 O_WRONLY|O_CREAT|O_APPEND
a+:可读可追加,文件不存在创建,存在追加 0_RDWR|O_CREAT|O_APPEND
 */
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
int main(int argc, char const *argv[])
{
    //打开文件
    //当第二个参数中有O_CREAT选项时,需要第三个参数
    // int fd = open("a.txt",O_RDONLY);
    // if(fd<0)
    // {
    //     perror("open err");
    //     return -1;
    // }
    // printf("fd:%d\n",fd);
    int fd = open("b.txt",O_RDWR|O_CREAT|O_TRUNC,0666);
    if(fd<0)
    {
        perror("open err");
        return -1;
    }
    printf("fd:%d\n",fd);
    //读写操作
    write(fd,"hello\n",6);
    char buf[32]={0};
    //将文件指针移动到开头
    lseek(fd,0,SEEK_SET);
    ssize_t s =read(fd,buf,32);
    printf("%d %s\n",s,buf);
    //lseek返回值是当前位置前字符个数
    off_t len = lseek(fd,0,SEEK_END);
    printf("%ld\n",len);
    //关闭文件
    close(fd);
    return 0;
}


网站公告

今日签到

点亮在社区的每一天
去签到