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会快