




已阅读5页,还剩32页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
实验八 文件管理实践【实验目的】配合操作系统课程的学习,加深对文件管理的理解。【实验学时】建议2学时【实验内容】1.掌握linux中文件的基本操作,了解带缓存与不带缓存文件IO函数,进行简单的文件IO程序编写。2.生成基本的引导程序,加载入内存执行(选做)3.生成简单的操作系统内核,加载入内存执行(选做)【实验原理】一、 基本文件操作(1)查看文件(可以是二进制的)内容 cat执行格式:cat filename或more filename 或cat filename|more例: cat file1 以连续显示方式,查看文件file1的内容more file1 或 cat file1|more 以分页方式查看文件的内容(2)删除文件 rm执行格式: rm filename 例: rm file? rm f* (3)复制文件 cp 执行格式: cp -r source destination 例: cp file1 file2 将file1复制成file2 cp file1 dir1 将file1复制到目录dir1 cp /tmp/file1 将file1复制到当前目录 cp /tmp/file1 file2 将file1 复制到当前目录名为file2cp r dir1 dir2 (recursive copy)复制整个目录。 (4)移动或更改文件、目录名称mv执行格式: mv source destination例: mv file1 file2 将文件file1,更名为file2 mv file1 dir1 将文件file1,移到目录dir1下mv dir1 dir2 (5)比较文件(可以是二进制的)或目录的内容 diff 执行格式: diff -r name1 name2 (name1、name2同为文件或目录) 例: diff file1 file2 比较file1与file2的不同处 diff -r dir1 dir2 比较dir1与dir2的不同处(6)文件属性的设置 chmod & umask改变文件或目录的读、写、执行的允许权执行格式: chmod -R mode name其中:-R为递归处理,将指定目录下所有文件及子目录一并处理 mode为3-8位数字,是文件/目录读、写、执行允许权的缩写(r:read,数字代号为4 w:write,数字代号为2 x:execute,数字代号为1)mode: rwx rwx rwx user group other缩写: (u) (g) (o)例:chmod 755 dir1 将目录dir1设定成任何人皆有读取及执行的权利,但只有拥有者可作写修改。其中7=4+2+1,5=4+1 chmod 700 file1 将file1设为拥有者可以读、写和执行 chmod o+x file2 将file2,增加拥有者可执行的权利 chmod g+x file3 将file3,增加组使用者可执行的权利 chmod o-r file4 将file4,除去其它使用者可读取的权利umask命令 设定文件创建时的缺省模式,对应每一类用户(文件属主、同组用户、其他用户)存在一个相应的umask值中的数字。对于文件来说,这一数字的最大值分别是6。系统不允许在创建一个文本文件时就赋予它执行权限,必须在创建后用chmod命令增加这一权限。目录则允许设置执行权限,这样针对目录来说,umask中各个数字最大可以到7。执行格式: umask nnn用umask命令查看umask值022此时建立的文件默认权限是644(6-0,6-2,6-2),建立的目录的默认权限是755(7-0,7-2,7-2),二、 不带缓存的文件IO操作和带缓存的文件IO操作Linux系统中,基于文件描述符的文件操作主要有:不带缓存的文件I/O操作和带缓存的文件流I/O操作。(1)不带缓存的文件I/O操作,又称系统调用I/O操作,符合POSIX标准,设计的程序能在兼容POSIX标准的系统间方便地移植。 指在用户层无缓存!在内核层仍然用缓存!要写入数据到文件上时(就是写入磁盘上),内核先将数据写入到内核中所设的缓冲储存器,假如这个缓冲储存器的长度是100个字节,调用系统函数 :ssize_t write (int fd,const void * buf,size_t count);写操作时,设每次写入长度count=10个字节,那么要调用10次这个函数才能把这个缓冲区写满,此时数据还是在缓冲区,并没有写入到磁盘,缓冲区满时才进行实际上的IO操作,把数据写入到磁盘上。无缓存IO操作数据流向路径:数据内核缓存区磁盘不带缓存的文件I/O操作用到的主要函数有:int open(const char *path, int access,int mode) path 要打开的文件路径和名称 access 访问模式,宏定义和含义如下: O_RDONLY 1 只读打开 O_WRONLY 2 只写打开 O_RDWR 4 读写打开 还可选择以下模式与以上3种基本模式相与: O_CREAT 0x0100 创建一个文件并打开 O_TRUNC 0x0200 打开一个已存在的文件并将文件长度设置为0,其他属性保持 O_EXCL 0x0400 未使用 O_APPEND 0x0800 追加打开文件 O_TEXT 0x4000 打开文本文件翻译CR-LF控制字符 O_BINARY 0x8000 打开二进制字符,不作CR-LF翻译 mode 该参数仅在access=O_CREAT方式下使用,其取值如下: S_IFMT 0xF000 文件类型掩码 S_IFDIR 0x4000 目录 S_IFIFO 0x1000 FIFO 专用 S_IFCHR 0x2000 字符专用 S_IFBLK 0x3000 块专用 S_IFREG 0x8000 只为0x0000 S_IREAD 0x0100 可读 S_IWRITE 0x0080 可写 S_IEXEC 0x0040 可执行(2)带缓存IO操作数据流向路径:数据流缓存区内核缓存区磁盘带缓存IO也叫标准IO,符合ANSI C 的标准IO处理,不依赖系统内核,所以移植性强,我们使用标准IO操作很多时候是为了减少对read()和write()的系统调用次数,带缓存IO其实就是在用户层再建立一个缓存区,这个缓存区的分配和优化长度等细节都是标准IO库处理好了,不用去操心,还是用上面那个例子说明这个操作过程: 要写数据到文件上,内核缓存(注意这个不是用户层缓存区)区长度是100字节,如果调用不带缓存的IO函数write()就要调用10次,这样系统效率低,现在在用户层建立另一个缓存区(用户层缓存区或者叫流缓存),假设流缓存的长度是50字节,我们用标准C库函数的fwrite()将数据写入到这个流缓存区里面,流缓存区满50字节后在进入内核缓存区,此时再调用系统函数write()将数据写入到文件(实质是磁盘)上,总之,标准IO操作fwrite()最后还是要调用无缓存IO操作write,这里进行了两次调用fwrite()写100字节也就是进行两次系统调用write()带缓存的文件I/O操作用到的主要函数有: FILE *fopen(char *filename, char *mode) filename 文件名称 mode 打开模式: r :文件必须已经存在,为读而打开。 r+:文件必须已经存在,为读和写而打开。 w:创建文件或为写打开文件,如果文件存在则会清空原文件内容。 w+: 创建文件或为读和写而打开文件,如果文件存在则会清空原文件内容。 a:追加,即在文件尾加入内容,或为写而创建文件。 a+:在文件尾写内容,或者为读和写而创建文件。 另外,以二进制方式打开文件时,在mode中同时加上b,如 rb,r+b,rb+,w+b,ab+等,则以二进制方式进行读写,如果不加b,则以文本方式打开文件。而UNIX环境不区分文本和二进制方式,所以在UNIX下加b并无作用。 int fclose(FILE *fp); fclose 函数关闭一个流,其调用内核 close 关闭流对应的文件描述符。如果此时I/O缓冲区还有数据,则调用内核 write 写到到文件中,再调用 close,然后释放FILET 缓冲区。当进程终止而没有显示调用fclose时,所有未写入的缓冲区的数据将会被写入,并关闭所有打开的流。【实验要求和步骤】掌握linux下文件的基本操作命令。了解带缓存文件和不带缓存文件的创建,打开,关闭,读写操作,进一步掌握实验七中使用字符设备的c文件。生成简单操作系统内核,加载入虚拟机执行。1. 新建一个文件夹a,并在文件夹里新建一个文件fa,新建另一个文件夹b,将文件fa复制到文件夹b中。2. 设计一个程序,要求以可读写方式打开一个文件,如果该文件不存在,则创建此文件,如果存在,将文件清空后关闭。 输入以下代码:#include #include #include /*以读写方式打开当前目录下的lilan文件,如果不存在则创建该文件,并且将文件权限设置为拥有者可读,可写,可执行*/int main(void)int fd;fd = open(lilan, O_CREAT|O_RDWR|O_TRUNC, 0700); /*选项O_TRUNC表示文件存在时清空 选项O_RDWR表示以读写方式打开 选项O_CREAT表示如果文件不存在则新建文件*/if (fd = -1 )perror( fail to open );exit(1);elseprintf(打开(创建)文件,文件描述符为:%dn,fd);close(fd);return 0;3. 写代码将步骤2所创建的文件复制成新文件,使用read函数从源文件读取数据,再用write函数写入到目标文件。输入以下代码:#include #include #include #include #include #include int main(void)int fdsrc=0,fddes=0,nbytes=0;int flags=O_CREAT | O_TRUNC | O_WRONLY;int z;char buf20, des20;printf(请输入目标文件名:); /*提示输入目标文件名*/scanf(%s,des); /*读入目标文件名*/fdsrc=open(lilan,O_RDONLY);/*只读方式打开源文件*/if (fdsrc = -1 )perror( fail to open );exit(1);fddes=open(des,flags,0644); /*打开目标文件的权限为:644*/if (fddes = -1 )perror( fail to open );exit(1);while(nbytes=read(fdsrc,buf,20)0)z=write(fddes,buf,nbytes);if(z0)perror(写目标文件出错);/*此函数可以用来输出“错误原因信息”字符串*/close(fddes);close(fdsrc);printf(复制文件为%s文件成功!n,des);exit(0);改写上面的程序,源文件名和目标文件名都由键盘输入。4. 设计程序,把键盘上输入的字符串以带缓存的方式写入文件“liufile”, 如果该文件不存在,则创建此文件。 输入以下代码:#include#include int main(void)FILE * fp; /*定义文件变量指针*/char s80;if(fp=fopen(liufile,a+)=NULL) /*打开(创建)文件*/printf(打开(创建)文件出错); /*出错处理*/exit(0);printf(请输入要写入文件的字符串:); /*提示输入一个字符*/fputs(fgets(s,80,stdin),fp);/*把键盘输入的字符串写入文件*/fclose(fp); /*关闭文件流*/改写上面的程序,用带缓存的流文件I/O操作,把键盘上输入的字符串写入一个文件x, 如果该文件不存在,则创建此文件,多次运行程序多次输入字符串后,文件x中只保存最后一次输入的字符串,把文件x中的内容读取出来,在终端中打印输出。5. 有两个程序,一个写入程序把三个人的姓名和帐号余额信息,通过一次流文件I/O操作写入文件y,另一个读取程序则格式输出帐号信息,把每个人的帐号和余额一一对应显示输出。改写下面的程序,从键盘输入账号和余额。/*写入程序:把帐号信息写入文件*/ #include #include #define set_s(x,y,z) strcpy(,y);sx.pay=z; /*自定义宏,用于赋值*/#define nmemb 3struct test /*定义结构体*/char name20;int pay;snmemb;int main()FILE * fp; /*定义文件变量指针*/set_s(0,张三,12345);set_s(1,李四,200);set_s(2,王五,50000);fp=fopen(zhfile,a+);/*打开(创建)文件*/fwrite(s,sizeof(struct test),nmemb,fp);/*调用fwite函数把块信息写入文件*/fclose(fp);return 0; /*关闭文件流*/*读出程序,将账号信息读出*/#include#define nmemb 3struct test/*定义结构体*/char name20;int pay;snmemb;int main( )FILE * fp; /*定义文件变量指针*/int i;fp = fopen(zhfile, r);/*打开文件*/fread(s,sizeof(struct test),nmemb,fp);/*调用fread函数从文件读取块信息*/fclose(fp); /*关闭文件流*/for(i=0;inmemb;i+)printf(帐号%d:%-20s余额%d:%dn,i,,i,si.pay);return 0;6. (选做)将如下程序放在同一目录(注意文件名),输入make,编译成boot.img文件,挂载到虚拟机.这是你的第一个操作系统程序。从本质上来说它是一个引导程序。/*boot.S*/.code16.text mov %cs,%ax mov %ax,%ds mov %ax,%es call DispStr jmp .DispStr: mov $BootMessage, %ax mov %ax,%bp mov $16,%cx mov $0x1301,%ax mov $0x00c,%bx mov $0,%dl int $0x10 retBootMessage:.ascii Hello, OS world! Lilan 510.word 0xaa55#MakefileCC=gccLD=ldLDFILE=solrex_x86.ldOBJCOPY=objcopyall: boot.imgboot.img: boot.bindd if=boot.bin of=boot.img bs=512 count=1dd if=/dev/zero of=boot.img skip=1 seek=1 bs=512 count=2879boot.bin: boot.elf$(OBJCOPY) -R .pdr -R .comment -R.note -S -O binary boot.elf boot.binboot.elf: boot.o$(LD) boot.o -o boot.elf -e c -Tsolrex_x86.ldboot.o: boot.S$(CC) -c boot.S copy: boot.imgclean: rm -f boot.o boot.elf boot.bindistclean: cleanrm -f boot.imgrelease: cleanmv boot.img solrex.img/*solrex_x86.ld*/SECTIONS . = 0x7c00; .text : _ftext = .; /* Program will be loaded to 0x7c00. */ = 0 在同一目录下建立如下文件:/*loader.S内核程序*/.code16.textmov$0xb800,%axmov %ax,%gsmov$0xf,%ahmov$L,%almov%ax,%gs:(80*0+39)*2)jmp./*Makefile*/CC=gccLD=ldOBJCOPY=objcopyCFLAGS=-cTRIM_FLAGS=-R .pdr -R .comment -R.note -S -O binaryLDFILE_BOOT=solrex_x86_boot.ldLDFILE_DOS=solrex_x86_dos.ldLDFLAGS_BOOT=-T$(LDFILE_BOOT)LDFLAGS_DOS=-T$(LDFILE_DOS)all: boot.img LOADER.BINecho #echo # Compiling work finished, now you can use sudo make copy toecho # copy LOADER.BIN into boot.imgecho #boot.bin: boot.S$(CC) $(CFLAGS) boot.S$(LD) boot.o -o boot.elf $(LDFLAGS_BOOT)$(OBJCOPY) $(TRIM_FLAGS) boot.elf $LOADER.BIN: loader.S$(CC) $(CFLAGS) loader.S$(LD) loader.o -o loader.elf $(LDFLAGS_DOS)$(OBJCOPY) $(TRIM_FLAGS) loader.elf $boot.img: boot.bindd if=boot.bin of=boot.img bs=512 count=1dd if=/dev/zero of=boot.img skip=1 seek=1 bs=512 count=2879# You must have the authority to do mount, or you must use su root or# sudo command to do make copycopy: boot.img LOADER.BINmkdir -p /tmp/floppy;mount -o loop boot.img /tmp/floppy/ -o fat=12;cp LOADER.BIN /tmp/floppy/;umount /tmp/floppy/;rm -rf /tmp/floppy/;clean: rm -f *.o *.elf *.bin *.BINdistclean: cleanrm -f boot.imgrelease: cleanmv boot.img solrex.img=/*solrex_x86_boot.ld*/SECTIONS . = 0x7c00; .text : _ftext = .; = 0=/*solrex_x86_dos.ld*/SECTIONS . = 0x0100; .text : _ftext = .; = 0=/*boot.S*/.code16.set BaseOfStack, 0x7c00 /* Stack base address, inner */.set BaseOfLoader, 0x9000 /* Section loading address of LOADER.BIN */.set OffsetOfLoader, 0x0100 /* Loading offset of LOADER.BIN */.set RootDirSectors, 14 /* Root directory sector count */.set SecNoOfRootDir, 19 /* 1st sector of root directory */.set SecNoOfFAT1, 1 /* 1st sector of FAT1 */.set DeltaSecNo, 17 /* BPB_(RsvdSecCnt+NumFATs*FATSz) -2 */* Start sector of file space =*/.text/* Floppy header of FAT12 */ jmp LABEL_START /* Start to boot. */ nop /* nop required */BS_OEMName: .ascii WB. YANG /* OEM String, 8 bytes required */BPB_BytsPerSec: .2byte 512 /* Bytes per sector */BPB_SecPerCluster: .byte 1 /* Sector per cluster */BPB_ResvdSecCnt: .2byte 1 /* Reserved sector count */BPB_NumFATs: .byte 2 /* Number of FATs */BPB_RootEntCnt: .2byte 224 /* Root entries count */BPB_TotSec16: .2byte 2880 /* Total sector number */BPB_Media: .byte 0xf0 /* Media descriptor */BPB_FATSz16: .2byte 9 /* FAT size(sectors) */BPB_SecPerTrk: .2byte 18 /* Sector per track */BPB_NumHeads: .2byte 2 /* Number of magnetic heads */BPB_HiddSec: .4byte 0 /* Number of hidden sectors */BPB_TotSec32: .4byte 0 /* If TotSec16 equal 0, this works */BS_DrvNum: .byte 0 /* Driver number of interrupt 13 */BS_Reserved1: .byte 0 /* Reserved */BS_BootSig: .byte 0x29 /* Boot signal */BS_VolID: .4byte 0 /* Volume ID */BS_VolLab: .ascii Solrex 0.01 /* Volume label, 11 bytes required */BS_FileSysType: .ascii FAT12 /* File system type, 8 bytes required */* Initial registers. */LABEL_START: mov %cs,%ax mov %ax,%ds mov %ax,%es mov %ax,%ss mov $BaseOfStack, %sp /* Clear screen */ mov $0x0600,%ax /* %ah=6, %al=0 */ mov $0x0700,%bx /* Black white */ mov $0,%cx /* Top left: (0,0) */ mov $0x184f,%dx /* Bottom right: (80,50) */ int $0x10 /* BIOS int 10h, ah=6: Initialize screen */ /* Display Booting* */ mov $0,%dh call DispStr /* Display string(index 0)*/ /* Reset floppy */ xor %ah,%ah xor %dl,%dl /* %dl=0: floppy driver 0 */ int $0x13 /* BIOS int 13h, ah=0: Reset driver 0 */ /* Find LOADER.BIN in root directory of driver 0 */ movw $SecNoOfRootDir, (wSectorNo)/* Read root dir sector to memory */LABEL_SEARCH_IN_ROOT_DIR_BEGIN: cmpw $0,(wRootDirSizeForLoop) /* If searching in root dir */ jz LABEL_NO_LOADERBIN /* can find LOADER.BIN ? */ decw (wRootDirSizeForLoop) mov $BaseOfLoader,%ax mov %ax,%es /* %es - BaseOfLoader*/ mov $OffsetOfLoader,%bx /* %bx - OffsetOfLoader */ mov (wSectorNo),%ax /* %ax LOADER BIN */ mov $OffsetOfLoader,%di /* BaseOfLoader %al*/ cmp %es:(%di),%al jz LABEL_GO_ON jmp LABEL_DIFFERENT /* Different */LABEL_GO_ON: inc %di jmp LABEL_CMP_FILENAME /* Go on loop */LABEL_DIFFERENT: and $0xffe0,%di /* Go to head of this entry */ add $0x20,%di mov $LoaderFileName,%si /* Next entry */ jmp LABEL_SEARCH_FOR_LOADERBINLABEL_GOTO_NEXT_SECTOR_IN_ROOT_DIR: addw $1,(wSectorNo) jmp LABEL_SEARCH_IN_ROOT_DIR_BEGIN/* Not found LOADER.BIN in root dir. */LABEL_NO_LOADERBIN: mov $2,%dh call DispStr /* Display string(index 2) */ jmp . /* Infinite loop */* Found. */LABEL_FILENAME_FOUND: mov $RootDirSectors,%ax and $0xffe0,%di /* Start of current entry, 32 bytes per entry */ add $0x1a,%di /* First sector of this file */ mov %es:(%di),%cx push %cx /* Save index of this sector in FAT */ add %ax,%cx add $DeltaSecNo,%cx /* LOADER.BINs start sector saved in %cl */ mov $BaseOfLoader,%ax mov %ax,%es /* %es - BaseOfLoader */ mov $OffsetOfLoader,%bx /* %bx - OffsetOfLoader */ mov %cx,%ax /* %ax - Sector number */* Load LOADER.BINs sectors to memory. */LABEL_GOON_LOADING_FILE: push %ax push %bx mov $0x0e,%ah mov $.,%al /* Char to print */ mov $0x0f,%bl /* Front color: white */ int $0x10 /* BIOS int 10h, ah=0xe: Print char */ pop %bx pop %ax mov $1,%cl call ReadSector pop %ax /* Got index of this sector in FAT */ call GetFATEntry cmp $0x0fff,%ax jz LABEL_FILE_LOADED push %ax /* Save index of this sector in FAT */ mov $RootDirSectors,%dx add %dx,%ax add $DeltaSecNo,%ax add (BPB_BytsPerSec),%bx jmp LABEL_GOON_LOADING_FILELABEL_FILE_LOADED: mov $1,%dh call DispStr /* Display string(index 1) */* Jump to LOADER.BINs start address in memory.*/ jmp $BaseOfLoader,$OffsetOfLoader/*/* = Variable table*/wRootDirSizeForLoop: .2byte RootDirSectorswSectorNo:
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 电力生产质量培训
- 文化遗产保护项目2025年资金申请政策解读报告
- 高压安全技术操作考试题及答案
- 文化旅游产业与创意产业融合的2025年资金申请报告
- 工商银行2025绍兴市数据分析师笔试题及答案
- 邮储银行2025三沙市笔试英文行测高频题含答案
- 2025年3D打印技术的快速成型制造研究
- 邮储银行2025淮北市秋招群面案例总结模板
- 2025年3D打印技术的创新应用领域
- 建设银行2025来宾市秋招笔试英语题专练及答案
- 卡拉瓦乔课件
- 李东垣《脾胃论》【译文】
- 东方财富通的函数修订版
- 第17册中药成方制剂 卫生部颁药品标准
- 《医院员工激励问题研究11000字(论文)》
- 品管圈计划书(模板)
- GB/T 26559-2011机械式停车设备分类
- GB/T 2423.22-2012环境试验第2部分:试验方法试验N:温度变化
- 水土保持工程质量评定表
- 人像摄影:户外人像摄影课件
- 纸张消耗统计表
评论
0/150
提交评论