IO进程day02(文件IO)

2024-08-26 22:12
文章标签 进程 io day02

本文主要是介绍IO进程day02(文件IO),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

【1】什么是文件IO

1》概念

2》特点

3》操作

【2】函数接口

1》打开文件open()

思考:文件IO和标准IO的打开方式的对应关系

2》关闭文件 close()

 3》读写文件  read  write

1> 读文件 read()

2> 写文件 write() 

练习:文件IO实现cp功能。cp 源文件 新文件名

4》文件定位操作 lseek

练习:向文件中第 10 位置后面写一个字符,在文件此时的位置,往后移动20个位置处,写一行字符串hello进去,求此时文件的长度。

练习: 实现“head -n 文件名”命令的功能


【1】什么是文件IO

1》概念

又称系统IO,是系统调用,是操作系统提供的接口函数。

posix中定义的一组用于输入输出的函数。

POSIX接口 (英语:Portable Operating System Interface)可移植操作系统接口

2》特点

  1. 没有缓冲机制,每次都会引起系统调用。
  2. 围绕文件描述符进行操作,非负整数(>=0),依次分配。
  3. 文件IO默认打开三个文件描述符,分别是0(标准输入)、1(标准输出)和2(标准错误)。
  4. 操作除了目录d以外任意类型的文件b c - l s p
  5. 可移植性相对较差

3》操作

文件文件:open

关闭文件: close

读写操作: read和write

定位操作:lseek

【2】函数接口

1》打开文件open()

man 2 open

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

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

功能:打开文件

参数:pathname:文件路径名

flags:打开文件的方式

     O_RDONLY:只读

     O_WRONLY:只写

     O_RDWR:可读可写

     O_CREAT:不存在创建

     O_TRUNC:存在清空

     O_APPEND:追加

返回值:成功:文件描述符

失败:-1

当第二个参数中有O_CREAT选项时,需要给open函数传递第三个参数,指定创建文件的权限

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

最后权限 = mode &(~umask)

例如:指定权限为06668进制)

最终权限= 0666 & (~umask) = 0666 &(~0002) = 664

666 => 110 110 110

&775 111 111 101

664 110 110 100

 

思考:文件IO和标准IO的打开方式的对应关系

标准IO文件IO
r

O_RDONLY

只读

r+

O_RDWR

可读可写

w

O_WRONLY | O_CREAT | O_TRUNC, 0777

只写不存在创建存在清空

w+

O_RDWR | O_CREAT | O_TRUNC, 0777

可读可写不存在创建存在清空

a

O_WRONLY | O_CREAT | O_APPEND, 0777

只写存在创建存在追加

a+

O_RDWR | O_CREAT | O_APPEND, 0777

可读可写,存在创建存在追加

2》关闭文件 close()

#include <unistd.h>

int close(int fd);

功能:关闭文件

参数:fd:文件描述符

 3》读写文件  read  write

1> 读文件 read()

ssize_t read(int fd, void *buf, size_t count);

功能:从一个已打开的可读文件中读取数据

参数: fd 文件描述符

            buf 存放位置

            count 期望的个数

返回值:成功:实际读到的个数(小于期望值说明实际没这么多)

返回0:表示读到文件结尾

返回-1:表示出错,并设置errno号

fgetc -> EOF 末尾失败

fgets -> NULL 末尾失败

fread -> 0 末尾失败

read -> 0末尾 -1失败

2> 写文件 write() 

#include <unistd.h>

ssize_t write(int fd, const void *buf, size_t count);

功能:向指定文件描述符中,写入 count个字节的数据。

参数:fd 文件描述符

           buf 要写的内容

           count 期望写入字节数

返回值:成功:实际写入数据的个数

失败 : -1

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>int main(int argc, char const *argv[])
{int fd;char buf[32] = "";//1.打开文件fd = open("a.c", O_RDWR); //r+if (fd < 0){perror("open err ");return -1;}printf("fd: %d\n", fd);//2. 读写文件read(fd, buf, 10); //文件中内容为:helloprintf("%s\n", buf); //hellowrite(fd, "world", 5);//向文件中写 world//3.关闭文件close(fd);return 0;
}
练习:文件IO实现cp功能。cp 源文件 新文件名
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>int main(int argc, char const *argv[])
{int fd1, fd2;if (argc != 3){printf("err: %s <srcfile> <destfile>\n", argv[0]);return -1;}//1.打开两个文件fd1 = open(argv[1], O_RDONLY);if (fd1 < 0){perror("fd1 open err");return -1;}fd2 = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0777);if (fd2 < 0){perror("fd2 open err");return -1;}//2.循环读源文件,只要读到就写入目标char buf[32] = "";ssize_t n;while ((n = read(fd1, buf, 32)) > 0)write(fd2, buf, n);//while (read(fd1, buf, 1) > 0)  //或者//    write(fd2, buf, 1);//3. 关闭两个文件close(fd1);close(fd2);return 0;
}

4》文件定位操作 lseek

off_t lseek(int fd, off_t offset, int whence);

功能:设定文件的偏移位置

参数:fd:文件描述符

           offset: 偏移量

正数:向文件结尾位置移动

负数:向文件开始位置

            whence: 相对位置

                            SEEK_SET 开始位置

                            SEEK_CUR 当前位置

                            SEEK_END 结尾位置

补充:和fseek一样其中SEEK_SET,SEEK_CURSEEK_END和依次为012.

返回值:成功:文件的当前位置

失败:-1

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>int main(int argc, char const *argv[])
{int fd;fd = open("a.c", O_RDWR);if (fd < 0){perror("open err");return -1;}//离开头后10个lseek(fd, 10, SEEK_SET);write(fd, "k", 1);//在该位置写个 koff_t off = lseek(fd, 0, SEEK_END);//记录文件长度printf("%ld\n", off);return 0;
}
练习:向文件中第 10 位置后面写一个字符,在文件此时的位置,往后移动20个位置处,写一行字符串hello进去,求此时文件的长度。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>int main(int argc, char const *argv[])
{int fd;fd = open("a.c", O_RDWR);if (fd < 0){perror("open err");return -1;}lseek(fd, 10, SEEK_SET);//从头向后移动10个单位write(fd, "d", 1);lseek(fd, 20, SEEK_CUR);//从当前位置向后移动20各单位write(fd, "hello", 5);off_t off = lseek(fd, 0, SEEK_END);//计算从头到尾的长度printf("%ld\n", off);return 0;
}
练习: 实现“head -n 文件名”命令的功能
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main(int argc, char const *argv[])
{if (argc != 3){printf("err: %s -n <filename>\n", argv[0]); //./a.out -n <filename>return -1;}FILE *fp = fopen(argv[2], "r");if (fp == NULL){perror("fopen err");return -1;}//获取行数int num = atoi(argv[1] + 1); // +1是为了向后偏移一个地址单位把-去掉获取到要打印的行数char buf[32] = "";int len = 0;//循环读,然后数换行,打印到终端,如果是最后一行就退出while (fgets(buf, 32, fp) != NULL){if (buf[strlen(buf) - 1] == '\n')     //数换行len++;if (len > num)    //达到行数就退出break;fputs(buf, stdout); //打印内容到终端}fclose(fp);return 0;
}

今天的分享就到这里结束啦,如果有哪里写的不好的地方,请指正。
如果觉得不错并且对你有帮助的话请给个三连支持一下吧!

这篇关于IO进程day02(文件IO)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1109829

相关文章

[Linux]:进程(下)

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:Linux学习 贝蒂的主页:Betty’s blog 1. 进程终止 1.1 进程退出的场景 进程退出只有以下三种情况: 代码运行完毕,结果正确。代码运行完毕,结果不正确。代码异常终止(进程崩溃)。 1.2 进程退出码 在编程中,我们通常认为main函数是代码的入口,但实际上它只是用户级

Java IO 操作——个人理解

之前一直Java的IO操作一知半解。今天看到一个便文章觉得很有道理( 原文章),记录一下。 首先,理解Java的IO操作到底操作的什么内容,过程又是怎么样子。          数据来源的操作: 来源有文件,网络数据。使用File类和Sockets等。这里操作的是数据本身,1,0结构。    File file = new File("path");   字

java 进程 返回值

实现 Callable 接口 与 Runnable 相比,Callable 可以有返回值,返回值通过 FutureTask 进行封装。 public class MyCallable implements Callable<Integer> {public Integer call() {return 123;}} public static void main(String[] args

springboot体会BIO(阻塞式IO)

使用springboot体会阻塞式IO 大致的思路为: 创建一个socket服务端,监听socket通道,并打印出socket通道中的内容。 创建两个socket客户端,向socket服务端写入消息。 1.创建服务端 public class RedisServer {public static void main(String[] args) throws IOException {

C#关闭指定时间段的Excel进程的方法

private DateTime beforeTime;            //Excel启动之前时间          private DateTime afterTime;               //Excel启动之后时间          //举例          beforeTime = DateTime.Now;          Excel.Applicat

linux中使用rust语言在不同进程之间通信

第一种:使用mmap映射相同文件 fn main() {let pid = std::process::id();println!(

Java基础回顾系列-第七天-高级编程之IO

Java基础回顾系列-第七天-高级编程之IO 文件操作字节流与字符流OutputStream字节输出流FileOutputStream InputStream字节输入流FileInputStream Writer字符输出流FileWriter Reader字符输入流字节流与字符流的区别转换流InputStreamReaderOutputStreamWriter 文件复制 字符编码内存操作流(

Golang进程权限调度包runtime

关于 runtime 包几个方法: Gosched:让当前线程让出 cpu 以让其它线程运行,它不会挂起当前线程,因此当前线程未来会继续执行GOMAXPROCS:设置最大的可同时使用的 CPU 核数Goexit:退出当前 goroutine(但是defer语句会照常执行)NumGoroutine:返回正在执行和排队的任务总数GOOS:目标操作系统NumCPU:返回当前系统的 CPU 核数量 p

如何保证android程序进程不到万不得已的情况下,不会被结束

最近,做一个调用系统自带相机的那么一个功能,遇到的坑,在此记录一下。 设备:红米note4 问题起因 因为自定义的相机,很难满足客户的所有需要,比如:自拍杆的支持,优化方面等等。这些方面自定义的相机都不比系统自带的好,因为有些系统都是商家定制的,难免会出现一个奇葩的问题。比如:你在这款手机上运行,无任何问题,然而你换一款手机后,问题就出现了。 比如:小米的红米系列,你启用系统自带拍照功能后

android java.io.IOException: open failed: ENOENT (No such file or directory)-api23+权限受权

问题描述 在安卓上,清单明明已经受权了读写文件权限,但偏偏就是创建不了目录和文件 调用mkdirs()总是返回false. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.READ_E