实验1 linux文件系统
题目一
编写代码,完成以下功能:
-
创建文件file1,写入字符串“abcdefghijklmn”;
-
创建文件file2,写入字符串“ABCDEFGHIJKLMN”;
-
读取file1中的内容,写入file2,使file2中的字符串内容为“ ABCDEFGHIJKLMNabcdefghijklmn”
#include<stdio.h> #include<dirent.h> #include<stdlib.h> #include<string.h> #include<sys/types.h> #include<fcntl.h> #include<unistd.h> int main() { char str1[15] = "abcdefghijklmn"; char str2[15] = "ABCDEFGHIJKLMN"; char str3[15]; char str4[15]; char str5[32]; int bits; int fd1 = open("file1.txt",O_RDWR|O_CREAT,S_IRWXU|S_IRWXG|S_IRWXO); int fd2 = open("file2.txt",O_RDWR|O_CREAT,S_IRWXU|S_IRWXG|S_IRWXO); //写入内容 bits = write(fd1,str1,14); bits = write(fd2,str2,14); //读取第一个文件 lseek(fd1,SEEK_SET,0); bits = read(fd1,str3,14); printf("第一个文件的字节数: %d\n",bits); printf("第一个文件的内容: "); int i; for(i=0; i<bits; i++) printf("%c ",str3[i]); printf("\n"); //读取第二个文件 lseek(fd2,SEEK_SET,0); bits = read(fd2,str4,14); printf("第二个文件的字节数: %d\n",bits); printf("第二个文件的内容: "); for(i=0; i<bits; i++) printf("%c ",str4[i]); printf("\n"); //把第一个文件内容写入第二个文件中 lseek(fd2,SEEK_SET,14); bits = write(fd2,str3,14); //读取写入过后第二个文件的内容 lseek(fd2,SEEK_SET,0); bits = read(fd2,str5,31); printf("第二个文件的字节数: %d\n",bits); printf("第二个文件的内容: "); for(i=0; i<bits; i++) printf("%c ",str5[i]); printf("\n"); //关闭 close(fd1); close(fd2); return 0; }
运行截图
题目二
编写代码,完成以下功能:
-
创建新文件,该文件具有用户读写权限;
-
采用dup/dup2/fcntl复制一个新的文件描述符,通过新文件描述符向文件写入“class_name”字符串;
-
通过原有的文件描述符读取文件中的内容,并且打印显示;
#include<stdio.h> #include<fcntl.h> #include<unistd.h> #include<string.h> #include<sys/stat.h> int main(int argc,char *argv[]) { int fd=-1; int fd2=-1;//新的文件描述符 int wrnum,rdnum=0; char *buf="hello world!\n"; char buf1[128]= {0}; umask(0);//修改umask值 fd=open(argv[1],O_CREAT|O_RDWR,0600); if(fd==-1) { perror("open"); return -1; } //复制文件描述符 fd2=dup(fd);//选取未被使用的最小的文件描述法 wrnum=write(fd2,buf,strlen(buf));//使用新的文件描述符写入字符串 if(wrnum==0) { //如果写入失败 perror("write"); return -1; } //此时文件指针位于文件末尾 lseek(fd,0,SEEK_SET);//将文件指针指向文件开始 rdnum=read(fd,buf1,128);//使用老的文件描述符将文件中的信息读取到buf1中 if(rdnum==0) { perror("read"); return -1; } printf("%s",buf1);//打印出读取的字符串 return 0; }
运行截图
题目三
编写程序实现以下功能:
-
输入文件名称,能够判断文件类型,判断实际用户对该文件具有哪些存取权限;
-
要求打印出文件类型信息,inode节点编号,链接数目,用户id,组id,文件大小信息;
-
修改文件的权限为当前用户读写,组内用户读写,组外用户无权限。
#include<stdio.h> #include<fcntl.h> #include<unistd.h> #include<sys/stat.h> int main(int argc,char *argv[]) { unsigned int i,mask=0700; //111 000 000 struct stat buf; char *ptr; static char *BUF[]= {"---","--x","-w-","-wx","r--","r-x","rw-","rwx"}; if((stat(argv[1],&buf))==-1) { perror("stat"); return -1; } if(S_ISREG(buf.st_mode))//是否为普通文件 ptr="regular file "; else if(S_ISDIR(buf.st_mode))//是否为目录文件 ptr="directory file "; else if(S_ISCHR(buf.st_mode))//是否为字符设备文件 ptr="char dev file "; else if(S_ISBLK(buf.st_mode))//是否为块设备文件 ptr="block file "; else if (S_ISFIFO(buf.st_mode))//是否为管道文件 ptr="FIFO file "; printf("%s:%s ",argv[1],ptr); for(i=3; i; --i) { printf("%3s ",BUF[(buf.st_mode&mask)>>(i-1)*3]); mask>>=3; } printf("inode=%ld nlink=%ld uid=%d gid=%d size=%ld \n",buf.st_ino,buf.st_nlink,buf.st_uid,buf.st_gid,buf.st_size); if(chmod(argv[1],S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)==-1) { //将文件权限修改为拥有者可读写、组用户可读写 perror("chmod"); return -1; } return 0; }
运行截图
题目四
编写程序实现以下功能:
-
新建文件,设置文件权限屏蔽字为0;
-
建立该文件的硬链接文件,打印硬链接文件的inode节点号和文件大小;
-
建立该文件的软链接文件,打印软链接文件的inode节点号和文件大小;打印软链接文件中的内容;
-
打印源文件的inode节点号,文件大小和链接数目;
-
调用unlink对源文件进行操作,打印源文件链接数目;
#include<stdio.h> #include<fcntl.h> #include<unistd.h> #include<sys/stat.h> int main(int argc,char *argv[]) { int fd_c; umask(0); struct stat buf; char BUF[128]= {0}; if(fd_c=creat(argv[1],0755)==-1) { perror("create"); return -1; } if(link(argv[1],"hard_linkfile")==-1) { //创建硬链接 perror("link"); return -1; } if(lstat("hard_linkfile",&buf)==-1) { //读取硬链接文件属性 perror("lstat"); return -1; } printf("hard_linkfile_inode=%ld,size=%ld\n",buf.st_ino,buf.st_size);//打印硬链接信息 if(symlink(argv[1],"sym_linkfile")==-1) { //创建软连接 perror("symlink"); return -1; } if(lstat("sym_linkfile",&buf)) { //读取软连接文件属性 perror("lstat"); return -1; } if(readlink("sym_linkfile",BUF,sizeof(BUF))==-1) { //读取软连接文件内容 perror("readlink"); return -1; } printf("sym_linkfile_inode=%ld,size=%ld,read=%s\n",buf.st_ino,buf.st_size,BUF); if(stat(argv[1],&buf)==-1) { //读取源文件属性 perror("fstat"); return -1; } printf("%s: inode=%ld,size=%ld,nlink=%ld\n",argv[1],buf.st_ino,buf.st_size,buf.st_nlink); if(unlink(argv[1])==-1) { perror("unlink"); return -1; } if(fstat(fd_c,&buf)==-1) { //读取源文件属性 perror("stat"); return -1; } printf("%s:new_nlink=%ld\n",argv[1],buf.st_nlink); close(fd_c); return 0; }
运行截图
题目五
编写程序完成以下功能:
-
新建/home/user目录;
-
把当前工作路径移至/home/user目录;
-
印当前工作路径;
#include<stdio.h> #include<dirent.h> #include<unistd.h> #include<sys/stat.h> int main(int argc,char *argv[]) { char buf[128]= {0}; if(mkdir(argv[1],0777)==-1) { perror("mkdir"); return -1; } chdir(argv[1]); if(getcwd(buf,128)==NULL) { //获取当前路径 perror("getcwd"); return -1; } printf("%s\n",buf); return 0; }
运行截图
题目六
编写程序完成以下功能:
-
递归遍历/home目录,打印出所有文件和子目录名称及节点号。
-
判断文件类型,如果是子目录,继续进行递归遍历,直到遍历完所有子目录为止.
#include <stdio.h> #include<stdlib.h> #include<unistd.h> #include<dirent.h> #include<sys/types.h> unsigned long visit_dirs = 0; unsigned long visit_files = 0; int getdir(char * pathname){ DIR* path=NULL; path=opendir(pathname); if(path==NULL){ perror("failed"); exit(1); } struct dirent* ptr; //目录结构体---属性:目录类型 d_type, 目录名称d_name char buf[1024]={0}; while((ptr=readdir(path))!=NULL){ if(strcmp(ptr->d_name,".")==0||strcmp(ptr->d_name,"..")==0){ continue; } //如果是目录 if(ptr->d_type==DT_DIR){ sprintf(buf,"%s/%s",pathname,ptr->d_name); printf("目录:%s\n",buf); visit_dirs++; getdir(buf); } if(ptr->d_type==DT_REG){ sprintf(buf,"%s/%s",pathname,ptr->d_name);//把pathname和文件名拼接后放进缓冲字符数组 printf("文件:%s\n",buf); visit_files++; } } return 0; } int main(int argc, char* argv[]) { if(argc == 2) { getdir(argv[1]); printf("总目录数: %ld, 总文件数: %ld\n", visit_dirs, visit_files); } else { printf("请输入: 查询的目录\n"); return; } return 0; }
运行截图