c/c++文件操作学习

c/c++文件操作学习

open函数

函数

int open(const char * pathname, int flags);
int open(const char * pathname, int flags, mode_t mode);

pathname:指路径

flag 功能
O_RDONLY 以只读方式打开文件
O_WRONLY 以只写方式打开文件
O_RDWR 以可读写方式打开文件
上述三种旗标是互斥的, 也就是不可同时使用, 但可与下列的旗标利用OR运算符组合
O_CREAT 若欲打开的文件不存在则自动建立该文件
O_EXCL 如果O_CREAT 也被设置, 此指令会去检查文件是否存在. 文件若不存在则建立该文件, 否则将导致打开文件错误. 此外, 若O_CREAT 与O_EXCL 同时设置, 并且欲打开的文件为符号连接, 则会打开文件失败
O_NOCTTY 如果欲打开的文件为终端机设备时, 则不会将该终端机当成进程控制终端机
O_TRUNC 若文件存在并且以可写的方式打开时, 此旗标会令文件长度清为0, 而原来存于该文件的资料也会消失
O_APPEND 当读写文件时会从文件尾开始移动, 也就是所写入的数据会以附加的方式加入到文件后面
O_NONBLOCK 以不可阻断的方式打开文件, 也就是无论有无数据读取或等待, 都会立即返回进程之中
O_NDELAY 同O_NONBLOCK
O_SYNC 以同步的方式打开文件
O_NOFOLLOW 如果参数pathname
O_DIRECTORY 如果参数pathname 所指的文件并非为一目录, 则会令打开文件失败

参数mode 则有下列数种组合, 只有在建立新文件时才会生效, 此外真正建文件时的权限会受到umask 值所影响, 因此该文件权限应该为 (mode-umaks)

mode 权限
S_IRWXU00700 代表该文件所有者具有可读、可写及可执行的权限
S_IRUSR 或S_IREAD, 00400 代表该文件所有者具有可读取的权限
S_IWUSR 或S_IWRITE, 00200 代表该文件所有者具有可写入的权限
S_IXUSR 或S_IEXEC, 00100 代表该文件所有者具有可执行的权限
S_IRWXG 00070 代表该文件用户组具有可读、可写及可执行的权限
S_IRGRP 00040 代表该文件用户组具有可读的权限
S_IWGRP 00020 代表该文件用户组具有可写入的权限
S_IXGRP 00010 代表该文件用户组具有可执行的权限
S_IRWXO 00007 代表其他用户具有可读、可写及可执行的权限
S_IROTH 00004 代表其他用户具有可读的权限
S_IWOTH 00002 代表其他用户具有可写入的权限
S_IXOTH 00001 代表其他用户具有可执行的权限

错误代码

参数 功能
EEXIST 参数pathname 所指的文件已存在, 却使用了O_CREAT 和O_EXCL 旗标
EACCESS 参数pathname 所指的文件不符合所要求测试的权限
EROFS 欲测试写入权限的文件存在于只读文件系统内
EFAULT 参数pathname 指针超出可存取内存空间
EINVAL 参数mode 不正确
ENAMETOOLONG 参数 pathname 太长
ENOTDIR 参数pathname 不是目录
ENOMEM 核心内存不足
ELOOP 参数pathname 有过多符号连接问题
EIO I/O 存取错误

mmap函数

头文件

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

函数

void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offsize);
//mmap()用来将某个文件内容映射到内存中,对该内存区域的存取即是直接对该文件内容的读写。

参数说明

参数 说明
start 指向欲对应的内存起始地址,通常设为NULL,代表让系统自动选定地址,对应成功后该地址会返回
length 代表将文件中多大的部分对应到内存
prot 代表映射区域的保护方式,有下列组合 PROT_EXEC:映射区域可被执行 PROT_READ :映射区域可被读取PROT_WRITE:映射区域可被写入PROT_NONE:映射区域不能存取
flags 会影响映射区域的各种特性:**MAP_FIXED **: 如果参数 start 所指的地址无法成功建立映射时,则放弃映射,不对地址做修正。通常不鼓励用此旗标。**MAP_SHARED **: 对应射区域的写入数据会复制回文件内,而且允许其他映射该文件的进程共享。MAP_PRIVATE: 对应射区域的写入操作会产生一个映射文件的复制,即私人的"写入时复制" (copy on write)对此区域作的任何修改都不会写回原来的文件内容。MAP_ANONYMOUS : 建立匿名映射,此时会忽略参数fd,不涉及文件,而且映射区域无法和其他进程共享。**MAP_DENYWRITE ** :只允许对应射区域的写入操作,其他对文件直接写入的操作将会被绝。MAP_LOCKED: 将映射区域锁定住,这表示该区域不会被置换(swap)。在调用mmap()时必须要指定MAP_SHARED 或MAP_PRIVATE。
fd open()返回的文件描述词,代表欲映射到内存的文件
offset 文件映射的偏移量,通常设置为0,代表从文件最前方开始对应,offset必须是分页大小的整数倍

返回值

若映射成功则返回映射区的内存起始地址,否则返回MAP_FAILED(-1),错误原因存于errno 中。返回值:若映射成功则返回映射区的内存起始地址,否则返回MAP_FAILED(-1),错误原因存于errno 中。
错误代码:

代码 功能
EBADF 参数fd 不是有效的文件描述词
EACCES 存取权限有误。如果是MAP_PRIVATE 情况下文件必须可读,使用MAP_SHARED 则要有PROT_WRITE 以及该文件要能写入
EINVAL 参数start、length 或offset 有一个不合法
EAGAIN 文件被锁住,或是有太多内存被锁住
ENOMEM 内存不足

使用中的问题

include <sys/types.h>                                                                         #include <sys/stat.h>                                                                          #include <fcntl.h>                                                                             #include <unistd.h>                                                                            #include <sys/mman.h>                                                                          #include <iostream>                                                                            using namespace std;                                                                           int main()
{                                                                           
	int fd;
	fd = open("Wandering.txt", O_RDWR | O_CREAT, 00777); 
	char* Out = (char*) mmap(NULL, 1024, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 
	close(fd);                                                   
	string He = "Hello World!";                                      
	char* str = (char*)&He;
	cout << &He << endl;                                          
	Out[1] = '1';                                              
	while(*str != '\0')                                                
	{                                                              
		cout << *str++ << endl;                                             
	}                                                       
	munmap(Out, 100); /* 解除映射 */                                                           }                                                                                                                                                                                       

当向mmap地址中写入数据总是出现Bus error的提示
发生错误的原因是因为mmap不能去扩展一个内容为空的新文件,因为大小为0,所有本没有与之对应的合法的物理页,不能扩展。所以只需要在新创建的空文件中先写入一些数据即可。

lseek()函数

所有打开的文件都有一个当前文件偏移量(current file offset),以下简称为 cfo。cfo 通常是一个非负整数,用于表明文件开始处到文件当前位置的字节数。读写操作通常开始于 cfo,并且使 cfo 增大,增量为读写的字节数。文件被打开时,cfo 会被初始化为 0,除非使用了O_APPEND 。

函数调用

#include <unistd.h>
#include <sys/types.h>
off_t lseek(int filedes, off_t offset, int whence);

参数说明

返回值:

  • -1:失败
  • 数据 新的偏移量
whence 功能
SEEK_SET 文件偏移量将被设置为 offset
SEEK_CUR 文件偏移量将被设置为 cfo 加上 offset
SEEK_END 文件偏移量将被设置为文件长度加上 offset

SEEK_SET、SEEK_CUR 和 SEEK_END 是 System V 引入的,在这之前使用的是 0、1 和 2。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章