Linux下IO编程(一)
Linux下IO编程(一)
- Linux下IO编程
- 文件IO
- open函数——打开or创建一个文件
- write函数
- read函数
- lseek函数
Linux下IO编程
文件IO
open函数——打开or创建一个文件
#include <fcntl.h> //open函数在此头文件中声明
int open(const char *pathname, int flags, mode_t mode)
参数意义如下:
- pathname——文件路径
- flags ——打开文件的方式
- mode——创建文件的权限(可省略)
flags的内容如下:
flags | 功能 |
---|---|
O_RDONLY | 只读打开 |
O_WRONLY | 只写打开 |
O_RDWR | 读写打开 |
O_CREAT | 若路径中的文件不存在则自动建立该文件 |
O_APPEND | 读写文件从文件尾部开始移动,所写入 |
O_TRUNC | 打开文件,会把已经存在的内容删除 |
O_EXCL | O_CREAT |O_EXCL指令会去检查文件是否存在,文件若不存在则建立,否则返回-1 |
mode的表示方法1:
mode | 功能 |
---|---|
S_IRUSR | 所有者拥有读权限 |
S_IWUSR | 所有者拥有写权限 |
S_IXUSR | 所有者拥有执行权限 |
S_IRGRP | 群组拥有读权限 |
S_IWGRP | 群组拥有写权限 |
S_IXGRP | 群组拥有执行权限 |
S_IROTH | 其他用户拥有读权限 |
mode的表示方法2:——可以由3位数字组成(umask)
数值 | 第一位 | 第二位 | 第三位 |
---|---|---|---|
4(读) | 所有者 | 群组 | 其他用户 |
2(写) | |||
1(执行) |
函数返回值:
函数的返回值是文件描述符,如果打开文件成功返回一个正整数,否则返回-1。文件描述符,是一个非负的整数,相当于文件的ID号。
举例:通过open函数实现touch功能
#include <stdio.h> // 提供open()函数
#include <fcntl.h>
#include <unistd.h> // 提供close()函数
int main(int argc,char* argv[])
{int fd;fd =open(argv[1],O_CREAT | O_RDWR,0777);if(fd<0){printf("create file %s is failed\n",argv[1]);return -1;}else{printf("create file %s is sucess,fd is %d\n",argv[1],fd);}close(fd);return 0;
}
write函数
#include <unistd.h>
ssize_t write (int fd, const void * buf, size_t count);
参数:
- fd——文件描述符
- buf——写入内容
- cout——向文件中写多少(字节)
函数返回值:返回实际写入的字节数。
举例:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc,char* argv[])
{int fd;int wr_ret;char buf[]="hello linux";fd=open("./a.c",O_TRUNC |O_RDWR);if(fd<0){printf("open file is failed");return -1;}printf("open file is success ,fd is %d\n",fd);wr_ret=write(fd,buf,sizeof(buf));printf("the wr_ret is %d\n",wr_ret); //12个字节 加上“\0”close(fd);return 0;
}
read函数
#include <unistd.h>
ssize_t read(int fd, void * buf, size_t count);
函数说明:
read()会把参数fd所指的文件传送count 个字节到buf 指针所指的内存中。
返回值:返回值为实际读取到的字节数
注意:
- 先写再读会涉及一个指针读写位置指针,在写完的指针位置进行读会读不到内容,如下举例
- read时fd中的数据如果小于要读取的数据,就会引起阻塞,详见:https://blog.csdn.net/hhhlizhao/article/details/71552588
举例:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc,char* argv[])
{int fd;int wr_ret,rd_ret;char buf[]="hello linux";char rd_buf[]={0};fd=open("./a.c",O_TRUNC |O_RDWR);if(fd<0){printf("open file is failed");return -1;}printf("open file is success ,fd is %d\n",fd);wr_ret=write(fd,buf,sizeof(buf));printf("the wr_ret is %d\n",wr_ret);//readrd_ret=read(fd,rd_buf,128);printf("the rd_ret is %d,the rd_buf is %s\n",rd_ret,rd_buf);close(fd);return 0;
}
//以上输出为
open file is success ,fd is 3
the wr_ret is 12
the rd_ret is 0,the rd_buf is //发现读不到
lseek函数
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence)
函数作用:
用于移动文件读写指针,因此还有以下两种作用:
- 扩展文件;
- 获取文件大小;lseek(fd,0,SEEK_END)
参数:
- fd——文件描述符
- offset——相对基准的偏移量,字节为单位,为正则向文件末尾移动(向前移),为负数则向文件头部(向后移)
- whence——当前的基准
whence主要有3个标志:
whence | 说明 |
---|---|
SEEK_SET |
从文件头部开始偏移offset 个字节
|
SEEK_CUR |
从文件当前读写的指针位置开始,增加offset 个字节的偏移量
|
SEEK_END | 从文件结尾开始,文件偏移量设置为文件的大小加上偏移量字节 |
返回值:成功,返回从文件开头到当前结束位置的偏移量(1字节为单位);失败返回-1。
举例1:对上个例子应用lseek()将读写指针移到开头,来实现先写再读
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc,char* argv[])
{int fd;int wr_ret,rd_ret;char buf[]="hello linux";char rd_buf[]={0};fd=open("./a.c",O_TRUNC |O_RDWR);if(fd<0){printf("open file is failed");return -1;}printf("open file is success ,fd is %d\n",fd);wr_ret=write(fd,buf,sizeof(buf));printf("the wr_ret is %d\n",wr_ret);//start read lseek(fd,0,SEEK_SET); //<========================================rd_ret=read(fd,rd_buf,128);printf("the rd_ret is %d,the rd_buf is %s\n",rd_ret,rd_buf);close(fd);return 0;
}
//经过lseek()函数调整读写指针位置后
open file is success ,fd is 3
the wr_ret is 12
the rd_ret is 12,the rd_buf is hello linux
举例2:综合应用——使用以上所学完成类似cp操作
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main(int argc,char* argv[])
{int rd_fd,wr_fd;int rd_ret;int wr_ret;char read_buf[128]={0};if(argc<3){printf("are you kiding me? ");return -1;}rd_fd=open(argv[1],O_RDONLY);if(rd_fd<0){printf("open the src file:%s is failed\n",argv[1]);return -2;}printf("open the %s is sucessful\n",argv[1]);wr_fd=open(argv[2],O_WRONLY);if(wr_fd<0){printf("open the des file:%s is failed\n",argv[2]);return -3;}printf("open the %s is sucessful\n",argv[2]);while(1){rd_ret=read(rd_fd,read_buf,128); //read时有读写指针wr_ret=write(wr_fd,read_buf,rd_ret); //所以此处一次读不完但是也能连续if(rd_ret<128){break;}memset(read_buf,0,128);}close(wr_fd);close(rd_fd);return 0;}
注:
从文件向buf中read时,因为文件有读写指针,并且一次循环read完一个buf马上进行write,所以最终得到的内容是连续的。但是要注意write函数,write()函数从buf写数据到fd中时,若buf中数据无法一次性读完,那么第二次读buf中数据时,其读位置指针(也就是第二个参数buf)不会自动移动,需要程序员来控制,而不是简单的将buf首地址填入第二参数即可。
#include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <string.h> int main(int argc,char* argv[]) {int wr_fd;int wr_ret;char buf[]="hello linux";wr_fd=open(argv[1],O_CREAT |O_RDWR,0666);if(wr_fd<0){printf("open the file is failed");return -1;}wr_ret=write(wr_fd,buf,2); wr_ret=write(wr_fd,buf,2);//写两次结果可能为“hehe” or "hell"close(wr_fd);return 0; }
//编译后执行 ./test test.c 得到test.c文件中内容为“hehe”
可按如下格式实现buf读位置移动:write(fp, p1+len, (strlen(p1)-len))。 这样write第二次循环时便会从p1+len处写数据到fp, 之后的也一样。由此类推,直至(strlen(p1)-len)变为0。
int main() {char *p1 = "This is a c test code";volatile int len = 0;int fp = open("/home/test.txt", O_RDWR|O_CREAT);for(;;){int n;n=write(fp, p1+len, (strlen(p1)-len);if(n== 0) { printf("n = %d \n", n);break;}len+=n; }return 0;
以上例子还未用到lseek()函数,因为以上函数是直接cp复制一个编辑好的文件,而不是复制通过write函数写出的文件。
Linux下IO编程(一)相关推荐
- linux v4l2 反操作,Linux下V4L2编程小结--吴老师
作者:武汉华嵌-嵌入式培训中心 吴老师 Linux下V4L2编程小结 一.设置采集方式,格式 常用命令标志 打开视频设备后,可以设置该视频设备的属性,例如裁剪.缩放等.这一步是可选的.在Linux编 ...
- Linux下Socket编程
Linux下Socket编程 网络的Socket数据传输是一种特殊的I/O,Socket也是一种文件描述符.Socket也具有一个类似于打开文件的函数调用Socket(),该函数返回一个整型的S ...
- Linux下高性能网络编程中的几个TCP/IP选项
Linux下高性能网络编程中的几个TCP/IP选项 转自:http://blog.chinaunix.net/u/12592/showart.php?id=2064847 最近在新的平台上测试程序,以 ...
- linux下多进程编程简介
两年前的文章,拿过来充充门面. ------------------------ linux下多进程编程简介 ( 作者:mikespook | 发布日期:2002-12-8 | 浏览次数:272 ) ...
- [zz]Linux 下 socket 编程示例
本示例为 Client/Server 结构,通过代码演示 Client 如何建立连接,并向远程端发送数据:Server 端如何侦听系统连接请求,接收请求并建立连接,进而获取客户端发来的数据.代码虽短, ...
- Linux下网络编程
Linux下网络编程初步 Linux以其源代码公开闻名于世,并以其稳定性和可靠性雄霸操作系统领域,在网络应用技术方面使用得更加广泛.很久以来它就是Windows的重要对手之一.随着网络时代的来临,Li ...
- linux下 C编程改变输出字体颜色
linux下 C编程改变输出字体颜色 分类: Linux基础编程 Linux操作系统 2012-09-19 10:53 1409人阅读 评论(0) 收藏 举报 linux编程c 格式: echo &q ...
- linux实验串行端口程序设计,Linux下串口编程心得(转)
最近一段时间,需要完成项目中关于Linux下使用串口的一个部分,现在开帖记录过程点滴. 项目的要求是这样的,Qt应用程序主要完成数据采集和发送功能,一开始在google中海搜关键字"Qt串口 ...
- linux下Bash编程until语句及格式化硬盘分区等编写脚本(十)
linux下Bash编程until语句及格式化硬盘分区等编写脚本(十) 1.循环语句结构总结 1.1.while语句当条件满足时,进入循环语句 while 条件; do 语句 done 1.2.unt ...
最新文章
- git reset revert 回退回滚取消提交返回上一版本
- android listview 去掉水波纹效果_CocosCreator之分层管理的ListView
- Android学习——ListView的缓存机制
- [Swift]LeetCode46. 全排列 | Permutations
- DPM 2012 R2恢复Exchange 2013单用户邮箱
- cygwin下各盘挂载点
- java微信上传本地视频教程_java微信开发之上传下载多媒体文件,java上传下载_PHP教程...
- 【脚本开发】:性能测试-Java虚拟用户实现下载脚本
- bzoj 2795	[Poi2012]A Horrible Poem hash+线性筛
- 非关系型数据库和关系型数据库区别(转载)
- c++/cli 之数据库操作
- Typora下载安装详细步骤
- 信息安全工程师考试科目
- word文件做一半未响应_word编辑一半未响应怎么办
- VUE时间戳和时间相互转换,使用UI库为Ant Design of Vue
- tplink查看上网记录_Tplink路由器PPPOE拨号不能上网日志查看原因
- kali2.0 安装 网易云音乐(无法打开解决方法)和为知笔记
- 最成功的失败学——《创游记:游戏团队创业成长之路》
- Quorum NWR
- 安装pandas成功但import不成功的解决办法