# 2018-2019-1 20165317 第六周学习总结

2018-2019-1 20165317 第六周学习总结

教材学习内容总结

输入/输出(I/O)是主存和外部设备(I/O设备)(如磁盘驱动器、终端、网络)之间拷贝数据的过程。输入是从I/O设备拷贝到主存。反之则反。

10.1Unix I/O

  • Unix文件就是一个m字节的序列:b0,b1,b2….bm-1。所有的I/O设备都被虚拟化为文件。所有的输入输出都是在当成相对应的文件的读写。将设备映射为文件,Unix内核引出一个应用接口,Unix I/O。
  • 输入输出的执行方式:
    • 打开文件:打开文件,内核会返回描述符。标准输入(STDIN_FILENO)描述符为0、标准输出(STDOUT_FILENO)描述符为1、标准错误(STDERR_FILENO)描述符为2。也就是说在Unix生命周期一开始,0、1、2就被占用,以后的open只能从3开始——习题10.1
    • 改变当前文件位置:文件位置k,是文件开头起始的字节偏移量。
    • 读写文件:读是从文件拷贝到存储器。写相反。当k超过文件字节数m时,会触发end-of-file(EOF)条件。
    • 关闭文件:释放文件打开时创建的数据结构(释放文件的存储器资源),将描述符恢复到可用的描述符池中。

10.2打开和关闭文件

  • 1.open函数

(1)函数定义:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int open(char *filename, int flags, mode_t mode);

(2)参数解析:

返回值:类型为int型,返回的是描述符数字,总是在进程中当前没有打开的最小描述符。如果出错,返回值为-1.
  • filename:文件名
  • flags:指明进程打算如何访问这个文件,可以取的值见下:

    O_RDONLY:只读

    O_WRONLY:只写

    O_RDWR:可读可写

    O_CREAT:文件不存在,就创建新文件

    O_TRUNC:如果文件存在,就截断它

    O_APPEND:写操作前设置文件位置到结尾处

    这些值可以用“或”连接起来。

  • mode:指定了新文件的访问权限位,符号名称如下:

      

  • 2.close函数

(1)函数定义:

#include <unistd.h>

int close(int fd);

(2)参数解析:

返回值:成功返回0,出错返回-1

关闭一个已经关闭的描述符会出错

fd:即文件的描述符。

10.3读和写文件

  • 1.读 read

(1)函数原型:

#include <unistd.h>

ssize_t read(int fd, void *buf, size_t n);//返回有符号值

(2)参数解析:

返回值:成功则返回读的字节数,EOF返回0,出错返回-1。返回值为有符号数。
fd:文件描述符
buf:存储器位置
n:最多从当前文件位置拷贝n个字节到存储器位置buf
  • 2.写 write

(1)函数原型:

#include <unistd.h>

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

(2)参数解析:

返回值:成功则返回写的字节数,出错返回-1。返回值为有符号数。
fd:文件描述符
buf:存储器位置
n:最多从存储器位置buf拷贝n个字节到当前文件位置
  • 需要注意的是,read和write在正常情况下返回值是实际传送的字节数量。
  • 3.不足值
      不足值指在某些情况下,read和write传送的字节比应用程序要求的要少,原因如下:
      读的时候遇到EOF
      从终端读文本行
      读和写socket

10.4用RIO包健壮地读写

  • RIO包能自动地处理不足值。提供了两个函数:无缓冲的输入输出函数,带缓冲的输入函数。
  • RIO的无缓冲的输入输出函数

这些函数的作用是直接在存储器和文件之间传送数据,常适用于网络和二进制数据之间。

rio_readn函数和rio_writen定义:

#include "csapp.h"

ssize_t rio_readn(int fd, void *usrbuf, size_t n);
ssize_t rio_writen(int fd, void *usrbuf, size_t n);

参数:

fd:文件描述符
usrbuf:存储器位置
n:传送的字节数

返回值:

rio_readn成功则返回传送的字节数,EOF为0(一个不足值),出错为-1
rio_writen成功则返回传送的字节数,出错为-1,没有不足值。
  • RIO的带缓冲的输入函数

    • 可以高效的从文件中读取文本行和二进制数据。
    • 文本行就是一个由换行符结尾的ASCII码字符序列。换行符数字值为0x0a.rio_readlineb函数从内部读缓冲区拷贝一个文本行,当缓冲区为空时,会自动地调用read重新填满缓冲区。rio_readn带缓冲区的版本:rio_readnb。
    • rio_readlineb从rp读出一个文本行(包括换行符)并把它存到usrbuf,并用空字符结束这个文本行。最多读maxlen-1个字节,剩下一个给结尾处的空字符。
    • rio_readnb最多读n个字节。

10.5读取文件元数据

  • 检索文件元数据的方式:调用stat和fstat函数。两者功能相似。

    • stat数据结构中的成员。重点掌握st_mode,st_size.

       st_size:文件字节数大小
      
       st_mode:文件访问许可位和文件类型。(普通文件:二进制文件和文本文件。目录文件:其他文件信息。套接字:通过网络与其他进程通信的文件。)

10.6共享文件

  • 用三个相关的数据结构表示打开的文件:

    • 描述符表:每个打开的描述符表项指向文件表中的一个表项。
    • 文件表:打开的文件的集合是由一张文件表表示的,所有的进程共享这张表。包括文件位置、引用计数(当前指向该表项的描述符表项数),指向v-node表的指针。
    • v-node表:包含stat结构中大多数信息。

      打开文件的内核数据结构:

      文件共享。共享了同一个磁盘文件:

    子父进程共享文件。子进程有一个父进程描述表符副本,所以他们共享打开文件的集合。注意,在内核删除相应文件表表项之前,子父进程必须都关闭他们的描述符。

10.7 I/O重定向

  • I/O重定向操作符: >

      ls > foo.txt

这句代码的含义就是使外壳加载和执行ls程序,并且将标准输出重定向到磁盘文件foo.txt。

  • I/O重定向函数: dup2

    函数定义为:

      #include <unistd.h>
    
      int dup2(int oldfd, int newfd);

返回值:成功返回描述符,错误返回-1

- 这个函数执行的操作是,拷贝描述符表表项oldfd,覆盖描述表表项newfd,如果后者被打开,则在拷贝前关闭它。

10.8 标准I/O

标准I/O库:一组高级输入输出函数。将一个打开的文件模型化为一个流,一个流即一个指向FILE类型的结构的指针。

每个ANSI C程序开始时都有三个打开的流:stdin(标准输入),stdout(标准输出),stderr(标准错误)。

类型为FILE的流是对文件描述符和流缓冲区的抽象。为了减小系统开销。

10.9 综合:该使用哪些I/O函数

在网络套接字的时候使用RIO函数。需要格式化输出,使用sprintf函数格式化一个字符串,然后用rio_writen把它发送到套接口。

格式化输入,使用rio_readlineb读一个完整的文本行,再使用scanf从文本行提取不同字段。

原文地址:https://www.cnblogs.com/ningxinyu/p/9905372.html

时间: 2024-11-08 20:57:29

# 2018-2019-1 20165317 第六周学习总结的相关文章

20145317《信息安全系统设计基础》第六周学习总结(1)

20145317<信息安全系统设计基础>第六周学习总结(1) 第四章 处理器体系结构 指令体系结构:一个处理器支持的指令和指令的字节级编码 4.1Y86指令集体系结构 Y86:包括定义各种状态元素.指令集和它们的编码.一组编程规范和异常事件处理. Y86程序中的每条指令都会读取或修改处理器状态的某些部分.Y86具体包括:8个程序寄存器.3个条件码ZF\SF\OF.程序计数器(PC) Y86用虚拟地址引用存储器位置. 程序状态的最后一个部分是状态码Stat,它表明程序执行的总体状态. 注意:条件

20145222《信息安全系统设计基础》第六周学习总结(1)

20145222<信息安全系统设计基础>第六周学习总结(1) 第四章 处理器体系结构 指令体系结构:一个处理器支持的指令和指令的字节级编码 4.1Y86指令集体系结构 · Y86:包括定义各种状态元素.指令集和它们的编码.一组编程规范和异常事件处理. · Y86程序中的每条指令都会读取或修改处理器状态的某些部分.· Y86具体包括:8个程序寄存器.3个条件码ZF\SF\OF.程序计数器(PC) · Y86用虚拟地址引用存储器位置. 程序状态的最后一个部分是状态码Stat,它表明程序执行的总体状

《Linux内核分析》第六周学习笔记

<Linux内核分析>第六周学习笔记 进程的描述和创建 郭垚 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 [学习视频时间:1小时 撰写博客时间:2小时] [学习内容:进程创建的过程.使用gdb跟踪分析内核处理函数sys_clone] 一.进程的描述 1.1 进程描述符task_struct数据结构(一) 1. 进程控制块PCB——task_struct 为了管理进程,内核

20145307《信息安全系统设计基础》第六周学习总结

20145307<信息安全系统设计基础>第六周学习总结 教材学习内容总结 Y86指令集体系结构 内容:定义一个指令集体系结构,包括定义各种状态元素.指令集和它们的编码.一组编程规范和异常事件处理. 程序员可见状态 Y86程序中的每条指令都会读取或修改处理器状态的某些部分. Y86具体包括:8个程序寄存器.3个条件码ZF\SF\OF.程序计数器(PC). Y86用虚拟地址引用存储器位置. 程序状态的最后一个部分是状态码Stat,它表明程序执行的总体状态. Y86指令 IA32指令集的一个子集,只

20145301第六周学习总结

20145301第六周学习总结 教材学习内容总结 第十章 输入/输出 10.1 InputStream与OutputStream InputStream与OutputStream  流(Stream)是对「输入输出」的抽象,注意「输入输出」是相对程序而言的  InputStream与OutputStream InputStream.OutStream提供串流基本操作,如果想要为输入/输出的数据做加工处理,则可以使用打包器类.常用的打包器具备缓冲区作用的BufferedOutputStream.B

20145319 第六周学习总结

20145319 <Java程序设计>第六周学习总结 教材学习内容总结 本周学习教材的第十.十一章,主要讲述了串流,字符处理和线程以及并行API 1. 输入输出 串流:1Java中的数据有来源(source)和目的地(destination),衔接两者的就是串流对象2串流设计:在不知道限定数据来源和目的地时,也可以依赖抽象的InputStream和Outstream来编写一个dump()方法,方便以后使用3InputStream和OutputStream:在java中,输入串流代表对象为jav

LINUX内核分析第六周学习总结——进程的描述和进程的创建

LINUX内核分析第六周学习总结——进程的描述和进程的创建 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.知识概要 进程的描述 进程描述符task_struct数据结构(一) 进程描述符task_struct数据结构(二) 进程的创建 进程的创建概览及fork一个进程的用户态代码 理解进程创建过程复杂代码的方法 浏览进程创建过程相关的关键代码 创建的新进程是从哪里开始执行的

20145311 《信息安全系统设计基础》第六周学习总结

20145311 <信息安全系统设计基础>第六周学习总结 教材学习内容总结 书上那几个表还是挺重要的 一个程序编译成在一种机器上运行,就不能在另一种机器上运行寄存器%esp被入栈.出栈.调用和返回指令作为栈指针程序计数器PC存放当前正在执行指令的地址三个一位的条件吗:ZF.SF.OF保存着最近的算数运算或逻辑运算所造成影响的有关信息Y86指令集:每个指令的第一个字节表明指令的类型,高4位是代码部分,低4位是功能部分指令集的一个重要性质就是字节编码必须有唯一的解释IA32(复杂指令集计算机CIS

20165315 第六周学习总结

20165315 第六周学习总结 本周学习中遇到的问题和解决过程 在编写第八章例子7时,编译正常,但运行时出现如下问题: 解决过程: 经过多次尝试,我发现在我的电脑系统下,一个汉字是占3个字节的,故不能完全照抄书上代码,修改后即可运行出正确结果: 在编写第八章例子21时,出现如下问题: 解决过程: 在命令行中是可以实现的 询问了许多同学,还没有找到在IDEA中实现的解决方法,找到后会补上这部分 在编写第十五章例子11时,运行没有问题,出现如下窗口: 但是输入需要录入的数据后,点击"录入"