Linux操作系统——文件操作(3)

一、文件IO

文件IO:系统调用
Linux内核专门为应用层提供的文件操作方法。

二、文件IO基本操作

打开文件和关闭文件

打开文件         open

包含的头文件:

       #include <sys/types.h>
       #include <sys/stat.h>
       #include <fcntl.h>

函数用法:

       int open(const char *pathname, int flags);
       int open(const char *pathname, int flags, mode_t mode);
       功能:打开文件并获得一个文件描述符
       参数:
                 pathname:要打开的文件的文件名
                 flags:打开方式
                       O_RDONLY : 只读方式
                       O_WRONLY:只写方式
                       O_RDWR:  可读可写
                       O_CREAT:  创建文件
                       O_TRUNC:  清空文件
                       O_APPEND: 追加写
                 
                    标准IO:         文件IO:
                     "r"                    O_RDONLY 
                     "r+"                  O_RDWR
                     "w"                   O_WRONLY | O_CREAT |  O_TRUNC, 0664
                     "w+"                 O_RDWR | O_CREAT |  O_TRUNC, 0664
                     "a"                     O_WRONLY | O_APPEND | O_CREAT, 0664
                     "a+"                  O_RDWR |  O_APPEND | O_CREAT,0664
            mode:文件读写执行操作权限(当flag中有O_CREAT标志时,必须要增加mode操作限)

eg:
                                  rwxrwxrwx
                                  111 111 111  --->0777
                                  rw-rw-r--
                                  110 110 100 --->0664
                                  (mode & ~umask)
                                  111 111 111                                    110 110 100
                              & 111 111 101                                & 111 111 101
                                   111 111 101 ----》0775                110 110 100----》0664
       返回值:
                成功:文件描述符 
                失败:-1

文件描述符:

        操作系统中已打开文件的标识符。
        小的、非负的整形数据
        范围:0-1023 (总共1024个)
        分配原则:最小未被使用原则
        文件描述符泄露:已打开的文件,使用完时,未及时关闭。

操作系统已经打开的三个文件占用了0、1、2这三个文件描述符:

        标准IO:                                        文件IO
        FILE *                                          int
        stdin  ---->标准输入设备 -----》0
        stdout ---->标准输出设备-----》1
        stderr ---->标准出错设备-----》 2

关闭文件      close

包含的头文件:

 #include <unistd.h>
 函数用法:

int close(int fd);
      功能:关闭文件

#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 = open("1.txt", O_WRONLY | O_CREAT | O_TRUNC, 0664);
    if(-1 == fd)
    {
        printf("open error\n");
    }
 
    printf("fd = %d\n", fd);
 
    close(fd);
 
    return 0;
}

读写文件

ssize_t write(int fd, const void *buf, size_t count);
      功能:向文件中写入数据
      参数:
            fd:文件描述符
            buf:要写入的数据的首地址
            count:要写入的字节数

       返回值:
            成功:实际写入的字节数
            失败:-1


     ssize_t read(int fd, void *buf, size_t count);
     功能:从文件中读取数据
     参数:
         fd:文件描述符
         buf:存储数据的空间首地址
         count:希望读取的字节数
     返回值:
          成功:实际读到的字节数
          失败:-1
          读到文件末尾:0

 
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
 
int main(int argc, const char *argv[])
{
	write(1, "hello world", 11);
 
	return 0;
}
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
 
int main(int argc, const char *argv[])
{
	int fd = open("1.txt", O_RDONLY);
	if (fd < 0)
	{
		printf("open error\n");
		return -1;
	}
	
	char buff[1024] = {0};
 
	ssize_t cnt = read(fd, buff, sizeof(buff));
	printf("cnt = %ld\n", cnt);
	printf("buff = %s\n", buff);
 
	close(fd);
	return 0;
}

文件的拷贝

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
 
 
int main(int argc, const char *argv[])
{
	if (argc < 2)
	{
		printf("Usage : ./a.out <filename>\n");
		return -1;
	}
 
	int fd = open(argv[1], O_RDONLY);
	if (fd < 0)
	{
		printf("open error\n");
		return -1;
	}
	
	char buff[1024] = {0};
	
	while (1)
	{
		ssize_t cnt = read(fd, buff, sizeof(buff));
		if (0 == cnt)
		{
			break;
		}
		else if (-1 == cnt)
		{
			printf("read error\n");
			break;
		}
		write(1, buff, cnt);
	}
	close(fd);
 
	return 0;
}
 
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
 
 
 
int main(int argc, char const *argv[])
{
 
    int fd = open("/usr/include/stdio.h", O_RDONLY);
    int fp = open("stdio.h", O_WRONLY | O_CREAT | O_TRUNC, 0664);
    if (-1 == fd || -1 == fp)
    {
        perror("open failed");
        return -1;
    }
 
  
    char buff[1024] = {0};
    ssize_t bytes_read = 0;
    ssize_t bytes_written = 0;
 
    while ((bytes_read = read(fd, buff, sizeof(buff))) > 0)
    {
        bytes_written = write(fp, buff, bytes_read); 
        if (bytes_written == -1 || bytes_written != bytes_read)
        {
            printf("write failed\n");
            close(fd);
            close(fp);
            return -1;
        }
    }
 
  
    if (bytes_read == -1)
    {
        printf("read failed\n");
        close(fd);
        close(fp);
        return -1;
    }
 
    close(fd);
    close(fp);
    return 0;
}

文件定位

lseek:

off_t lseek(int fd, off_t offset, int whence);
功能:文件读写位置定位
参数:
        fd:文件描述符
        offset:偏移量(字节)
        whence:要偏移的相对位置
            SEEK_SET:文件开头位置
            SEEK_CUR:文件当前读写位置
            SEEK_END:文件末尾
返回值:
       成功:返回当前读写位置到文件开头的偏移量
       失败:-1

求文件大小:
off_t len = lseek(fd, 0, SEEK_END);
lseek(fd, 0, SEEK_SET);  //文件读写位置复位
 

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
 
 
int main(int argc, const char *argv[])
{
	int fd = open("./1.txt", O_WRONLY | O_TRUNC | O_CREAT, 0664);
	if (fd < 0)
	{
		printf("open error\n");
		return -1;
	}
	
	off_t offset = lseek(fd, 10, SEEK_SET);
	printf("offset = %ld\n", offset);
	write(fd, "A", 1);
 
	offset = lseek(fd, 0, SEEK_CUR);
	printf("offset = %ld\n", offset);
	
	offset = lseek(fd, 0, SEEK_SET);
	printf("offset = %ld\n", offset);
	
	offset = lseek(fd, 0, SEEK_END);
	printf("offset = %ld\n", offset);
	lseek(fd, 0, SEEK_SET); //文件读写位置复位
 
 
	close(fd);
	return 0;
}

三、标准IO与文件IO的区别

标准IO:
1. 属于C库函数,移植性强
2. 标准IO是系统调用的一次封装,增加了缓冲区,目的是提高数据读写的效率
3. 标准IO主要用在对普通文件的操作
文件IO:
1. 属于系统调用,只能用于Linux操作系统,移植性弱
2. 文件IO无缓冲区
3. 文件IO主要应用在对硬件的操作的,也可以操作普通文件

底层原理

缓冲区:

1. 行缓冲  1k(1024字节)   -----》人机交互界面、终端
        缓冲区被刷新的方法:
       1. 程序结束,自动刷新缓冲区
       2. 遇到\n刷新
       3. fflush()强制刷新
       4. 缓冲区满刷新

2. 全缓冲  4k(4096字节)   -----》文件缓冲区
        缓冲区被刷新的方法:
       1.程序结束,自动刷新缓冲区
        2. fflush()强制刷新
        3. 文件关闭刷新
        4. 缓冲区满刷新

3. 无缓冲  0k   --------》出错信息对应的设备
       stderr---》无缓冲
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值