实验4 文件操作
- 格式:docx
- 大小:50.84 KB
- 文档页数:6
目录备注:实验考核要求及成绩评定本课程共有10个上机实验(16次),均为必做。
实验考核由出勤与纪律情况、实验任务完成情况、实验报告质量三个环节组成,成绩以百分计,满分 100 分。
各考核环节所占分值比例及考核要求如下。
每次实验按百分制单独评分,取各次成绩的平均值作为此环节的最终成绩并按比例计入课程总评成绩。
sy1_7.py 并保存至已建好的文件夹中。
4. 检查已输入的程序是否有错(包括输入时输错的和编程中的错误),如发现有错,及时改正。
5. 运行程序并分析运行结果是否合理。
在运行时要注意当输入不同的数据时所得结果是否正确,应测试两组以上数据,分别检查在不同情况下结果是否正确。
列出1-7题源程序清单并记录上机运行结果。
1.编写Python程序,进行摄氏度和华氏度之间的温度转换。
源程序:运行结果:2. 天天向上的力量计算。
一年365天,以第1天的能力值为基数,记为1.0,当好好学习时能力值相比前一天提高1‰,当没有学习时由于遗忘等原因能力值相比前一天下降1‰。
每天努力和每天放任,一年下来的能力值相差多少呢?源程序:运行结果:思考:如果好好学习时能力值相比前一天提高5‰,当放任时相比前一天下降5‰。
效果相差多少呢?源程序:运行结果:如果好好学习时能力值相比前一天提高1%,当放任时相比前一天下降1%。
效果相差多少呢?源程序:运行结果:3. 一年365天,一周5个工作日,如果每个工作日都很努力,可以提高1%,仅在周末放任一下,能力值每天下降1%,效果如何呢?源程序:运行结果:4. 每周工作5天,休息2天,休息日水平下降0.01,工作日要努力到什么程度一年后的水平才与每天努力1%所取得的效果一样呢?(选作)源程序:运行结果:5. 输入一个星期数字,返回对应星期名称。
源程序:运行结果:6. 利用print()函数实现简单的非刷新文本进度条及单行动态刷新文本进度条。
(1) 简单的非刷新文本进度条源程序:运行结果:(2) 单行动态刷新文本进度条源程序:运行结果:实验成绩评定表sy2_1.py-sy2_9.py并保存至已建好的文件夹中。
文件操作的实验报告1. 实验背景文件是计算机中存储数据的一种重要方式,在实际应用中,经常需要对文件进行读写与操作。
本实验旨在通过实际操作,掌握文件的打开、读写、复制和关闭等基本操作。
2. 实验内容本实验分为四个部分,分别是文件的打开、读写、复制和关闭操作。
2.1 文件的打开文件的打开是文件操作的第一步,通过打开文件可以获得对文件的访问权限。
在本实验中,我们使用Python语言进行文件操作。
下面是打开文件的示例代码:pythonfile = open("test.txt", "r")在上述代码中,"test.txt"是指要打开的文件名,"r"表示以只读方式打开文件。
如果需要以写入方式打开文件,可以使用"w"作为参数。
2.2 文件的读写文件的读写是文件操作的核心内容之一。
通过读取文件,可以获得文件中的内容;而通过写入文件,可以向文件中写入内容。
下面是读取文件内容和写入文件内容的示例代码:python读取文件内容content = file.read()写入文件内容file.write("Hello, World!")在上述代码中,`read()`函数用于从文件中读取所有内容,`write()`函数用于向文件中写入指定的内容。
2.3 文件的复制文件的复制是文件操作中常见的需求之一。
通过文件的复制,可以将一个文件的内容复制到另一个文件中。
下面是文件复制的示例代码:python打开源文件和目标文件source_file = open("source.txt", "r")target_file = open("target.txt", "w")读取源文件内容content = source_file.read()写入目标文件target_file.write(content)关闭文件source_file.close()target_file.close()在上述代码中,我们首先打开源文件和目标文件,然后读取源文件的内容并写入目标文件,最后关闭文件。
c语言实验心得体会在学习C语言的过程中,我参与了多个实验项目,通过实际操作和实验结果的分析,我对C语言的特点、应用和一些常见问题有了更深入的理解和体会。
以下是我对这些实验项目的心得体会:1. 实验项目一:基本语法和数据类型在这个实验中,我学习了C语言的基本语法和数据类型。
通过编写简单的程序,我掌握了变量的定义和使用、常量的使用、运算符的使用以及输入输出函数的应用。
我发现C语言的语法相对简洁明了,易于理解和学习。
同时,我也了解到不同的数据类型在内存中所占用的空间大小以及其取值范围的限制。
2. 实验项目二:控制语句和循环结构在这个实验中,我学习了C语言中的控制语句和循环结构。
通过编写程序,我掌握了条件语句(if-else语句、switch语句)和循环语句(for循环、while循环、do-while循环)的使用。
我发现控制语句和循环结构可以帮助我们实现程序的灵活控制和流程控制,提高程序的效率和可读性。
3. 实验项目三:数组和字符串在这个实验中,我学习了C语言中数组和字符串的使用。
通过编写程序,我掌握了数组的定义和初始化、数组元素的访问和修改、多维数组的使用以及字符串的输入输出和处理。
我发现数组和字符串在实际编程中非常常见,掌握了它们的使用可以提高程序的处理能力和效率。
4. 实验项目四:函数和指针在这个实验中,我学习了C语言中函数和指针的使用。
通过编写程序,我掌握了函数的定义和调用、函数的参数传递和返回值、递归函数的编写以及指针的定义和使用。
我发现函数和指针是C语言中非常重要的概念,掌握了它们可以提高程序的模块化和灵活性。
5. 实验项目五:文件操作在这个实验中,我学习了C语言中的文件操作。
通过编写程序,我掌握了文件的打开和关闭、文件的读写操作以及文件指针的使用。
我发现文件操作在实际应用中非常常见,掌握了文件操作可以实现程序与外部文件的数据交互,提高程序的扩展性和灵活性。
通过这些实验项目,我不仅学会了C语言的基本语法和常用功能,还培养了自己的编程思维和解决问题的能力。
文件管理实验报告一、实验目的文件管理是操作系统的重要组成部分,本次实验的目的在于深入理解文件管理的基本概念和原理,掌握文件的存储、组织、检索和访问等操作,熟悉常见的文件系统结构和功能,提高对文件管理系统的实际操作能力和问题解决能力。
二、实验环境1、操作系统:Windows 102、开发工具:Microsoft Visual Studio 2019三、实验内容1、文件的创建、删除和重命名使用 C++或 Python 编程语言,通过系统调用或相关库函数实现文件的创建、删除和重命名操作。
观察文件在操作系统中的实际表现,如文件的出现和消失,文件名的更改等。
2、文件的读写操作实现对文本文件和二进制文件的读写操作,包括读取文件的全部内容、按行读取文件、向文件写入数据等。
分析不同读写模式(如只读、只写、读写等)对文件操作的影响。
3、文件属性的获取和修改获取文件的基本属性,如文件大小、创建时间、修改时间、访问权限等。
尝试修改文件的部分属性,如只读属性、隐藏属性等,观察修改后的效果。
4、文件目录的操作创建、删除和遍历目录。
实现文件在不同目录之间的移动和复制操作。
四、实验步骤1、文件的创建、删除和重命名以下是使用 Python 实现文件创建、删除和重命名的示例代码:```pythonimport os创建文件file_path ="exampletxt"with open(file_path, 'w') as f:fwrite("This is a test file")删除文件osremove(file_path)重命名文件new_file_path ="renamed_exampletxt"osrename(file_path, new_file_path)```运行代码后,可以在指定的目录中观察到文件的创建、删除和重命名操作的结果。
2、文件的读写操作读取文本文件的示例代码:```pythonfile_path ="text_filetxt"with open(file_path, 'r') as f:content = fread()print(content)```按行读取文本文件的示例代码:```pythonfile_path ="text_filetxt"with open(file_path, 'r') as f:for line in f:print(linestrip())```写入数据到文件的示例代码:```pythonfile_path ="outputtxt"with open(file_path, 'w') as f:fwrite("New data written to file")```分别运行上述代码,观察文件的读写结果。
删除临时文件学生姓名: 李亚军专业班级: 卓越计科 121 班1.实验目的通过编写文件读写及上锁的程序, 进一步熟悉 Linux 中文件 I/O 相关的应用开发, 并 且熟练掌握open() 、read() 、 write() 、fcntl() 等函数的使用。
2.实验内容在 Linux 中 FIFO 是一种进程之间的管道通信机制。
Linux 支持完整的 FIFO 通信 机制。
本实验内容,通过使用文件操作,仿真 FIFO (先进先出)结构以及生产者 - 消费者运行模型。
本实验中需要打开两个虚拟终端,分别运行生产者程序( producer )和消费者程序 (customer )。
此时两个进程同时对同一个文件进行读写操作。
因为这个文件是临界资源, 所以可以使用文件锁机制来保证两个进程对文件的访问都是原子操作。
先启动生产者进程,它负责创建仿真 FIFO 结构的文件(其实是一个普通文件)并投 入生产,就是按照给定的时间间隔,向 FIFO 文件写入自动生成的字符(在程序中用宏定 义选择使用数字还是使用英文字符),生产周期以及要生产的资源数通过参数传递给进程 (默认生产周期为 1s ,要生产的资源数为 10 个字符)。
后启动的消费者进程按照给定的数目进行消费,首先从文件中读取相应数目的字符 并在屏幕上显示, 然后从文件中删除刚才消费过的数据。
为了仿真 FIFO 结构, 此时需要 使用两次复制来实现文件内容的偏移。
每次消费的资源数通过参数传递给进程,默认值 为 10 个字符。
3.实验步骤(1)实验流程图 本实验的两个程序的流程图如图:开始开始( producer )(customer)生产一个资源 是上锁上锁将剩下的数据拷贝到 临时文件 tmp 中用临时文件 tmp 覆盖原数据文件,这样 模拟 FIFO 结构 解锁解锁生产完了吗图 节流程图创建 FIFO 结构文件消费资源 打印字符)学 号: 96消费够了吗等待一秒 将“生产”的字符 写入到 FIFO结构文件结束结束2)代码头部文件代码:struct myflock{short l_type; /* 文件锁类型:F_RDLOCK读取锁;F_WRLC写入锁;F_UNLCK解锁*/off_t l_start; /* 相对位移量*/相对位移量的起点SEEK_SET;SEEK_CUR; SEEK_END: */short l_whence; /*off_t l_len; /* 加锁区域长度*/pid_t l_pid; /* */} ;/* lock_set */int lock_set(int fd, int type){struct myflock old_lock, lock;= SEEK_SET;= 0;= 0;= type;= -1;/* 判断文件是否可以上锁*/fcntl(fd, F_GETLK, &lock);if != F_UNLCK){/* 判断文件不能上锁的原因*/if == F_RDLCK) /* 该文件已有读取锁*/{printf("Read lock already set by %d\n", ;}else if == F_WRLCK) /* 该文件已有写入锁*/{printf("Write lock already set by %d\n", ;/* l_type 可能已被F_GETLK修改过*/= type;/* 根据不同的type 值进行阻塞式上锁或解锁*/if ((fcntl(fd, F_SETLKW, &lock)) < 0){printf("Lock failed:type = %d\n", ; return 1;}switch{case F_RDLCK: printf("Read lock set by %d\n", getpid());break;case F_WRLCK: printf("Write lock set by %d\n", getpid());break;case F_UNLCK: printf("Release lock by %d\n", getpid()); return 1;break;default:break;} /* end of switch */return 0;}生产者程序的源代码:/* */#include <>#include <>#include <>#include <>#include <>#include ""#define MAXLEN 10 /* 缓冲区大小最大值*/#define ALPHABET 1 /* 表示使用英文字符*/#define ALPHABET_START 'a' #define COUNT_OF_ALPHABET #define DIGIT 2 /* #defineDIGIT_START '0' #defineCOUNT_OF_DIGIT 10/* 头一个字符,可以用 'A'*/ 26 /*字母字符的个数 */ 表示使用数字字符 *//* 头一个数字字符 *//* 数字字符的个数 */ 本实例用英文字符 */ /* !" FIFO 文件名 *//* 函数 product() 产生一个字符并写入仿真 FIFO 文件中 */ int roduct(void){int fd;unsigned int sign_type, sign_start, sign_count, size; static unsigned int counter = 0; /* 打开 !" FIFO 文件 */if ((fd = open(fifo_file, O_CREAT|O_RDWR|O_APPEND, 0644)) < 0) {printf("Open fifo file error\n"); exit(1); }sign_type = SIGN_TYPE; switch(sign_type) {case ALPHABET: /* 英文字符 */{sign_start = ALPHABET_START; sign_count = COUNT_OF_ALPHABET; } break;case DIGIT: /* 数字字符 */{sign_start = DIGIT_START; sign_count = COUNT_OF_DIGIT; }#define SIGN_TYPE ALPHABET /*const char *fifo_file = "./myfifo"; char buff[MAXLEN]; /* 缓冲区 */break;default:{return -1;}} /*end of switch*/sprintf(buff, "%c", (sign_start + counter)); counter = (counter + 1) % sign_count; lock_set(fd, F_WRLCK); /* 上写锁*/if ((size = write(fd, buff, strlen(buff))) < 0){printf("Producer: write error\n"); return -1;}lock_set(fd, F_UNLCK); /* 解锁*/close(fd);return 0;}int main(int argc ,char *argv[]){int time_step = 1; /* 生产周期*/int time_life = 10; /* 需要生产的资源数*/if (argc > 1){/* 第一个参数表示生产周期*/sscanf(argv[1], "%d", &time_step);}if (argc > 2){/* 第二个参数表示需要生产的资源数*/sscanf(argv[2], "%d", &time_life);}while (time_life--){if (product() < 0){break;}sleep(time_step);}exit(EXIT_SUCCESS);}消费者程序的源代码:/* */#include <> #include <> #include <> #include <> #include <> #include "" #define MAX_FILE_SIZE 100 * 1024 * 1024 /* 100M*/const char *fifo_file = "./myfifo"; /* 仿真FIFO 文件名*/const char *tmp_file = "./tmp"; /* 临时文件名*//* 资源消费函数customing */int customing(const char *myfifo, int need){int fd;char buff;int counter = 0;if ((fd = open(myfifo, O_RDONLY)) < 0){printf("Function customing error\n");return -1;printf("Enjoy:");lseek(fd, SEEK_SET, 0);while (counter < need){while ((read(fd, &buff, 1) == 1) && (counter < need)){fputc(buff, stdout); /* -. 就是在屏幕上/0 的显示*/counter++;}}fputs("\n", stdout); close(fd);return 0;}/* myfilecopy() 函数: 实现从sour_file 文件的offset 偏移处开始将count 个字节数据复制到dest_file 文件*/int myfilecopy(const char *sour_file,const char *dest_file, int offset, int count, int copy_mode){int in_file, out_file;int counter = 0;char buff_unit;if ((in_file = open(sour_file, O_RDONLY|O_NONBLOCK)) < 0){printf("Function myfilecopy error in source file\n"); return -1;}if ((out_file = open(dest_file, O_CREAT|O_RDWR|O_TRUNC|O_NONBLOCK, 0644)) < 0){printf("Function myfilecopy error in destination file:"); return -1;}lseek(in_file, offset, SEEK_SET);while ((read(in_file, &buff_unit, 1) == 1) && (counter < count)){write(out_file, &buff_unit, 1); counter++; } close(in_file); close(out_file);return 0;}/* custom() 函数:实现FIFO 消费者*/int custom(int need){int fd;/* 对资源进行消费,need 表示该消费的资源数目*/ customing(fifo_file, need);if ((fd = open(fifo_file, O_RDWR)) < 0){printf("Function myfilecopy error in source_file:");return -1;}/* 为了模拟FIFO 结构,对整个文件进平行行移动*/ lock_set(fd, F_WRLCK);myfilecopy(fifo_file, tmp_file, need, MAX_FILE_SIZE, 0); myfilecopy(tmp_file, fifo_file, 0, MAX_FILE_SIZE, 0); lock_set(fd, F_UNLCK);unlink(tmp_file);close(fd);return 0;}int main(int argc ,char *argv[])int customer_capacity = 10;if (argc > 1) /* 第一个参数指定需要消费的资源数目,默认值为10 */{sscanf(argv[1], "%d", &customer_capacity);}{if (customer_capacity > 0){custom(customer_capacity);}exit(EXIT_SUCCESS);}(3) 分别编译生产者程序和消费者程序(4) 确保编译没有错误后,先在控制台终端1 上运行生产者程序:./producer 1 20再在控制台终端2 上运行消费者程序:./customer 54. 完成实验报告( 1)将实验过程和实验结果截图( 2)认真阅读程序代码,参考代码并根据实验结果,完成实验总结。
一、实验目的1. 熟悉高级语言程序设计的基本概念和编程环境。
2. 掌握程序设计的基本方法和技巧。
3. 提高逻辑思维和问题解决能力。
4. 学会使用高级语言编写简单的程序。
二、实验内容本次实验选用的高级语言为Python,主要内容包括:1. 变量和数据类型2. 控制结构3. 函数4. 文件操作5. 异常处理三、实验步骤1. 环境搭建(1)下载并安装Python环境。
(2)配置Python环境变量。
(3)验证Python环境是否搭建成功。
2. 编写程序(1)创建一个Python文件(例如:test.py)。
(2)编写以下代码,实现一个简单的计算器功能。
```python# 定义加法函数def add(x, y):return x + y# 定义减法函数def subtract(x, y):return x - y# 定义乘法函数def multiply(x, y):return x y# 定义除法函数def divide(x, y):if y == 0:return "Error: Division by zero"else:return x / y# 主函数def main():while True:print("请输入操作符(+、-、、/)或输入'q'退出:") operator = input()if operator == 'q':breakprint("请输入第一个数:")num1 = float(input())print("请输入第二个数:")num2 = float(input())if operator == '+':print("结果是:", add(num1, num2))elif operator == '-':print("结果是:", subtract(num1, num2)) elif operator == '':print("结果是:", multiply(num1, num2)) elif operator == '/':print("结果是:", divide(num1, num2))else:print("Error: Invalid operator")# 调用主函数if __name__ == "__main__":main()```3. 运行程序(1)打开命令行窗口,切换到Python文件所在的目录。
一、实验目的1. 理解文件管理的概念和基本原理。
2. 掌握文件系统的结构及其组成。
3. 学会使用文件管理系统进行文件操作。
4. 了解文件系统的性能优化方法。
二、实验环境1. 操作系统:Windows 102. 文件管理系统:Windows Explorer3. 实验工具:文本编辑器(如Notepad)三、实验内容1. 文件系统的基本概念2. 文件系统的结构3. 文件操作4. 文件系统性能优化四、实验步骤1. 文件系统的基本概念(1)打开Windows Explorer,观察文件系统的组织结构。
(2)分析文件系统的组成,包括文件、目录、驱动器等。
(3)了解文件名、扩展名、路径等基本概念。
2. 文件系统的结构(1)创建一个新文件夹,命名为“实验文件夹”。
(2)在“实验文件夹”中创建一个文本文件,命名为“实验报告.txt”。
(3)观察文件系统的树状结构,理解目录与文件之间的关系。
3. 文件操作(1)打开“实验报告.txt”,使用文本编辑器进行编辑。
(2)保存并关闭编辑器。
(3)将“实验报告.txt”复制到“实验文件夹”的子目录中。
(4)删除“实验文件夹”中的“实验报告.txt”。
(5)重命名“实验文件夹”中的子目录。
4. 文件系统性能优化(1)查看磁盘属性,了解磁盘空间占用情况。
(2)对磁盘进行碎片整理。
(3)使用磁盘清理工具清理磁盘中的临时文件。
五、实验结果与分析1. 文件系统的基本概念通过实验,我们了解了文件系统的基本概念,包括文件、目录、驱动器等。
文件系统是操作系统管理文件的一种数据结构,用于存储、检索、更新和删除文件。
2. 文件系统的结构实验中,我们创建了文件夹和文件,并观察了文件系统的树状结构。
文件系统采用分层结构,目录与文件之间通过路径连接。
3. 文件操作实验中,我们进行了文件操作,包括创建、编辑、复制、删除和重命名。
这些操作是文件管理的基本技能。
4. 文件系统性能优化通过磁盘碎片整理和清理磁盘中的临时文件,我们提高了文件系统的性能。
第1篇一、实验目的通过本次在线编程实验,旨在提高我的编程能力,加深对编程语言的理解,熟悉编程环境的使用,并培养良好的编程习惯。
同时,通过实际编程练习,解决实际问题,提升我的逻辑思维和问题解决能力。
二、实验内容本次实验选择了电大在线编程平台提供的C语言编程课程,主要包括以下内容:1. C语言基本语法;2. 数据类型、变量和运算符;3. 控制结构(分支和循环);4. 函数的定义和调用;5. 数组、指针和字符串操作;6. 文件操作。
三、实验步骤1. 准备工作:登录电大在线编程平台,选择C语言编程课程,熟悉编程环境和操作界面。
2. 编写代码:根据实验指导书,逐个完成实验任务,编写相应的C语言程序。
3. 调试程序:使用调试工具,检查代码中的错误,修正语法错误和逻辑错误。
4. 运行程序:成功编译并运行程序,观察输出结果,确保程序功能符合预期。
5. 总结与反思:对实验过程中遇到的问题进行总结,分析原因,提出改进措施。
四、实验结果与分析1. C语言基本语法:通过实验,我掌握了C语言的基本语法,包括数据类型、变量、运算符等。
2. 控制结构:实验中,我学会了使用if语句、switch语句进行分支控制,以及for循环、while循环进行循环控制。
3. 函数:通过编写和调用函数,我了解了函数的定义、参数传递和返回值等概念。
4. 数组、指针和字符串操作:实验中,我掌握了数组的定义、初始化、访问和操作方法,了解了指针的概念和用法,以及字符串操作函数。
5. 文件操作:通过实验,我学会了使用文件操作函数,实现文件的读写操作。
五、实验总结通过本次在线编程实验,我收获颇丰。
以下是我对本次实验的总结:1. 编程能力得到提高:通过实际编程练习,我对C语言有了更深入的了解,编程能力得到提升。
2. 问题解决能力增强:在实验过程中,我遇到了各种问题,通过查阅资料、请教同学和老师,我学会了如何分析和解决实际问题。
3. 良好的编程习惯:在实验过程中,我养成了良好的编程习惯,如规范命名、注释代码、代码复用等。
第1篇一、实验目的1. 熟悉文件的基本操作,包括创建、打开、保存、关闭等。
2. 掌握文件的编辑、格式设置、排版等基本技能。
3. 学习使用文件进行数据管理和信息整理。
4. 提高实际操作能力,为以后的工作和学习打下基础。
二、实验环境1. 操作系统:Windows 102. 文字处理软件:Microsoft Word 20163. 硬件设备:电脑、显示器、鼠标、键盘等三、实验内容1. 文件的基本操作2. 文本的编辑和格式设置3. 文档的排版和打印4. 文件夹的管理四、实验步骤1. 文件的基本操作(1)创建新文件:打开Microsoft Word,点击“空白文档”或选择合适的模板创建新文件。
(2)打开文件:点击“文件”菜单,选择“打开”,在弹出的对话框中选择要打开的文件。
(3)保存文件:点击“文件”菜单,选择“保存”,在弹出的对话框中设置文件名、保存路径和文件格式,然后点击“保存”。
(4)关闭文件:点击“文件”菜单,选择“关闭”,或者直接点击窗口右上角的关闭按钮。
2. 文本的编辑和格式设置(1)输入文本:将光标定位在文档中,使用键盘输入文本内容。
(2)选择文本:将鼠标指针移动到文本的开始位置,按住鼠标左键拖动至文本的结束位置,即可选中文本。
(3)设置字体:选中文本,点击“开始”选项卡中的“字体”下拉菜单,选择合适的字体、字号、颜色等。
(4)设置段落格式:选中文本,点击“开始”选项卡中的“段落”下拉菜单,设置段落间距、缩进、对齐方式等。
3. 文档的排版和打印(1)插入表格:点击“插入”选项卡中的“表格”,在弹出的对话框中设置表格的行列数,然后点击“确定”。
(2)插入图片:点击“插入”选项卡中的“图片”,在弹出的对话框中选择要插入的图片,然后点击“插入”。
(3)设置页眉和页脚:点击“插入”选项卡中的“页眉和页脚”,在弹出的对话框中设置页眉和页脚的内容、格式等。
(4)打印文档:点击“文件”菜单,选择“打印”,在弹出的对话框中设置打印范围、打印份数、打印设置等,然后点击“打印”。
实验4、文件操作1.实验目的通过编写文件读写及上锁的程序,进一步熟悉Linux 中文件I/O 相关的应用开发,并且熟练掌握open()、read()、write()、fcntl()等函数的使用。
2.实验内容在Linux 中FIFO 是一种进程之间的管道通信机制。
Linux 支持完整的FIFO通信机制。
本实验内容,通过使用文件操作,仿真FIFO(先进先出)结构以及生产者-消费者运行模型。
本实验中需要打开两个虚拟终端,分别运行生产者程序(producer)和消费者程序(customer)。
此时两个进程同时对同一个文件进行读写操作。
因为这个文件是临界资源,所以可以使用文件锁机制来保证两个进程对文件的访问都是原子操作。
先启动生产者进程,它负责创建仿真FIFO 结构的文件(其实是一个普通文件)并投入生产,就是按照给定的时间间隔,向FIFO 文件写入自动生成的字符(在程序中用宏定义选择使用数字还是使用英文字符),生产周期以及要生产的资源数通过参数传递给进程(默认生产周期为1s,要生产的资源数为10 个字符)。
后启动的消费者进程按照给定的数目进行消费,首先从文件中读取相应数目的字符并在屏幕上显示,然后从文件中删除刚才消费过的数据。
为了仿真FIFO 结构,此时需要使用两次复制来实现文件内容的偏移。
每次消费的资源数通过参数传递给进程,默认值为10 个字符。
3.实验步骤(1)实验流程图本实验的两个程序的流程图如图:开始开始(producer)(customer)消费资源创建FIFO结构文件(打印字符)否消费够了吗?生产一个资源是上锁上锁将剩下的数据拷贝到等待临时文件tmp中一秒将“生产”的字符写入到FIFO结构文件用临时文件tmp覆盖原数据文件,这样模拟FIFO结构解锁解锁生产完了吗?删除临时文件结束结束图6.4 节流程图(2)代码头部文件代码:mylock.hstruct myflock{short l_type; /*文件锁类型:F_RDLOCK 读取锁;F_WRLCK 写入锁;F_UNLCK 解锁*/ off_t l_start; /*相对位移量*/short l_whence; /*相对位移量的起点SEEK_SET;SEEK_CUR; SEEK_END: */off_t l_len; /* 加锁区域长度*/pid_t l_pid; /* */} ;/* lock_set */int lock_set(int fd, int type){struct myflock old_lock, lock;lock.l_whence = SEEK_SET;lock.l_start = 0;lock.l_len = 0;lock.l_type = type;lock.l_pid = -1;/* 判断文件是否可以上锁*/fcntl(fd, F_GETLK, &lock);if (lock.l_type != F_UNLCK){/* 判断文件不能上锁的原因*/if (lock.l_type == F_RDLCK) /* 该文件已有读取锁*/{printf("Read lock already set by %d\n", lock.l_pid);}else if (lock.l_type == F_WRLCK) /* 该文件已有写入锁*/{printf("Write lock already set by %d\n", lock.l_pid);}}/* l_type 可能已被F_GETLK 修改过*/lock.l_type = type;/* 根据不同的type 值进行阻塞式上锁或解锁*/if ((fcntl(fd, F_SETLKW, &lock)) < 0){printf("Lock failed:type = %d\n", lock.l_type); return 1;}switch(lock.l_type){case F_RDLCK: printf("Read lock set by %d\n", getpid());break;case F_WRLCK: printf("Write lock set by %d\n", getpid());break;case F_UNLCK: printf("Release lock by %d\n", getpid()); return 1;break;default:break;} /* end of switch */return 0;}生产者程序的源代码:producer.c/* producer.c */#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <fcntl.h>#include "mylock.h"#define MAXLEN 10 /* 缓冲区大小最大值*/#define ALPHABET 1 /* 表示使用英文字符*/#define ALPHABET_START 'a' /* 头一个字符,可以用'A'*/#define COUNT_OF_ALPHABET 26 /* 字母字符的个数*/#define DIGIT 2 /* 表示使用数字字符*/#define DIGIT_START '0' /* 头一个数字字符*/#define COUNT_OF_DIGIT 10 /* 数字字符的个数*/#define SIGN_TYPE ALPHABET /* 本实例用英文字符*/const char *fifo_file = "./myfifo"; /* !" FIFO 文件名*/char buff[MAXLEN]; /* 缓冲区*//* 函数product() 产生一个字符并写入仿真FIFO 文件中*/int roduct(void){int fd;unsigned int sign_type, sign_start, sign_count, size;static unsigned int counter = 0;/* 打开!" FIFO 文件*/if ((fd = open(fifo_file, O_CREAT|O_RDWR|O_APPEND, 0644)) < 0){printf("Open fifo file error\n"); exit(1);}sign_type = SIGN_TYPE;switch(sign_type){case ALPHABET: /* 英文字符*/{sign_start = ALPHABET_START;sign_count = COUNT_OF_ALPHABET;}break;case DIGIT: /* 数字字符*/{sign_start = DIGIT_START;sign_count = COUNT_OF_DIGIT;}break;default:{return -1;}} /*end of switch*/sprintf(buff, "%c", (sign_start + counter)); counter = (counter + 1) % sign_count;lock_set(fd, F_WRLCK); /* 上写锁*/if ((size = write(fd, buff, strlen(buff))) < 0){printf("Producer: write error\n"); return -1;}lock_set(fd, F_UNLCK); /* 解锁*/return 0;}int main(int argc ,char *argv[]){int time_step = 1; /* 生产周期*/int time_life = 10; /* 需要生产的资源数*/if (argc > 1){/* 第一个参数表示生产周期*/sscanf(argv[1], "%d", &time_step);}if (argc > 2){/* 第二个参数表示需要生产的资源数*/sscanf(argv[2], "%d", &time_life);}while (time_life--){if (product() < 0){break;}sleep(time_step);}exit(EXIT_SUCCESS);}消费者程序的源代码:customer.c/* customer.c */#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <fcntl.h>#include "mylock.h"#define MAX_FILE_SIZE 100 * 1024 * 1024 /* 100M*/ const char *fifo_file = "./myfifo"; /* 仿真FIFO 文件名*/ const char *tmp_file = "./tmp"; /* 临时文件名*//* 资源消费函数customing */int customing(const char *myfifo, int need){int fd;char buff;int counter = 0;if ((fd = open(myfifo, O_RDONLY)) < 0){printf("Function customing error\n");return -1;}printf("Enjoy:");lseek(fd, SEEK_SET, 0);while (counter < need){while ((read(fd, &buff, 1) == 1) && (counter < need))fputc(buff, stdout); /* -.就是在屏幕上/0的显示*/counter++;}}fputs("\n", stdout);close(fd);return 0;}/* myfilecopy()函数: 实现从sour_file 文件的offset 偏移处开始将count 个字节数据复制到dest_file 文件*/ int myfilecopy(const char *sour_file,const char *dest_file, int offset, int count, int copy_mode){int in_file, out_file;int counter = 0;char buff_unit;if ((in_file = open(sour_file, O_RDONLY|O_NONBLOCK)) < 0){printf("Function myfilecopy error in source file\n"); return -1;}if ((out_file = open(dest_file, O_CREAT|O_RDWR|O_TRUNC|O_NONBLOCK, 0644)) < 0){printf("Function myfilecopy error in destination file:"); return -1;}lseek(in_file, offset, SEEK_SET);while ((read(in_file, &buff_unit, 1) == 1) && (counter < count)){write(out_file, &buff_unit, 1); counter++;}close(in_file);close(out_file);return 0;}/* custom()函数:实现FIFO 消费者*/int custom(int need){int fd;/* 对资源进行消费,need 表示该消费的资源数目*/customing(fifo_file, need);if ((fd = open(fifo_file, O_RDWR)) < 0){printf("Function myfilecopy error in source_file:");return -1;}/* 为了模拟FIFO 结构,对整个文件进平行行移动*/lock_set(fd, F_WRLCK);myfilecopy(fifo_file, tmp_file, need, MAX_FILE_SIZE, 0);myfilecopy(tmp_file, fifo_file, 0, MAX_FILE_SIZE, 0);lock_set(fd, F_UNLCK);unlink(tmp_file);close(fd);return 0;}int main(int argc ,char *argv[]){int customer_capacity = 10;if (argc > 1) /* 第一个参数指定需要消费的资源数目,默认值为10 */{sscanf(argv[1], "%d", &customer_capacity);}if (customer_capacity > 0){custom(customer_capacity);}exit(EXIT_SUCCESS);}(3) 分别编译生产者程序producer.c 和消费者程序customer.c(4) 确保编译没有错误后,先在控制台终端1上运行生产者程序:./producer 1 20再在控制台终端2上运行消费者程序:./customer 54.完成实验报告(1)将实验过程和实验结果截图(2)认真阅读程序代码,参考代码并根据实验结果,完成实验总结。