平台网站有哪些,公司网站管理图片,郑州住房和城乡建设厅网站,怎么建立企业网站Linux C高级编程文件操作之系统调用 宗旨#xff1a;技术的学习是有限的#xff0c;分享的精神是无限的#xff01; 库函数是一些完成特定功能的函数#xff0c;一般由某个标准组织制作发布#xff0c;并形成一定的标准。使用库函数编写的函数一般可以应用于不同的平台而…Linux C高级编程文件操作之系统调用 宗旨技术的学习是有限的分享的精神是无限的 库函数是一些完成特定功能的函数一般由某个标准组织制作发布并形成一定的标准。使用库函数编写的函数一般可以应用于不同的平台而不需要做任何修改具有很好的可移植性。 系统调用函数与操作系统直接相关不同的操作系统所使用的系统调用可能不太一样因此如果两个操作系统差异很大系统调用函数的可移植性就不高。例如windows采用的系统调用的应用程序不能直接在Linux下编译运行。 之所以使用系统调用是因为系统资源的有限性以及内核管理的方便系统调用将上层内的应用开发与底层的硬件实现分开上层应用不需要关注底层硬件的具体实现。Linux的系统调用使用软中断实现使用系统调用后该程序的状态将从用户态切换到内核态。库函数实现最终也要调用系统调用函数但它封装了系统调用操作从而增加了代码的可移植性。 1、open()函数
——用于打开或者创建一个文件
1函数原型 #includesys/types.h
#includesys/stat.h
#includefcntl.h
int open(constchar* pathname, int flags, ...) 2参数
pathname要创建或者打开的文件名
flags: 指定文件的打开模式、标志等信息
必须指定一个O_RDONLY ——只读 O_WRONLY——只写 O_RDWR——读写
可选标志按位或O_APPEND——追加
O_TRUNC——若文件存在读写方式打开或只写打开则文件长度为0
O_CREAT——若文件不存在则创建文件此时open需要第三个参数用于指定该 文件的访问权限umask可以看掩码
O_EXCL——若同时指定为O_CREAT标志而文件已经存在则会出错可用于文件 是否存在
O_NONBLOCK对于设备文件以O_NONBLOCK方式打开可以做非阻塞I/O
3返回值
整数类型——成功时返回文件描述符出错时返回-1
4文件描述符
文件描述符——已打开文件的索引——通过索引找到已打开文件
文件描述符是一个非负的整数
文件描述符0,1,2分别表示标准输入标准输出标准错误输出在进程创建时已经打开。open返回的文件描述符一定是该进程尚未使用的最小描述符
5出错处理
errno.h头文件中定义了errno当API调用出错时errno说明出错的具体原因
可简单的将errno理解成整型数据
出错信息转换成可读字符串
#includestring.h
char* strerror(int errno);
perror函数根据当前的errno输出一条出错信息void perror(constchar* msg) #includestdio.h
#includestdlib.h#includesys/types.h
#includesys/stat.h
#includefcntl.hint main(int argc, char *argv[])
{int fd;if(argc 2){puts(please input the open filepathname!\n);exit(1);}//如果flag参数里有O_CREAT表示,该文件如果不存在,系统则会创建该文件,该文 件的权限由第三个参数决定,此处为0755//如果flah参数里没有O_CREAT参数,则第三个参数不起作用.此时,如果要打开的 文件不存在,则会报错.//所以fdopen(argv[1],O_RDWR),仅仅只是打开指定文件if((fd open(argv[1], O_CREAT | O_RDWR, 0755)) 0){perror(open filefailure!\n);exit(1);}else{printf(open file %d success!\n, fd);}close(fd);return 0;
}span stylefont-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255); /span 2、 creat()函数
——用于创建一个新文件
1函数原型
int creat(const char *pathname,mode_t mode)
2参数
pathname:要创建的文件名包括路径信息
mode:同open的第二个参数讨论文件的访问权限位时分析
S_IRUSR——可读 S_IWUSR——可写 S_IXUSR——可执行 S_IRWXU——可读、写、执行
除了用上述宏之外还可以用数字来表示文件的权限
可读——4 可写——2 可执行——1 无任何权限——0
3返回值
成功返回只写打开的文件描述符出错返回-1
4creat函数缺点它以只写方式打开创建的文件。若要创建一个临时文件并先写该文件然后又读该文件则必须先调用creat,close,然后再open.简便方法
open(pathname,O_RDWR| O_CREAT | O_TRUNC,mode); #includestdio.h
#includestdlib.h#includesys/types.h
#includesys/stat.h
#includefcntl.hvoid create_file(char *filename)
{/*创建的文件具有什么样的属性*/if(creat(filename, 0755) 0){printf(create file %sfailure!\n, filename);exit(EXIT_FAILURE);}else{printf(create file %s success!\n, filename);}
}int main(int argc, char *argv[])
{int i;if(argc 2){perror(you havent input thefilename,please try again!\n);exit(EXIT_FAILURE);}for(i 1; i argc; i){create_file(argv[i]);}return 0;
} 3、lseek函数(和fseek类似)
——用于修改当前文件偏移量
当前文件偏移量的作用规定了从文件什么地方开始进行读、写操作
——通常读写操作结束时会使文件偏移量增加读写的字节数
——当打开一个文件时除非指定了O_APPEND标志否则偏移量被设置为0
(1) 函数原型 #includesys/types.h
#includeunistd.h
off_t lseek(int filedes, off_t offset, int whence) (2) 参数
第一个参数filedesopen/creat函数返回的文件描述符
第二个参数offset
相对偏移量需结合whence才能计算出真正的偏移量
类型off_t通常情况下是32为数据类型
第三个参数whence该参数取值是三个常量
SEEK_SET:当前文件偏移量为——距文件开始出的offset个字节
SEEK_CUR:当前文件偏移量 offset可正可负
SEEK_END:当前文件长度 offset(可正可负)
3返回值
成功返回新的文件偏移量失败返回-1
4获取当前的偏移量
Off_tcurrent_position;
Current_position lseek(fd,0,SEEK_CUR);
lseek操作并不引起任何I/O操作只是修改内核中的记录并不引起磁盘的访问 操作
5空洞文件
——使用lseek修改文件偏移量后当前文件偏移量有可能大于文件的长度
——在这种情况下对该文件的下一次写操作将加长该文件
——这样文件中形成了一个空洞。对空洞区域进行读均返回0 4、read函数
——用于从文件中读出数据
1函数原型 #includeunistd.h
ssize_t read(int fd, void *buff, size_t nbytes) 2参数
第一个参数fd文件描述符
第二个参数buff指向缓冲区用于存放从文件读出的数据
第三个参数nbytes:unsigned int;需要从文件中读出的字节数
——缓冲区的大小 nbytes
3返回值
返回值类型ssize_t即int
出错返回-1成功返回从文件中实际读到的字节数当文件读到结尾时则返回0
4很多情况下read实际读出的字节数都小于要求读出的字节数
——读普通文件在读到要求的字节数之前就到达了文件尾端
——当从终端设备读时通常一次最多读一行
——当从网络读时网络中的缓冲机构可能造成read函数返回值小于所要求读出 的字节数
——某些面向记录的设备如磁盘一次最多返回一个记录 #includesys/types.h
#includesys/stat.h
#includefcntl.h
#includestdio.h#define LENGTH 100int main(void)
{int fd, len;char str[LENGTH];/* 创建并打开文件 */fd open(hello.txt, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);if(fd) {/* 写入 Hello, software weekly字符串 */write(fd, Hello,Software Weekly, strlen(Hello, software weekly));close(fd);}fd open(hello.txt, O_RDWR);len read(fd, str, LENGTH);/* 读取文件内容 */str[len] \0;printf(%s\n, str);close(fd);return 0;
}span stylefont-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255); /span 5、write函数
——用于向文件里面写入数据
(1) 函数原型
#includeunistd.h
ssize_t writeint fd,const void*buff,size_t nbytes
(2) 参数
第一个参数fd:文件描述符
第二个参数buff指向缓冲区存放了需要写入文件的数据
第三个参数nbytes需要写入文件的字节数
(3) 返回值
返回值类型ssize_t,即int
出错返回-1成功返回实际写入文件的字节数
(4) write出错的原因
——磁盘满
——没有访问权限
——超过了给定进程的文件长度限制 6、close函数
——用于关闭一个已打开的文件
1函数原型
int close(int filedes)
2 返回值
成功返回0出错返回-1
3参数
filedes文件描述符
4当close函数关闭文件时会释放进程加在该文件上的所有记录锁
内核会对进程打开文件表文件对象索引节点表项等结构进行修改释放相关的 资源
当进程退出时会关闭当前所有已打开的文件描述符 7、ioctl函数
——用于向设备发控制和配置命令这些数据不能用read/write读写
1 函数原型 #include sys/ioctl.h
int ioctl(int d, int request, ...) 2 参数
第一个参数d某个设备的文件描述符
第二个参数request是ioctl的命令可变参数取决于request通常是是一个指向 变量或者结构体的指针
3返回值
若出错返回-1成功返回其他值取决于request
ioctl(STDOUT_FILENO,TIOCGWINSZ,size)——获得终端设备的窗口大小
manioctl_list——可以看require的各种参数 8、mmap函数
——可以把磁盘文件的一部分直接映射到内存这样文件中的位置直接就有对应的内存地址对文件的读写可以直接用指针来做而不需要read/write函数
(1) 函数原型
#includesys/mman.h
void* mmap(void *addr,size_t len,int prot,int flag,int filedes,off_t off)
(2) 参数
addrNULL——内核会自己在进程地址空间中选择合适的地址建立映射
len需要映射的那部分文件的长度
off从文件的什么位置开始映射必须是页大小的整数倍32位——4K
filedes该文件的文件描述符
prot
PROT_EXEC——映射的这一段可执行例如映射的共享库
PROT_READ——映射的这一段可读
PROT_WRITE——映射的这一段可写
PROT_NONE——映射的这一段不可访问
flag
MAP_SHARED——多个进程对同一文件的映射是共享的一个进程对映射的内存做了修改另一个进程也会看到这种变化。
MAP_PRIVATE——多个进程对同一文件的映射不是共享的一个进程对映射的内存做了修改另一个进程不会看到这种变化也不会真的写到文件中去。
3返回值
成功则返回映射的首地址出错返回常数MAP_FAILED。 9、access函数
——判断文件是否可以进行某种操作
1函数原型
int access(const char *pathname,int mode)
2参数
pathname:文件名
mode判断的访问权限R_OK:文件可读 W_OK文件可写 X_OK:文件可执行 F_OK文件存在
3返回值
成功时返回0如果一个条件不符合时返回-1 10 dup函数
——复制文件描述符
1 函数原型 #include unistd.h
int dup(int oldfd); 2 参数
oldfd:待复制的文件描述符
3返回值
成功返回新的文件描述符;失败返回-1 11 dup2函数
——复制文件描述符
1 函数原型 #include unistd.h
int dup2(int oldfd, int newfd); 2 参数
oldfd:待复制的文件描述符
newfd:新的文件描述符
3 返回值
成功返回新的文件描述符;失败返回-1 //小项目用系统调用函数实现文件拷贝的功能
/************************************************************************* File Name: copy.c Author: libang Mail: 18211438613163.com Created Time: 2014年07月16日 星期三 00时15分12秒************************************************************************/#includestdio.h
#includestring.h
#includeunistd.h
#includesys/stat.h
#includesys/types.h
#includefcntl.h
#includestdlib.hint copy_file(intsrc_fd, int dest_fd);int main(intargc, char *argv[]) //注意先搭建主框架
{if(argc 3){printf(inputerror!\n);exit(1);}int src_fd, dest_fd;src_fd open(argv[1], O_RDONLY);dest_fd open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0666);if(src_fd 0 | dest_fd 0){printf(file openfail!\n);exit(0);}copy_file(src_fd, dest_fd);printf(success!\n);close(src_fd);close(dest_fd);return 0;
}int copy_file(intsrc, int dest)
{char buf[128];int r_ret, w_ret;char *tmp;//memset(buf,0,128);printf(success!\n);while((r_ret read(src, buf, 128)) 0) //经典的拷贝算法{tmp buf;while(r_ret){w_ret write(dest, tmp, r_ret);r_ret r_ret - w_ret;printf(%d\n, r_ret);tmp w_ret;}//memset(buf,0,128);}printf(success!\n);return 0;
}