10.文件操作

CSAPP笔记

1.shell程序设计
2.内存管理
3.链接库
4.文件操作
5.多进程
6.多线程
7.网络编程
8.makefile
9.调试技巧与调试工具



前言

学习文件的创建、打开、读写、关闭操作。
学习目录的创建、扫面、删除操作。


一、基础知识

  1. 对文件和目录进行处理有两种方式:
    a. 系统调用(效率低、受硬件特点限制)
    b. 标准I/O库(对应头文件为stdio.h)
    推荐使用标准I/O库,降低系统调用的开销。
  2. Linux中文件为操作系统服务和设备提供了一个简单而一致的接口,普通文件、目录和设备都被视作文件。
  3. 根目录下的内容:
二级子目录存放的内容
/bin系统程序的二进制可执行文件
/etc系统配置文件
/lib系统函数库文件
/dev物理设备接口文件
/home直接使用cd命令进入自己的家目录
/proc硬件状态信息文件
  1. Linux中比较重要的设备文件:/dev/console/dev/tty/dev/null
  2. 因为设备也是一种文件,所以设备按是否需要一次读写一整块,可以被分为字符设备和块设备。一般情况下块设备是那些支持某些类型文件系统的设备,如硬盘。
  3. 用于对文件和设备进行访问和控制的函数称为系统调用,由Linux直接提供,它们也是通向操作系统本身的接口。
  4. 操作系统的核心部分——内核,是一组设备驱动程序。它们是一组对系统硬件进行控制的底层接口。
  5. 为了向用户提供一个统一的接口,设备驱动程序封装了所有与硬件相关的特性。硬件的特有功能通过ioctl(用于I/O控制)系统调用来提供,ioctl调用提供了一些与特定硬件设备有关的必要控制,用法因设备而异。
    用于访问设备驱动程序的系统调用:open、 read、 write、close、 ioctl
  6. 一个程序开始运行产生进程时,一般会有3个已经打开的文件描述符:0标准输入、1标准输出、2标准错误。
    10.常见的文件有关的系统调用见红书3.4底层文件访问。
    常见的标准I/O库见红书3.5标准I/O库。

1.文件复制

采用系统调用,编写一个底层程序copy_system.c,用来逐个字符地将一个文件复制到另一个文件。假设输入文件已经存在,输出文件不存在。

#include <unistd.h>//首先包含
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>

int main(){
    char c;//定义1字符的缓冲区
    int in, out;//定义两个文件的描述符

    in = open("file.in", O_RDONLY);
    out = open("file.out", O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR );
    
    while(read(in, &c, 1) == 1){
        write(out, &c, 1);
    }
    
    exit(0);
}

该程序复制字符很多的文件时,进行大量的系统调用,速度非常慢。
对程序进行改进,每次复制大一些的数据块。

#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>

int main(){
    char block[1024];//定义1字符的缓冲区
    int in, out;//定义两个文件的描述符
    int nread;

    in = open("file.in", O_RDONLY);
    out = open("file.out", O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR );
    
    while((nread = read(in, block, sizeof(block))) > 0){
        write(out, block, nread);
    }
    
    exit(0);
}

采用标准I/O函数实现文件复制。
从键盘输入被复制文件的名字

#include <stdio.h>
#include <stdlib.h>

int main(){
	char filename[10];
	int c;
	FILE *in, *out;
	
	printf("please enter the file name");
	scanf("%s", filename);
	
	in = fopen(filename, "r");
	if((out = fopen("file.out", "w")) == NULL){
		printf("unable to open the file");
		exit(0);//终止程序
	}
	//out = fopen("file.out", "w");

	while((c = fgetc(in)) != EOF){//c = EOF时表示文件流到达文件尾
		fputc(c, out);//把字符c写到一个输出文件流中
	}

	fclose(in);
	fclose(out);
	
	exit(0);
}

顺序读写数据文件基本框架:

  1. 先用fopen打开文件,并与定义好的文件流建立关联。
  2. 再用fgetc和fputc操作文件流,一般会使用一个中间变量临时存放读出的字符。使用whlie循环遍历整个文件。
  3. 关闭刚才打开的文件。

顺序读写读取了太多不需要的信息,如果想要读取指定的数据,就需要用到随机读写。
实现随机读写的关键是要按要求移动位置指针,也就是文件的定位。
移动文件内部的位置指针的函数主要有两个,即 rewind() 和 fseek()。
要说明的是 fseek 函数一般用于二进制文件。在文本文件中由于要进行转换,故往往计算的位置会出现错误。

2.扫描目录

  1. Linux扫描目录有两种方式做到:
    a. shell程序设计,用表达式的通配符扩展。
    b. 使用dirent.h头文件中定义的一套目录操作库函数。

3.使用mmap函数进行文件处理


总结

问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值