一些 C C++ POSIX 的 IO 操作总结

  • 文件-内存之间
  • 内存-内存之间
  • POSIX 有无缓冲的 IO 操作

对文件的操作,读文件至内存,从内存写至文件

// 读文件至内存buf中
void Fread()
{
char buf[BUFSIZE];
size_t flen = 0;
FILE *fp = fopen("./foo", "r+"); flen = fread(buf, sizeof(char), BUFSIZE, fp); // fp -> buf
printf("read len: %lu\n", flen);
printf("Fread text:\n%s\n\n", buf);
fclose(fp);
} // 将内存 buf 中的内容写入打开的文件 fp 中
void Fwrite()
{
char buf[BUFSIZE] = BUFTEXT;
size_t flen = 0;
FILE *fp = fopen("./foo", "w+");
flen = fwrite(buf, sizeof(char), strlen(buf), fp); // buf -> fp
printf("Fwrite write len: %lu\n\n", flen);
fclose(fp);
} // 将fp 换为 stdin 输入至 buf 中
void Fscanf()
{
char buf[BUFSIZE];
size_t flen = 0;
FILE *fp = fopen("./foo", "r+");
while(fscanf(fp, "%s", buf) != EOF) // fp -> buf, terminated by blank char
printf("Fscanf text:\n%s\n", buf);
printf("\n");
fclose(fp);
} // C++ 文件流,输入至内存中,由于流遇到空格等空白符停止所以需循环将流中的内容全部输入至
// 内存(string)中,直至返回 EOF
void Ifstream()
{
ifstream ifs("./foo");
string buf;
while (ifs >> buf) // ifs -> buf
cout <<"Ifstream: " << buf << endl; // char *str = new char[100];
// ifs.read(str, 10);
// whlile (getline(ifs, buf))
// cout << "Ifstream: " << buf << endl;
ifs.close();
cout << endl;
} // fp 换为 stdout, buf 中的内容写入至 fp 中
void Fprintf()
{
char buf[BUFSIZE] = "ioi ioi";
int flen = 0;
FILE *fp = fopen("./foo", "w+");
flen = fprintf(fp, "%s", buf); // buf -> fp
printf("Fprintf len: %d\n", flen);
fclose(fp);
} void Ofstream()
{
ofstream ofs("./foo", ios::app | ios::out);
string buf = "quick,,time go on";
// ofs << buf;
ofs.write(buf.c_str(), buf.size());
ofs.close();
}

字符流的操作,内存至内存

// 文件流 stdio 换为 str, 格式化输入
void Sscanf()
{
char str[BUFSIZE] = BUFTEXT;
char buf[BUFSIZE];
sscanf(str, "%s", buf); // str -> buf
printf("Sscanf text:\n%s\n\n", buf);
} // istringstream 对象 iss 绑定 buf,作为输入流输入至 word(string)
void Istringstream()
{
string buf = "hello world";
string word; istringstream iss(buf); // buf -> iss
while (iss >> word) // iss -> word, repeatedly
cout << "Istringstream: " << word << endl;
} // 与 sscanf() 类似, 格式化输出
void Sprintf()
{
char str[BUFSIZE] = BUFTEXT;
char buf[BUFSIZE];
sprintf(buf, "%s", str); // str -> buf
printf("Sprintf text:\n%s\n\n", buf);
} // 与 istringstream 类似
void Ostringstream()
{
string buf = BUFTEXT;
string word; ostringstream oss;
oss << buf; // buf -> oss
word = oss.str(); // oss -> word
cout << "Ostringstream: " << word << endl;
}

Linux 有无缓冲的 IO操作 (参考 UNP)

// 无缓冲, 普通的 read() write() 并不难保证完成所需要传送的字符数
ssize_t rio_readn(int fd, void *usrbuf, size_t n)
{
size_t nleft = n;
ssize_t nread;
char *bufp = usrbuf; while (nleft > 0) {
if ((nread = read(fd, bufp, nleft)) < 0) {
if (errno == EINTR) // interrupted by sig handler return
nread = 0; // call read() again
else
return -1; // errno set by read()
} else if (nread == 0)
break; // EOF
nleft -= nread;
bufp += nread;
} return (n - nleft);
} // not buff read
ssize_t rio_writen(int fd, void *usrbuf, size_t n)
{
size_t nleft = n;
ssize_t nwritten;
char *bufp = usrbuf; while(nleft > 0) {
if ((nwritten = write(fd, bufp, nleft)) <= 0) {
if (errno == EINTR)
nwritten = n;
else
return -1;
}
nleft -= nwritten;
bufp += nwritten;
} return n;
} // IO 缓冲区结构体
typedef struct {
int rio_fd;
int rio_cnt;
char *rio_bufptr;
char rio_buf[RIO_BUFSIZE];
} rio_t;
// 与 read() 语义相同
// 如果缓冲区为空会通过调用 read() 填满它
static ssize_t rio_read(rio_t *rp, char *usrbuf, size_t n)
{
int cnt; while (rp->rio_cnt <= 0) { // refill if buf is empty
rp->rio_cnt = read(rp->rio_fd, rp->rio_buf, sizeof(rp->rio_buf));
if (rp->rio_cnt < 0) {
if (errno != EINTR)
return -1;
} else if (rp->rio_cnt == 0) { // EOF
return 0;
} else {
rp->rio_bufptr = rp->rio_buf; // reset buffer ptr
}
} // copy min(n, rp->cnt) bytes from internal buf to user buf
cnt = n;
if (rp->rio_cnt < n)
cnt = rp->rio_cnt;
memmove(usrbuf, rp->rio_bufptr, cnt);
rp->rio_bufptr += cnt;
rp->rio_cnt -= cnt; return cnt;
}

一点小结

  • 本质是操作对象的变化
// C
printf() -- stdout scanf() -- stdin
fprintf() -- FILE* fscanf() -- FILE*
sprintf() -- char* sscanf() -- str
// C++ 与上类似, 都具有缓冲区
ostream istream
ofstream ifstream
ostringstream istringstream
  • 带有缓冲区的 rio_read() 有时效率很高,因为不必一直在内核-用户态之间切换

C C++ POSIX 的一些 IO 操作的更多相关文章

  1. python之协程与IO操作

    协程 协程,又称微线程,纤程.英文名Coroutine. 协程的概念很早就提出来了,但直到最近几年才在某些语言(如Lua)中得到广泛应用. 子程序,或者称为函数,在所有语言中都是层级调用,比如A调用B ...

  2. Linux学习记录--文件IO操作相关系统编程

    文件IO操作相关系统编程 这里主要说两套IO操作接口,各自是: POSIX标准 read|write接口.函数定义在#include<unistd.h> ISO C标准 fread|fwr ...

  3. Linux文件IO操作

    来源:微信公众号「编程学习基地」 目录 文件操作 Linux文件类型 Linux文件权限 修改文件权限 Linux error 获取系统调用时的错误描述 打印错误信息 系统IO函数 open/clos ...

  4. [.NET] 利用 async & await 进行异步 IO 操作

    利用 async & await 进行异步 IO 操作 [博主]反骨仔 [出处]http://www.cnblogs.com/liqingwen/p/6082673.html  序 上次,博主 ...

  5. 文件IO操作..修改文件的只读属性

    文件的IO操作..很多同行的IO工具类都是直接写..但是如果文件有只读属性的话..则会写入失败..所以附加了一个只读的判断和修改.. 代码如下: /// <summary> /// 创建文 ...

  6. JAVASE02-Unit08: 文本数据IO操作 、 异常处理

    Unit08: 文本数据IO操作 . 异常处理 * java.io.ObjectOutputStream * 对象输出流,作用是进行对象序列化 package day08; import java.i ...

  7. JAVASE02-Unit07: 基本IO操作 、 文本数据IO操作

    基本IO操作 . 文本数据IO操作 java标准IO(input/output)操作 package day07; import java.io.FileOutputStream; import ja ...

  8. IO操作概念。同步、异步、阻塞、非阻塞

    “一个IO操作其实分成了两个步骤:发起IO请求和实际的IO操作. 同步IO和异步IO的区别就在于第二个步骤是否阻塞,如果实际的IO读写阻塞请求进程,那么就是同步IO. 阻塞IO和非阻塞IO的区别在于第 ...

  9. Java基础复习笔记系列 七 IO操作

    Java基础复习笔记系列之 IO操作 我们说的出入,都是站在程序的角度来说的.FileInputStream是读入数据.?????? 1.流是什么东西? 这章的理解的关键是:形象思维.一个管道插入了一 ...

随机推荐

  1. 20170623_oracle基础知识_常见问题

    1 如何配置网络服务?两种连接 Oracle 工具? 1) 打开Net Manager 2) 选择服务命名,点击“+ ”号 3 ) 网络服务名:  remote协议:tcp/ip 主机名:ip地址 端 ...

  2. 主表a主表b 从表c中有ab两个表中各一个字段a1,b1 从表d中有ab两个表中各一个字段a2,b2

    a1和a2在a表中具有唯一性 b1和b2在b表中具有唯一性 现在需要连接c表和d表 需要分两步来做 1.先让c表join表a和表b select c.*,a.a2,b.b2 from c inner ...

  3. HTML5浏览器嵌入窗口程序解决方案

    浏览器嵌入窗口程序一直以来就是WEB应用程序的首选方案,这种方案只需要实现一个主窗口,并提供一些接口供脚本调用,内部的界面和逻辑处理全部用html,css,javascript去实现.我最早看到的相关 ...

  4. 【POJ 3349】 Snowflake Snow Snowflakes

    [题目链接] http://poj.org/problem?id=3349 [算法] 哈希 若两片雪花相同,则它们六个角上的和一定相同,不妨令 H(A) = sigma(Ai) % P ,每次只要到哈 ...

  5. JavaGraphics类的绘图方法

    Graphics类提供基本绘图方法,Graphics类提供基本的几何图形绘制方法,主要有:画线段.画矩形.画圆.画带颜色的图形.画椭圆.画圆弧.画多边形.画字符串等. 1. 画线段:在窗口中画一条线段 ...

  6. poj1611 并查集 (路径压缩)

    http://poj.org/problem?id=1611 题目大意: 有一个学校,有N个学生,编号为0-N-1,现在0号学生感染了非典,凡是和0在一个社团的人就会感染,并且这些人如果还参加了别的社 ...

  7. Lambda表达式怎么写SQL中的in?

    ambda表达式查询没有IN这个方法,可以变通一下,in查询的数组是否包含在映射对象里面的集合里 直接贴代码吧,一看就懂了 class Program { static void Main(strin ...

  8. 题解报告:hdu 1232 畅通工程(并查集)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1232 Problem Description 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了 ...

  9. 手势识别官方教程(7)识别缩放手势用ScaleGestureDetector和SimpleOnScaleGestureListener

    1.Use Touch to Perform Scaling As discussed in Detecting Common Gestures, GestureDetector helps you ...

  10. [ POI 2017 ] Podzielno

    \(\\\) \(Description\) \(B\)进制数,每个数字\(i(i\in [0,B-1])\)有\(A_i\)个.用这些数字组成一个最大的\(B\)进制数\(X\)(不能有前导零,不需 ...