• 2017-2018-1 20155327 《信息安全系统设计基础》第四周学习总结


    2017-2018-1 20155326 《信息安全系统设计基础》第四周学习总结

    要求

    补充完成课上没有完成的内容(2分)
    学习教材附录A,第十章内容
    参考别出心裁的Linux系统调用学习法,学习视频,掌握两个重要命令:
    man -k key1 | grep key2| grep 2 : 根据关键字检索系统调用
    grep -nr XXX /usr/include :查找宏定义,类型定义
    完成head,tail的使用,相关API的分析,伪代码,产品代码,测试代码的编写(3分)

    改写myod

    1 参考教材第十章内容

    2 用Linux IO相关系统调用编写myod.c 用myod XXX实现Linux下od -tx -tc XXX的功能,注意XXX是文件名,通过命令行传入,不要让用户输入文件名

    3 不要把代码都写入main函数中

    4 要分模块,不要把代码都写入一个.c中

    题目分析

    将原来myod 的标准I/O函数改写为系统调用来访问的I/O
    1.fopen换成系统调用的open
    标准I/O使用fopen函数打开一个文件:
    FILE* fp=fopen(const char* path,const char*mod)

    其中path是文件名,mod用于指定文件打开的模式的字符串,比如"r","w","w+","a"等等,可以加上字母b用以指定以二进制模式打开(对于Linux系统,只有一种文件类型,因此没有区别),如果成功打开,返回一个FILE文件指针,如果失败返回NULL,这里的文件指针并不是指向实际的文件,而是一个关于文件信息的数据包,其中包括文件使用的缓冲区信息。

    Linux系统使用open函数用于打开一个文件:

    int fd=open(char *name,int how);  
    

    与fopen类似,name表示文件名字符串,而how指定打开的模式:O_RDONLY(只读),O_WRONLY(只写),O_RDWR (可读可写),还有其他模式请man 2 open。成功返回一个正整数称为文件描述符,这与标准I/O显著不同,失败的话返回-1,与标准I/O返回NULL也是不同的。
    2将fgets改变成系统调用的read
    fgets使用三个参数:
    char* fgets(char *s, int size, FILE *stream);
    第一个参数和gets一样,用于存储输入的地址,第二个参数为整数,表示输入字符串的最大长度,最后一个参数就是文件指针,指向要读取的文件。最后是fscanf,与scanf类似,只不过增加了一个参数用于指定操作的文件,比如fscanf(fp,"%s",words)

    Linux系统中使用read函数用于读取open函数打开的文件,函数原型如下:

    ssize_t numread=read(int fd,void*buf,size_t qty);  
    

    其中fd就是open返回的文件描述符,buf用于存储数据的目的缓冲区,而qty指定要读取的字节数。如果成功读取,就返回读取的字节数目(小于等于qty)。
    3将fclose改变成close
    ,标准I/O使用fclose关闭文件,将文件指针传入即可,如果成功关闭,返回0,否则返回EOF
    比如:

    if(fclose(fp)!=0)   
     printf("Error in closing file");  
    

    而Linux使用close用于关闭open打开的文件,与fclose类似,只不过当错误发生时返回的是-1,而不是EOF,成功关闭同样是返回0。
    代码如下:

    #include "head.h" 
    #include <stdio.h> 
    #include <stdlib.h> 
    #include <sys/types.h> 
    #include <sys/stat.h> 
    #include <fcntl.h>
     #include <unistd.h> 
    #define SIZE 100
    int main(int argc,char *argv[]) {    
     int fd=open(argv[3],O_RDONLY,0);      
    char ch[SIZE];     
    int length = read(fd,&ch,SIZE);     
    close(fd);     
       
    ascii(ch,length);       
        
    return 0; }
    

    题目结果:

    教材知识总结

    打开和关闭文件

    进程是通过调用open函数来打开一个已存在的文件或者创建一个新文件:

    • flags参数表示进程打算如何访问这个文件,它的值包括:
      O_RDONLY:只读
      O_WRONLY:只写
      O_RDWR:可读可写
      mode参数指定了新文件的访问权限位。作为上下文的一部分,每个进程都有一个umask它是通过调用umask函数来设置的。

    读和写文件

    应用程序是通过分别调用系统函数 read和write函数来执行输入和输出的。

    • read和write传送的字节比应用程序要求的要少。这些不足值不表示有错误。出现这种情况的可能的原因有:
      读时遇到EOF
      从终端读文本行
      读和写网络套接字

    rio的无缓冲的输入输出函数

    通过调用rio_readn和rio_writen函数,应用程序可以在储存器和文件之间直接传送数据。
    rio_readn函数从描述符fd的当前文件位置最多传送n个字节到存储器位置usrbuf。类似的rio_writen函数从位置usrbuf传送n个字节到描述符fd。rio_readn函数在遇到EOF时只能返回一个不足值。rio_writen函数绝不会返回不足值。

    rio的带缓冲的输入函数

    在带缓冲区的版本中,每打开一个描述符都会调用一次rio_readinitb函数,它将描述符fd和地址rp处的一个类型为rio_t的读缓冲区联系起来。
    rio_readinitb函数从文件rp读取一个文本行(包括结尾的换行符),将它拷贝到存储器位置usrbuf,并且用空字符来结束这个文本行。
    RIO读程序的核心是rio_read函数,rio_read函数可以看成是Unix read函数的带缓冲区的版本。当调用rio_read要求读取n个字节的时候,读缓冲区内有rp->rio_cnt个未读的字节。如果缓冲区为空的时候,就会调用read系统函数去填满缓冲区。这个read调用收到一个不足值的话并不是一个错误,只不过读缓冲区的是填充了一部分。
    一旦缓冲区非空,rio_read就从读缓冲区拷贝n和rp->rio_cnt中较小值个字节到用户缓冲区,并返回拷贝字节的数目。
    对于应用程序来说,rio_read和系统调用read有着相同的语义。出错时返回-1;在EOF时,返回0;如果要求的字节超过了读缓冲区内未读的字节的数目,它会返回一个不足值。rio_readlineb函数多次调用rio_read函数。每次调用都从读缓冲区返回一个字节,然后检查这个字节是否是结尾的换行符。

    读取文件元数据

    应用程序能够通过调用stat和fstat函数,检索到关于文件的信息。(有时也称为元数据。)
    stat函数以一个文件名作为输入,填写如图数据结构中的各个成员。

    st_size成员包含了文件的字节数大小。st_mode成员则编码了文件访问许可位和文件类型。Unix识别大量不同的文件类型。普通文件包括某种类型的二进制或文本数据。对于内核而言,文本文件和二进制文件毫无区别。

    掌握两个重要命令

    • man -k key1 | grep key2| grep 2 : 根据关键字检索系统调用

    • grep -nr XXX /usr/include :查找宏定义,类型定义

    完成head,tail的使用,相关API的分析,伪代码,产品代码,测试代码的编写

    head功能:head的功能是显示一个文件前十行的内容

    -伪代码

    循环打印出每行内容直至第十行
    关闭文件,结束````
    - 代码:
    
    ````#include
    
    void main()
    {
    int i,n;
    char buf[500];
    FILE *fp;
    
    if((fp=fopen("test.txt","rt"))==NULL)
    {
    printf("cannot open file
    ");
    return;
    }
    for(i=0;i<10;i++){
    fscanf(fp,"%[^
    ]%*c",buf);
    printf("%s
    ", buf);
    }
    fclose(fp);
    }````
    ####tail
    功能:显示打开文件的后10行内容
    ![](http://images2017.cnblogs.com/blog/1071551/201712/1071551-20171207013617894-1797258244.png)
    - 伪代码
    打开文件
    找到文件后十行
    循环打印出每行内容直至结束
    关闭文件,结束
    - 代码:
    #include
    
    void main()
    {
    int i,n;
    char buf[500];
    FILE fp;
    int num=0;
    if((fp = fopen("test.txt","rt")) == NULL)
    {
    perror("fail to read");
    return;
    }
    while(fgets(buf,500,fp) != NULL)
    {
    num++;
    }
    rewind(fp);
    n=num-10;
    for(i=0;i<n;i++)
    {
    fscanf(fp,"%[^
    ]%c");
    }
    for(i=n;i<num;i++)
    {
    fscanf(fp,"%[^
    ]%c",buf);
    printf("%s
    ",buf);
    }
    fclose(fp);
    }
  • 相关阅读:
    【BZOJ1093】【ZJOI2007】最大半联通子图 [DP][Tarjan]
    【BZOJ1926】【SDOI2010】粟粟的书架 [主席树]
    【BZOJ4069】【APIO2015】巴厘岛的雕塑 [贪心][DP]
    【BZOJ2815】【ZJOI2012】灾难 [LCA]
    【BZOJ3453】XLkxc [拉格朗日插值法]
    【BZOJ2850】巧克力王国 [KD-tree]
    《类和对象》
    @RequestMapping映射请求
    010-Python-socket编程
    SSH-Struts第二弹:一个Form提交两个Action
  • 原文地址:https://www.cnblogs.com/l97----/p/7674768.html
Copyright © 2020-2023  润新知