Linux 文件系统编程之系统调用和标准I/O库

系统调用

访问设备驱动程序的底层函数主要有:
open:打开文件或者设备。
read:从打开的文件或者设备里面读取数据。
write:向文件或者设备写数据。
close:关闭文件或者设备。
open系统调用:
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
int open (const char *path, int flags);
int open (const char *path, int flags, mode_t mode);
path表示文件名,flags用来定义准备对打开的文件进行操作的动作。
如果open调用成功,则返回一个新的文件描述符(非负整型);如果失败,就返回-1close系统调用:
#include <unistd.h>
int close(int filedes);
成功返回0;出错返回-1read系统调用:
#include <unistd.h>
ssize_t read(int filedes, const void *buf, size_t nbytes);< publishblog.blogchina.com http:>
将n个字节从文件描述符对应的文件读出放入到buf中。成功则返回实际的读取字节数。write系统调用:
#include <unistd.h>
ssize_t write(int filedes, const void *buf, size_t nbytes);
返回值是实际写入的字节数(可能会小于nbytes);如果返回值是0,表示没有写入任何数据;如果返回值是-1,表示在write调用中出错了。
将n个字节从buf中写入到文件描述符对应的文件中。

常用标准I/O库文件函数:fopen,fwrite,fread,fclose,fflush,fseek,fgets,getchar,fputs等系列的函数
他们与系统调用的一个主要的区别在于,这是带缓冲的函数,操作的对象不是int型的文件描述符,而是fopen返回的FILE型的文件指针(*fp).对应的标准输入,输出,出错为stdin,stdout,stderr文件指针。
我把这些函数的用法全都写在这里:

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <time.h>#define SIZE  1024// fopen
int main0()
{FILE* fp = fopen ("abc", "ab+");if (NULL == fp){perror ("fopen");return -1;}printf ("打开文件成功\n");return 0;
}// fread
int main1()
{FILE* fp = fopen ("BTree.c", "ab+");if (NULL == fp){perror ("fopen");return -1;}char buf[SIZE] = {0};// feof 判断是否读到文件结尾,如果读到文件结尾,它返回一个非0 的值int ret;while (ret = fread (buf, sizeof(char), SIZE-1, fp)){buf[ret*sizeof(char)] = '\0';printf ("%s\n", buf);}if (0 == ret && !feof(fp)){perror ("fread");return -1;}printf ("文件读取结束\n");return 0;
}// fwrite
int main2()
{FILE* fp = fopen ("1.ppt", "ab+");if (NULL == fp){perror ("fopen");return -1;}FILE* fp1 = fopen ("2.ppt", "ab+");if (NULL == fp1){perror ("fopen");return -1;}char buf[SIZE] = {0};// feof判断是否读到文件结尾,如果读到文件结尾,它返回一个非0 的值int ret;while (ret = fread (buf, sizeof(char), SIZE, fp)){fwrite (buf, sizeof(char), ret, fp1);}if (0 == ret && !feof(fp)){perror ("fread");return -1;}printf ("文件读取结束\n");fclose (fp);fclose (fp1);return 0;
}// fgetc
int main3()
{FILE* fp = fopen ("1.ppt", "ab+");if (NULL == fp){perror ("fopen");return -1;}FILE* fp1 = fopen ("2.ppt", "ab+");if (NULL == fp1){perror ("fopen");return -1;}char buf[SIZE] = {0};// feof 判断是否读到文件结尾,如果读到文件结尾,它返回一个非0 的值int ret;while(1){int  c = fgetc (fp);if (EOF == c){break;}fputc (c, fp1);}fclose (fp);fclose (fp1);return 0;
}// 数据获取
/***************************************************************/
typedef struct student
{int id;char name[20];
}STU;void write_data(STU* a, int len)
{FILE* fp = fopen ("student", "ab+");if (NULL == fp){perror ("fopen");return;}   // 要写入个数fwrite (&len, sizeof(int), 1, fp);int i;for (i = 0; i < len; i++){// 写入数据长度len = sizeof(a[i]);     fwrite (&len, sizeof(int), 1, fp);// 写入数据fwrite (&a[i], sizeof(STU), 1, fp);}fclose (fp);
}// 读取数据
void read_data()
{FILE* fp = fopen ("student", "ab+");if (NULL == fp){perror ("fopen");return;}// 读记录的个数int count;fread (&count, sizeof(int), 1, fp);printf ("记录个数是:%d\n", count);int i;STU tmp;for (i = 0; i < count; i++){int len;fread (&len, sizeof(int), 1, fp);// 读取数据fread (&tmp, len, 1, fp);printf ("id = %d, name = %s\n", tmp.id, tmp.name);}fclose (fp);
}int main4()
{int i;STU a[20];for (i = 0; i < 20; i++){a[i].id = i;                sprintf (a[i].name, "zhang%d", i);}int len = sizeof(a)/sizeof(a[0]);   // 写数据write_data(a, len);// 读数据read_data();return 0;
}
/***************************************************************/// open
int main5()
{close(1);// 打开一个文件int fd = open ("test.txt", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR |   S_IXUSR);// int fd = open("test.txt", O_RDONLY);if (-1 == fd){printf ("打开文件失败\n");perror ("open");printf ("%s\n", strerror(errno));          }printf ("fd = %d\n", fd);printf ("asdadsafsfkj\n", fd);printf ("asdadsafsfkj\n", fd);printf ("asdadsafsfkj\n", fd);printf ("asdadsafsfkj\n", fd);printf ("asdadsafsfkj\n", fd);printf ("asdadsafsfkj\n", fd);printf ("asdadsafsfkj\n", fd);// fflush(stdout);close(fd);return 0;}// read
/***************************************************************/
int main6()
{int fd = open ("BTree.c", O_RDONLY, 0777);if (-1 == fd){perror ("open");return -1;}// 缓冲区  char buf[SIZE] = {0};ssize_t ret = read (fd, buf, SIZE-1);if (-1 == ret){perror ("read");}// 返回值为0 代表读到文件结尾if (0 == ret){printf ("文件读取结束\n");}printf ("len = %d\n", strlen(buf));printf ("读到%d字节:%s\n", ret, buf);return 0;
}// 缓冲区覆盖问题
int main7()
{int fd = open ("BTree.c", O_RDONLY, 0777);if (-1 == fd){perror ("open");return -1;}char buf[SIZE] = {0};while(1){ssize_t ret = read (fd, buf, SIZE-1);if (-1 == ret){perror ("read");}// 返回值为0 代表读到文件结尾if (0 == ret){printf ("文件读取结束\n");break;}// printf ("len = %d\n", strlen(buf));// printf ("读到%d 字节: %s\n", ret, buf);printf ("%s", buf);}return 0;
}// 读取数据之前清空缓冲区
int main8()
{int fd = open ("BTree.c", O_RDONLY, 0777);if (-1 == fd){perror ("open");return -1;}char buf[SIZE] = {0};while(1){memset (buf, 0, SIZE);          // 清空缓冲区ssize_t ret = read (fd, buf, SIZE-1);if (-1 == ret){perror ("read");}if (0 == ret){printf ("文件读取结束\n");break;}printf ("%s", buf); }return 0;
}// 每次读完数据之后讲下一个字节置为'\0';
int main9()
{int fd = open ("BTree.c", O_RDONLY, 0777);if (-1 == fd){perror ("open");return -1;}char buf[SIZE] = {0};while(1){ssize_t ret = read (fd, buf, SIZE-1);if (-1 == ret){perror ("read");}if (0 == ret){printf ("文件读取结束\n");break;}buf[ret] = '\0';printf ("%s", buf);}return 0;
}// 读一个完整的大数据
int main10()
{int fd = open ("BTree.c", O_RDONLY, 0777);if (-1 == fd){perror ("open");return -1;}char buf[SIZE] = {0};char* p = buf;int count = SIZE - 1;               // 每次要读的数据个数ssize_t ret =0;while (ret = read (fd, p, count)){// 出错if (-1 == ret){if (errno == EAGAIN || errno == EINTR){continue;}break;}printf ("sfjsfsjfs\n");// 读完if (ret == count){break;}count -= ret;                   // 下一次要读的数据p += ret;}printf ("len = %d\n", strlen(buf));// printf ("%s\n", buf);return 0;
}
/***************************************************************/// write
int main11()
{int fd = open ("abc", O_WRONLY|O_CREAT, 0777);if (-1 == fd){perror ("open");return -1;}char buf[SIZE] = {0};while(1){fgets (buf, SIZE, stdin);if (0 == strncmp ("end", buf, 3)){break;}ssize_t ret = write (fd, buf, strlen(buf));if (-1 == ret){perror ("write");}printf ("要写的字节数:%d,实际写的字节数:%d\n", SIZE, ret);}close(fd);return 0;
}// 文件复制
int main12()
{// 打开要读的文件int fd1 = open ("1.ppt", O_RDONLY);if (-1 == fd1){perror ("open fd1");return -1;}int fd2 = open ("2.ppt", O_WRONLY|O_CREAT, 0777);if (-1 == fd2){perror ("open fd2");return -1;}int ret = 0;char buf[SIZE] = {0};while (ret = read (fd1, buf, SIZE)){if (-1 == ret){perror("read");break;}write (fd2, buf, ret);}printf ("文件复制完成\n");close (fd1);close (fd2);return 0;
}// lseek
int main13()
{// 打开要读的文件int fd = open ("abc2", O_RDWR|O_CREAT, 0777);if (-1 == fd){perror ("open fd1");return -1;}// 设置这个文件的偏移指针lseek (fd, 20, SEEK_SET);char* buf = "hello";write (fd, buf, strlen(buf));close (fd);return 0;
}// 创建一个大文件
int main14()
{// 打开要读的文件int fd = open ("big", O_RDWR|O_CREAT, 0777);if (-1 == fd){perror ("open fd1");return -1;}// 设置这个文件的偏移指针到1G处lseek (fd, 1024*1024*1024, SEEK_SET);char* buf = "hello";    write (fd, "a", 1);close (fd);return 0;
}// printf缓冲
int main15()
{while(1){printf ("a");usleep (2000);}return 0;
}// 文件偏移指针测试1
int main16()
{// 打开要读的文件int fd = open ("big", O_RDWR|O_CREAT, 0777);if (-1 == fd){perror("open fd1");return -1;}printf ("%d\n", fd);// 设置这个文件的偏移指针到1G处lseek (fd, 20, SEEK_SET);printf ("等待2些数据\n");getchar();char* buf = "hello";write (fd, "a", 1);getchar();close (fd);return 0;
}// 文件偏移指针测试2
int main17()
{// 打开要读的文件int fd1 = open ("abc", O_RDWR|O_CREAT, 0777);if (-1 == fd1){perror ("open fd1");return -1;}printf ("abc fd = %d\n", fd1);int fd = open ("big", O_RDWR|O_CREAT, 0777);if (-1 == fd){perror ("open fd");return -1;}printf ("bif fd = %d\n", fd);// 设置这个文件的偏移指针到 1G处lseek (fd, 10, SEEK_SET);char *buf = "12345";write (fd, buf, strlen(buf));getchar();close (fd);return 0;
}/***************************************************************/
// 随机分组
// 函数功能:互换
void swap (int* a, int i, int j)
{int tmp = a[i];a[i]    = a[j];a[j]    = tmp;
}
// 函数功能:打印
void printA (int* a, int len)
{int i;for (i = 0; i < len; i++){if (0 == i % 4){printf ("\n");}printf ("%4d", a[len-i-1]);}putchar ('\n');
}int main18()
{srand ((unsigned int)time(NULL));int a[40];int i;int len = 40;for (i = 0; i < 40; i++){a[i] = i;}for (i = len-1; i > 0; i--){int index = rand() % (i+1);    // 获取随机数swap (a, index, i);            // 将获得的数和最后一个互换}printA (a, len);return 0;
}
/***************************************************************/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/448486.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql 索引:类型 、创建

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 一个简单的对比测试 以我去年测试的数据作为一个简单示例&#xff0c;20多条数据源随机生成200万条数据&#xff0c;平均每条数据源都重…

水调歌头·中秋

转载于:https://www.cnblogs.com/divineka/archive/2004/09/04/39560.html

代码面试最常用的10大算法

摘要&#xff1a;面试也是一门学问&#xff0c;在面试之前做好充分的准备则是成功的必须条件&#xff0c;而程序员在代码面试时&#xff0c;常会遇到编写算法的相关问题&#xff0c;比如排序、二叉树遍历等等。 在程序员的职业生涯中&#xff0c;算法亦算是一门基础课程&#…

fork与vfork的区别

fork与vfork的区别 1.vfork保证子进程先运行&#xff0c;在它调用exec或exit之后父进程才可能被调度运行。如果在调用这两个函数之前子进程依赖于父进程的进一步动作&#xff0c;则会导致死锁。 2.fork要拷贝父进程的进程环境&#xff1b;而vfork则不需要完全拷贝父进程的进程…

IDEA 2018 集成 MyBatis Generator 插件 详解、代码生成

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1、修改maven的pom文件 只需要将如下依赖添加到pom.xml文件中即可。&#xff08;注意此处是以plugin的方式&#xff0c;放在<plugins…

MongoDB监控及报警

转载请注明出处&#xff1a;https://www.cnblogs.com/shining5/p/11142357.html MongoDB监控及报警 Prometheus是由SoundCloud开发的开源监控报警系统和时序列数据库&#xff0c;其使用go语言开发。基本原理是通过HTTP协议周期性抓取被监控组件的状态&#xff0c;任意组件只要提…

umask命令:设置文件的默认权限掩码

今天接触到了掩码&#xff0c;从博客上总结了一些关于掩码解释比较全面的分析&#xff0c;和大家分享下。 文件权限是linux系统中的一种安全机制&#xff0c;通过设置不同的权限&#xff0c;可以达到限制用户操作的目的&#xff0c;有效地保证了文件的完整性。 默认的情况下&…

如何学习开源项目及Ceph的浅析

摘要&#xff1a;开源技术的学习和采用确实存在着一定门槛&#xff0c;然而学习各种开源项目已经成为许多开发者不可回避的工作内容。那么&#xff0c;对于类似OpenStack的大型开源项目&#xff0c;开发者该如何着手&#xff0c;这里我们看章宇的分享。 【编者按】在 上一届O…

Mybatis 中更新方法: updateByPrimaryKeySelective() 和 updateByPrimaryKey() 的区别

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 int updateByPrimaryKeySelective(TbItem record); int updateByPrimaryKey(TbItem record); 上面的是逆转工程生成的Mapper接口 对应…

SHT知识库操作要点

1.保存文档库模板&#xff1a; 知识库---设置---文档库设置---权限管理---将文档另存为模板2.设置版本号&#xff1a;知识库---设置---文档库设置---常规设置---版本控制设置3.设置文档库权限&#xff1a;列表---设置---文档库设置---此文档库的权限&#xff08;用户组读取列表…

浅谈三种特殊进程:孤儿进程,僵尸进程和守护进程

昨天学了进程控制&#xff0c;就这三种特殊的进程研究了一下&#xff0c;其中也借鉴了一些前人总计的经验。 1、孤儿进程 如果父进程先退出,子进程还没退出那么子进程将被 托孤给init进程,这里子进程的父进程就是init进程(1号进程).其实还是很好理解的。 // 父进程先子进程退…

设计师为什么要学编程,开发者为什么要学设计?

摘要&#xff1a;设计师和开发者目前正处于互联网的两端&#xff0c;看着彼此做不同的工作。如果他们能互相学习对方的技术&#xff0c;那么会协作得更好。 很多开发者认为&#xff0c;设计师应该学会如何编写代码&#xff0c;这一点是真的&#xff1a;通过学习&#xff0c;设计…

git 查看远程仓库地址

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 就一个命令&#xff1a; git remote -v 如下&#xff1a;

tensorflow之tf.train.exponential_decay()指数衰减法

exponential_decay(learning_rate, global_steps, decay_steps, decay_rate, staircaseFalse, nameNone) 使用方式&#xff1a; tf.tf.train.exponential_decay() 例子&#xff1a; tf.train.exponential_decay(self.config.e_lr, self.e_global_steps&#xff0c;self.config…

wait( )和 waitpid( )

进程一旦调用了wait&#xff0c;就立即阻塞自己&#xff0c;由wait自动分析是否当前进程的某个子进程已经退出&#xff0c;如果让它找到了这样一个已经变成僵尸的子进程&#xff0c;wait就会收集这个子进程的信息&#xff0c;并把它彻底销毁后返回&#xff1b;如果没有找到这样…

享受阅读的十二个好习惯

严谨的国际阅读率比较研究显示&#xff0c;当下韩国国民人均阅读量约为每年11本&#xff0c;法国约为8.4本&#xff0c;日本在8.4—8.5本之间。全世界每年阅读书籍数量排名第一的是犹太人&#xff0c;平均每人一年读书64本。而中国13亿人口&#xff0c;扣除教科书&#xff0c;平…

在 vscode 中使用 Git :拉取、提交、克隆

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 PS&#xff1a;转载此文后&#xff0c;网友在评论中提到还有其它方法&#xff0c;不过目前个人尚在研究中&#xff0c;有兴趣的朋友们也可…

偶也要去上海Tech一把了

公司组织的&#xff0c;后天去&#xff0c;呵呵&#xff1a;&#xff09;希望能多认识一点博客园的兄弟姐妹转载于:https://www.cnblogs.com/martinxj/archive/2004/09/14/42930.html

进程控制常用的一些操作

1、获取进程的id int main0() {printf ("当前进程 ID %d\n", getpid());printf ("当前父进程&#xff1a;%d\n", getppid());printf ("当前用户&#xff1a; %d\n", getuid());while (1);return 0; }2、fork 和 vfork之前的博客里有&#xf…

vscode 配置 git (配置、暂存、推送、拉取、免密)

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 vscode 中对 git 进行了集成&#xff0c;很多操作只需点击就能操作&#xff0c;无需写一些 git 指令。 不过这就需要你对 vscode 进行配…