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

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

1.myod-系统调用版本

(1). 题目要求:

1.参考教材第十章内容

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

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

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

5.提交测试代码和运行结果截图, 提交调试过程截图,要全屏,包含自己的学号信息

(2)实现过程

1. od 命令能干什么

通过

man od

来查看

用户通常使用od命令查看特殊格式的文件内容。通过指定该命令的不同选项可以以十进制、八进制、十六进制和ASCII码来显示文件。

2.如何实现myod-系统调用版本

对比两次myod的实习,这次的myod需要使用系统调用,即open和read。

open

函数open是UNIX系统的系统调用函数,区别于C语言库函数fopen。包含在头文件

#include <fcntl.h>

,作用:打开和创建文件。

int open(constchar*pathname, int flags);    
int open(constchar*pathname, int flags, mode_t mode);

返回值:成功则返回文件描述符,否则返回-1
参数说明:对于open函数来说,第三个参数仅当创建新文件时(即使用了O_CREAT 时)才使用,用于指定文件的访问权限位(access permission bits)。pathname是待打开/创建文件的POSIX路径名(如/home/user/a.cpp);flags用于指定文件的打开/创建模式,这个参数可由以下常量(定义于fcntl.h)通过逻辑位或逻辑构成。

O_RDONLY 只读模式
O_WRONLY 只写模式
O_RDWR 读写模式
read

通过 man 2 read 来了解相关知识。

返回值:

RETURN VALUES
     If successful, the number of bytes actually read is returned.  Upon read-
     ing end-of-file, zero is returned.  Otherwise, a -1 is returned and the
     global variable errno is set to indicate the error.

返回值-1表示一个错误,而返回值0表示EOF。否则,返回值表示的是实际传送的字节数量。

实现myod

通过对上个版本的myod进行修改。

fd=open(argv[1], O_RDONLY,0);

通过调用open函数来打开文件。

read(fd,&ch,1)!=0

通过read函数来读取文件。
主函数:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, const char * argv[]) {
    // insert code here...
    int fd;
    fd=open(argv[1], O_RDONLY,0);
    myod(fd);
    close(fd);
}

myod:

void myod(int fd)
   {
       char c,line[16];
       int i;
      int k=0;
      int j=0;
      while(read(fd,&c,1)!=0){
      line[j%16]=c;
      if((j+1)%16==0){
      printf("%07o  ",16*k);
     k++;
      for(j=0;j<16;j++)
      {
              printf("%3c",line[j]);
              putchar('\0');
       }
          printf("\n");
         printf("\t");
         putchar(' ');
 for(int m=0;m<16;m++)
          {
              printf("%3x",line[m]);
              putchar('\0');
          }
         printf("\n");
          putchar('\n');}
      j++;
       }
  }

结果截图:

完成head,tail

RIO 一个用缓冲区实现的IO系统

  3.1 RIO中rio_read函数的编写思想:

    a)采用预读取方案,提前把数据读入Buffer;

    b)每当用户取数据的时候,从Buffer里面读取,而不是使用系统调用read函数,这样减少了多次使用系统调用的开销。

   3.2 rio_read函数的编写原则:必须与系统的 read 函数保持语义一致,这意味着rio_read的返回值有三种情况:

    a) -1代表出错,这里不包含EINTR;

    b) 0代表EOF,读取结束;

    c) >0表示读取的字节数。

首先查看head和tail的功能;



实际使用:

设计思路:同样通过open和read来读取文件,只需要控制读取的行数(10行),即可实现所需的功能;

主函数:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc,char *argv[])
{
    
    
    int fd=0;
    
    fd=open(argv[1],O_RDONLY);
    mh(fd);
    close(fd);
    return 0;
}

mh函数:

void mh(int fd){
    int count=0;
    char c;
    while(read(fd,&c,1)!=0)
    {
        putchar(c);
        if(c == '\n')
        count++;
        if(count == 10)
        break;
    }
}

结果截图:

TAIL

产品代码:
设计思路:先统计文件有多少行,然后输出后十行

    1#include <stdio.h>
  2 #include <stdlib.h>
  3 #include <unistd.h>
  4 #include <sys/types.h>
  5 #include <sys/stat.h>
  6 #include <fcntl.h>
  7 int  ct(int fd){
  8     int count=0;
  9     char c;
 10     while(read(fd,&c,1)!=0)
 11     {
 12        if(c == '\n')
 13         count++;
 14
 15     }
 16     return count;
 17     }
 18 void mh(int fd,int n)
 19 {
 20     int count=0;
 21     char c;
 22     while (read(fd, &c, 1)!=0) {
 23             if (c=='\n')
 24             {
 25             count++;
 26             }
 27         if (count>=n-10) {
 28             putchar(c);
 29
 30             }
 31
 32     }
 33
 34 }
 35 int main(int argc,char *argv[])
 36 {
 37
 38
 39     int fd=0,ft=0;
 40     int count;
 41     fd=open(argv[1],O_RDONLY);
 42     count=ct(fd);
 43    close(fd);
 44     ft=open(argv[1],O_RDONLY);
 45     mh(fd,count);
 46      close(ft);
 47      return 0;
 48 }

截图:
因为重复使用了hello.txt文件,第一次就把指针移动到了文件尾,所以第二次就没有任何输出。后来查找资料,找到了问题,也找到了解决的方法:使用fseek函数进行跳转。比如“起始点”参数设置为SEEK_SET 即可将文件指针挪到文件开头位置再次读取,反复这样操作,即可实现重复读取文件。

fseek(fp,100L,SEEK_SET);   //将文件位置标记向前移到离文件开头100
posted @ 2017-10-15 21:41  徐志瀚  阅读(294)  评论(5编辑  收藏  举报