Linux程序设计之--第三章 文件操作

         本篇主要是针对Linux中的文件、目录以及相关操作。主要介绍系统调用和标准I/O库。linux中,一切都是以文件的形式来表示的,包括一些硬件设备。大多数情况下,只需要使用五个基本的函数--open close read write 和ioctl。目录也是文件,它用来保存其他文件的节点号(inode)和名字。正常情况下,所有用户都必须用上层opendir/readdir接口来读取目录。文件的一些属性信息都被保存在文件的inode数据结构中,它还包含文件的长度和文件在磁盘上的存放位置。下面主要介绍下inode节点的一些信息。

      linux文件系统(EXT2)通常将文件的属性、权限以及文件的数据内容存放在不同的块中,将文件的属性与权限存放在inode中,实际数据则放置在data block块中。还有一个超级块,会记录整个文件系统的整体信息,包括inode与block的总量、使用量、剩余量等。inode记录文件的属性,一个文件占用一个inode,同时记录此文件的数据所在的block号码,而且每个inode的大小均为固定的128bytes(鸟哥是这么说的,但是ubuntu系统中的Inode大小为256B)。这样就方便快速的查找出数据,我们现找到文件的inode然后知道了该文件数据所在的块,这样就能快速的读取数据

         linux中比较重要的设备文件有三个--/dev/console /dev/tty /dev/null  第一个是表示系统控制台,过去会有一个指定的终端或者显示器来接收控制台消息,现在通常是虚拟控制台,比如在X视窗系统中,它是屏幕上的一个特殊的控制台窗口,就是我们说的终端。/dev/tty。如果一个进程有控制终端的话,那么特殊文件/dev/tty就是这个控制终端(键盘或者显示屏,或者键盘和窗口)的别名(逻辑设备)。

注意:虽然/dev/console设备只有一个,但是通过/dev/tty却能够访问许多不同的物理设备。

/dev/null是空设备,所有写向这个设备的输出都将被丢失。

我们用很少量的函数就可以对文件和设备进行访问和控制,这些函数被称为系统调用。操作系统的核心,即内核,是一组设备驱动程序。为了向用户提供一个统一的接口,设备驱动程序封装了所有与硬件相关的特性。硬件的特有功能可通过ioctl调用来完成。用来访问设备驱动程序的底层函数(系统调用)包括:

open:打开文件或设备。

read:从打开的文件或设备里读取数据

write:向文件或设备写入数据

close:关闭文件或设备

ioctl:把控制信息传递给设备驱动程序

下面分别介绍以下这五个系统调用函数。

1.open系统调用。创建新的文件描述符需要使用系统调用open。

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

int open(const char *path, int oflags)
int open(const char *path, int oflags, mode_t mode)

这是要使用open系统调用需要用到的库,即头文件。以及函数原型,函数返回值为这个文件的文件描述符。准备打开的文件或设备的名字作为参数path传递给函数,oflags参数用来定义打开文件所采取的动作。oflags参数是通过主要文件访问模式与其他可选模式的结合来指定的。它必须指定以下所示的文件访问模式之一:O_RDONLY 以只读方式打开  O_WRONLY 以只写方式打开  O_RDWR 以读写方式打开。它还可以通过按位或的方式仙则下面可选模式:O_APPEND :把写入的数据追加在文件的末尾。O_RTUNC:把文件长度设置为0,丢弃已有的内容。 O_CREAT:如果需要,就按参数mode中给出的访问模式创建文件。O_EXCL:与O_CREAT一起使用,确保调用者创建出文件。open调用在成功时返回一个信的文件描述符(它总是一个非负数),失败时返回-1,并设置局部变量errno以指明失败的原因。新文件描述符总是使用未使用的最小值。

2.read系统调用。从与文件描述符fildes相关联的文件里读入nbytes个字节的数据,并把他们放到数据区buf中。它返回实际读入的字节数。

#include <unistd.h>
size_t read(int fildes, void *buf, size_t nbytes)
3.write系统调用。把缓冲区buf的前nbytes个字节写入与文件描述符fildes关联的文件中。它返回实际写入的字节数。

#include<unistd.h>

size_t write(int fildes, const void *buf, size_t nbytes);
4.close系统调用。终止一个文件描述符fildes与其对应文件之间的关联。文件描述符被释放并能够重新使用。

#include <unistd.h>

int close(int fildes);
调用成功返回0 ,出错返回-1.

5.ioctl系统调用。它提供一个用于控制设备及其描述符行为和配置底层服务的接口。

#include <unistd.h>

int ioctl(int fildes, int cmd, ...);

ioctl对描述符fildes指定的对象执行cmd参数中给出的操作。


其他与文件管理有关的系统调用

1、lseek系统调用 对文件描述符fildes的读写指针进行设置,可以用它来设置文件的下一个读写位置。

#include<unistd.h>
#include <sys/types.h>

off_t lseek(int fildes, off_t offset, int whence);
offset参数用来指定位置,而whence参数定义该偏移值的用法。whence取如下值:SEEK_SET:offset是一个绝对位置。SEEK_CUR:offset是相对于当前位置的一个相对位置。 SEEK_END:offset是相对于文件尾的一个相对位置。lseek返回从文件头到文件指针被设置处的字节偏移值,失败是返回-1。

2、fstat 、stat和lstat系统调用

fstat返回与打开的文件描述符相关的文件的状态信息,该信息将会写到buf结构中,buf的地址以参数的形式传递给fstat

#include <unistd,h>
#include <sys/stat.h>
#include <sys/types.h>

int fstat(int fildes, struct stat *buf);
int stat(const char *path, struct stat *buf);
int lstat(const char *path, struct stat *buf);


下面来介绍下标准I/O库

标准I/O库及其头文件stdio.h已经是ANSI C的一部分,而上述的系统调用还不是。在标准I/O库中,与底层文件描述符对应的叫做流(stream),它被实现为指向结构FILE的指针。在启动程序时,有三个文件流是自动打开的,分别是stdin,stdout,stderr。下面将与系统调用相对应介绍fopen fclose fread fwrite

1.fopen


#include <stdio.h>

FILE *fopen(const char *filename, const char *mode);
它主要用于文件和终端的输入和输出。

2.fread

#include <stdio.h>

size_t fread(void *ptr, size_t size, size_t nitems, FILE*stream);
从文件流stream读到由ptr指定的数据缓冲区里,size参数指定每个数据记录的长度,计数器nitems给出要传输的记录个数。它的返回值是成功读到数据缓冲区里的记录个数。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值