Linux系统级I/O课后作业

1、分析程序testseek.c执行后,infile文件的内容是什么并进行验证。

#include "wrapper.h"

int main()
{
    
    
    char  s1[6], s2[6];
    int  fd;
    fd = Open("infile" , O_RDWR, 0);
    lseek(fd,10, SEEK_SET);
    Read(fd, s1 , 5);
    s1[5]='\0';
    printf("读出的内容是: %s\n",s1);

    strcpy(s2, "12345");
    lseek(fd,-5, SEEK_CUR);
    Write(fd , s2 , 5 ) ;
    close(fd);
    exit (0) ;
}

答案:ABCDEFGHIJ12345OPQRST

2、创建测试文件infile,内容为“abcdefghijklmnopqrstuvwxyz”;写一个程序,在文件末尾追加一个指定字符’#’,在开始位置写入字符‘^’,在指定位置写入字符’&’;请问程序执行后infile文件的内容是什么?

答案:^abcdefghijklmnopqrs&tuvwxyz#

3、编写一个程序,创建一个大小为100MB的大文件。

代码片段:

fd = open("newFile",O_WRONLY|O_CREAT|O_TRUNC,0777);
lseek(fd,100*1024*1024,SEEK_SET);

4、分析以下程序执行后,文件data的大小是多少?

int main()
{
    
    
	int df,loc1,loc2;
	char ch;
	fd = open("data", O_WRONLY|O_CREAT|O_TRUNC,0777);
	lseek(fd,12345678,SEEK_SET);
	write(fd,&ch,1);
	close(fd);
}

答案:12345679 字节

5、编写程序,把下列变量的值写入文件data1,然后读回显示。

unsigned char a=128;
unsigned short c = 32700;
unsigned char ar[5] = {
    
    129,254,131,112,178};

程序:

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<fcntl.h>

int main()
{
    
    
    unsigned char a=128;
    unsigned short c = 32700;
    unsigned char ar[5] = {
    
    129,254,131,112,178};
    unsigned char ra;
    unsigned short rc;
    unsigned char rar[5];
    int i;
    int fd = open("data1", O_RDWR|O_CREAT|O_TRUNC,0777);
    write(fd,(void*)&a,sizeof(char));
    write(fd,(void*)&c,sizeof(short));
    for(i = 0; i < 5; i++)
        write(fd,(void*)&ar[i],sizeof(char));
    lseek(fd,0,SEEK_SET);
    read(fd,(void*)&ra,sizeof(char));
    read(fd,(void*)&rc,sizeof(short));
    printf("%d\n",ra);
    printf("%u\n",rc);
    for(i = 0; i < 5; i++)
    {
    
        
        read(fd,(void*)&rar[i],sizeof(char));
        printf("%d ",rar[i]);
    }
    printf("\n");
}

6、假设文件a.txt 和 b.txt 都存在,有一下一段代码:

int fd1,fd2,fd3,fd4;
fd1 = open("a.txt", O_RDONLY,0);
fd2 = open("b.txt", O_WRONLY,0);
fd3 = dup(fd1);
fd4 = dup2(fd4,0);

请给出执行这段代码后fd1、fd2、fd3、fd4的值。

答案:fd1 = 3 、fd2 = 4、 fd3 = 5、 fd4 = 0

7、编写程序 Cat.c,实现命令cat的功能以显示文本文件的内容,比如执行"./cat /etc/passwd" 命令时,在终端显示文件/etc/passwd的内容。

程序:

#include <stdio.h>
int main(int argc, char *argv[])
{
    
    
    int read_ret;

    if(argc < 2)
    {
    
    
        printf("ERROR\n");
        return -1;
    }

    FILE *fp = fopen(argv[1], "r");
    if(fp == NULL)
    {
    
    
        printf("ERROR\n");
        return -1;
    }

    while(1)
    {
    
    
        read_ret = fgetc(fp);
        if(feof(fp))
        {
    
      
            printf("\n");
            break;
        }
        fputc(read_ret,stdout);
    }
}

8、编写程序Hex.c,以十六进制形式显示文件内容,每个字节用两个十六进制数字表示,每行显示40个字节内容。比如字符’a’的ASCII码是 0x61,如果某个文件的内容是’aaaa’,则显示结果应该是“61 61 61 61”。

代码:

#include <stdio.h>

int main(int argc, char *argv[])
{
    
    
    int read_ret;

    if(argc < 2)
    {
    
    
        printf("ERROR\n");
        return -1;
    }

    FILE *fp = fopen(argv[1], "r");
    if(fp == NULL)
    {
    
    
        printf("ERROR\n");
        return -1;
    }
    
    int i = 1;

    while(1)
    {
    
    
        read_ret = fgetc(fp);
        if(feof(fp))
        {
    
      
            printf("\n");
            break;
        }
        if(i == 1)
        {
    
    
           printf("%2x",read_ret); 
           i++;
        }
        else if(i < 40)
        {
    
    
            printf("%3x",read_ret);
            i++;
        }
        else
        {
    
    
            printf("%3x\n",read_ret);
            i = 1;
        }
    }
}

9、假设文件infile的内容是“abcdefghijklmnopqrstuvwxyz\n”,请写出以下程序的输出结果:

#include<stdio.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{
    
    
	int fd, loc1,loc2;
    char ch;
    fd = open("infile",O_RDONLY,0);
    loc1=lseek(fd,10,SEEK_CUR);
    read(fd,&ch,1);
    loc2=lseek(fd,0,SEEK_END);
    printf("loc1=%d ch=%c,loc2=%d\n",loc1,ch,loc2);
    close(fd);
}

输出:

loc1=10、ch=k、loc2=27

10、有一个元素类型为T的数组a,定义为“T a[n];”,其中N 为常量。已将数组写入新文件 fa,描述符为fd。

(1)计算元素a[k]距数组a起始位置的字节偏移量。

(2)计算元素a[k]在文件fa中的位置。

(3)定义变量“T e”,写一段代码,从文件fd将元素a[k]的内容读入变量e。

答案:

(1)sizeof(T) * k

(2)sizeof(T) * k

(3)lseek(fd,sizeof(T) * k, SEEK_SET);
read(fd,&e,sizeof(T));

11、编写程序,输入5个学生的成绩信息,包括学号、姓名、语文、数学、英语,成绩允许有一位小数,存入一个结构体数组,该结构体的定义为:

typedef struct _subject
{
    
    
    char sno[20];
    char name[20];
    float chinese;
    float math;
    float english;
}subject;

将学生信息逐条写入数据文件data,最后读回1、3、4条学生成绩记录,显示出来,检查读出结果是否正确。

程序:

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<fcntl.h>

typedef struct _subject
{
    
    
    char sno[20];
    char name[20];
    float chinese;
    float math;
    float english;
}subject;

int main()
{
    
    
    subject subs[5] = {
    
    {
    
    "2000","谭伟恒",100,95.5,90.5},
    {
    
    "2001","谭伟哥",99,94.5,89.5},
    {
    
    "2002","谭伟人",98,93.5,88.5},
    {
    
    "2003","谭伟天",97,92.5,87.5},
    {
    
    "2004","谭伟的",96,91.5,86.5}};

    int fd,i;
    fd = open("data",O_WRONLY|O_CREAT|O_TRUNC,0777);
    for(i=0; i<5; i++)
        write(fd,(void*)&subs[i],sizeof(subject));
    close(fd);

    subject sub;
    fd = open("data",O_RDONLY,0);
    for(i = 0; i < 5; i++)
    {
    
    
        read(fd,(void*)&sub,sizeof(subject));
        if(i == 0 || i == 2 || i == 3)
            printf("%s  %s  %f  %f  %f\n",sub.sno,sub.name,sub.chinese,
            sub.math,sub.english);
    }
    close(fd);
}

输出:
在这里插入图片描述

12、假设数组var的元素类型为T、大小为N、其定义为T var[N]。请编写程序,将其内容写入文件data,要求除最后的write函数调用外,每次写操作传输的字节数为B。

程序:

#include<iostream>
#include<sys/types.h>
#include<unistd.h>
#include<fcntl.h>

using namespace std;

template<typename T>
void writeArray(T * var, int n, const char * name)
{
    int fd,i;
    int B = sizeof(T);
    fd = open(name,O_WRONLY|O_CREAT|O_TRUNC,0777);
    for(i=0; i<10; i++)
        write(fd,(void*)&var[i],B);
    close(fd);
}

template<typename T>
void readArray(T * var, int n, const char * name)
{
    int fd,i;
    int B = sizeof(T);
    T temp;
    fd = open(name,O_RDONLY,0);
    for(i=0; i<10; i++)
    {    
        read(fd,&temp,B);
        cout<<temp<<" ";
    }
    cout<<endl;
    close(fd);
}

int main()
{
    int var[10] = {101,102,103,104,105,106,107,108,109,110};
    writeArray(var,10,"data");
    readArray(var,10,"data");
}

13、结合文件I/O 内核数据结构,说明open和close函数的执行过程,为何读写文件之前要打开文件?

答案:

当程序中执行open函数打开时文件时,系统首先检查该文件的v_node是否存在,若不存在,则先为其创建其v_node,将文件的属性从外存读入v-node;接着,创建其文件表(file table)表项,设置读写方式、读写位置、v-node指针,访问计数器置为1;然后,在进程的描述符表中找到索引号最小的空闲表项,在其中填入文件表表项的指针,返回描述符表项的索引号。

调用close函数关闭某个文件时,如果v-node引用计数大于1,则计数值减1,仅当关闭文件对象引用计数为1的文件时,才能销毁文件对象。

14、假设文件a.txt 的内容是"abcdefghijklmnopqrstuvwxyz",文件b.txt的内容是"0123456789",当前进程对两个文件都有读写权限,请写出下列函数的输出结果。

输出:

The oldfd1 file descriptor =3

The oldfd2 file descriptor =4

The newfd file descriptor =5

The newfd2 file descriptor =0

I have read from a.txt:abcdefgh

15、阅读下面的程序,按要求回答问题

int main()
{
    
    
    int fd;
    fd = open("f2.txt",O_RDWR|O_CREAT,0621);
    close(fd);
}

程序编译完后执行如下命令,请写出文件f2.txt的权限

$umask -p 0022
$./f2
$ls -l f2.txt

答案:文件f2.txt权限为 0601

16、文件f31.txt的内容为空,文件f3.txt的内容为“123456789abcdefg\n”,请写出下面程序p3.c运行后,f32.txt文件的内容。

int main()
{
    
    
    int rbytes,wbytes,fd1,fd2;
    char buf[10];
    fd = open("f3.txt",O_RDONLY,0);
    lseek(fd,-10,SEEK_END);
    rbytes = read(fd1,buf,5);
    buf[5] = '\0';
    fd2 = open("f31.txt",O_WRONLY,0777);
    close(1);
    dup(fd2);
    close(fd2);
    printf("%s\n",buf);
    close(fd1);
}

输出:89abc

17、分析和验证下列程序的输出

#include<fcntl.h>
#include<stdio.h>
main()
{
    
    
    int fd1,fd2,fd3;
    fd1 = open("f1",O_RDWR);
    fd2 = open("f2",O_RDWR);
    printf("fd1=%d\nfd2=%d\n",fd1,fd2);
    close(fd1);
    fd3 = open("f3",O_RDWR);
    printf("fd3=%d\n",fd3);
    close(fd2);
    close(fd3);
}

输出:

fd1=6
fd2=7
fd3=6

注释:理论上应该是3,4,3才对,但是跑出来的结果是6,7,6……求大佬解释……

18、假定用户对当前目录下存在的 f1.txt和 f2.txt两个文件都有读权限,下面程序输出是什么?

int main()
{
    
    
    int fd1,fd2;
    fd1 = open("f1.txt",O_RDDNLY,0); //印刷错误,应该为O_RDONLY
    dup(fd1);
    dup2(fd1,6);
    fd2 = open("f2.txt",O_RDDNLY,0); //印刷错误,应该为O_RDONLY
    printf("fd2 = %d\n",fd2);
    exit(0);
}

输出:

fd2 = 8

注释:理论上应该是5才对,但是跑出来的结果是8……求大佬解释……

19、假设磁盘文件f.txt 由六个ASCII码字符“silent”组成。写出下列程序的输出。

int main()
{
    
    
    int fd1, fd2;
    char c;
    fd1 = open("f.txt",O_RDONLY,0);
    fd2 = open("f.txt",O_RDONLY,0);
    read(fd1,&c,1);
    printf("c1 = %c\n",c);
    read(fd2, &c, c);
    printf("c2=%c\n",c);
    exit(0);
}

输出:

c1 = s
c2 = s

20、假设文件test.txt存在,当前用户具有读写权限,请写出下列程序的输出结果。

int main()
{
    
    
    int fd1,fd2,fd3;
    fd1 = open("test.txt",O_RDWR | O_TRUNC);
    fd2 = dup(fd1);
    printf("fd2=%d\n",fd2);
    close(0);
    fd3=dup(fd1);
    printf("fd3=%d\n",fd3);
}

输出:

fd2=7
fd3=0

注释:理论上应该是4,0才对,但是跑出来的结果是7,0……求大佬解释……

21、下面是一段关于系统I/O的程序,请认真阅读并按要求回答问题。

int main()
{
    
    
    int rbytes,wbytes,fd1,fd2;
    char buf;
    fd1 = open("f1a.txt",O_RDONLY,0);
    fd2 = open("f1b.txt",O_WRONLY|O_CREAT,0600);
    while(rbytes=read(fd1,buf,1)>0)
    {
    
    
        if(buf>'a' && buf <='z')
            buf=toupper(buf);
        wbytes=write(fd2,&buf,rbytes);
    }
    close(fd1);
    close(fd2);
}

成果执行上面的程序后,执行下面两条命令:

$cat f1a.txt
2016 linux exam GOOD!GOOD!
$cat f1b.txt

输出:

2016 LINUX EXAM GOOD!GOOD!

22、为测量某个函数func的执行时间,通常可调用函数gettimeofday,取得代码段执行前后的系统时间t1,t2,如下所示:

M1 = gettimeofday();
for(i =0; i < N; i++)
    func();
M2 =gettimeofday();

将两者相减,得到代码段for(i =0; i < N; i++) func();的测量时间为 M2-M1

(1)请给出func()函数的测量时间M的表达式。

(2)假设时间测量误差是Delta1,代码段for(i =0; i < N; i++)的执行时间为Delta2,不考虑多任务切换带来的影响,请给出func()函数的真实执行时间T,讨论如何减少测量误差。

答案:

(1)M= (M2 -M1)/N

(2)真实执行时间测量误差为(Delta1+Delta2)/ N,由于Delta1为定值,通过增大N可减少测量误差

23、在Linux环境下,调用库函数gettimeofday,测量一个代码段的执行时间。请写一个程序,测量一次read和一次fread函数调用所需要的执行时间,并对测量结果给出解释。

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdlib.h>
#include<sys/time.h>

int main()
{
    
    
    int fd1;
    FILE *fp;
    char buf;
    struct timeval time_start;
    struct timeval time_end;
    fd1 = open("test.txt",O_RDONLY);
    fp = fopen("file.txt", "r");
    gettimeofday(&time_start,NULL);
    read(fd1,&buf,1);
    gettimeofday(&time_end,NULL);
    double wa= time_end.tv_usec - time_start.tv_usec;
    double sa= time_end.tv_sec - time_start.tv_sec;
    double ms = wa / 1000.0 + sa * 1000.0;
    printf("%lfms\n",ms);
    gettimeofday(&time_start,NULL);
    fread(&buf, 1, 1, fp);
    gettimeofday(&time_end,NULL);
    wa= time_end.tv_usec - time_start.tv_usec;
    sa= time_end.tv_sec - time_start.tv_sec;
    ms = wa / 1000.0 + sa * 1000.0;
    printf("%lfms\n",ms);
    close(0);
}

输出结果:

0.002000ms
0.021000ms
fread,自动分配缓存,速度相对read会快

猜你喜欢

转载自blog.csdn.net/Qingyuyuehua/article/details/114758281
今日推荐