6.4.4 缓冲

当一个人饿了,面对一大碗饭,他该怎么吃呢?任务的目标是将这一碗饭送到肚子里去, 解决饿的问题,而达成目标的最快方法是将一碗饭一口吞下,可惜没人有这么大的嘴。事实 上,人们采取的是每次吃一口的方式,一口一口地将饭吃到肚子里去。这个例子很好地说明 了计算机解决问题时的“缓冲”技术。

利用计算机解决问题时,经常需要将大量数据从一个地方传送到另一个地方,并且一次 性地传送所有数据会遇到种种限制。这时,可以在内存中建立一个缓冲区(buffer),用做传 送数据的临时过渡。通过缓冲区,就可以将大量数据以一小批一小批的方式传送到目的地。

例如,处理一个很大的磁盘文件时,由于内存容量有限,无法一次性将文件内容全部读 入内存,只好在内存中建立一个缓冲区,每次将一小批数据读入缓冲区以供 CPU 处理。上 面说的吃饭例子中,我们的嘴就是缓冲区。生活中类似的例子很多,例如学生用的书包其实 也是一个缓冲区——学生不可能随身带着自己的所有书籍,于是采用书包作为临时存储区, 每天只需带当天要用的课本。

又如,当计算机向打印机传送数据进行打印时,由于发送方(计算机)和接收方(打印 机)的数据处理速率存在很大差异,不可能将数据一下子传给打印机,这时也可以使用缓冲 区来协调计算机和打印机的步调。这种情形在生活中也很常见,去银行办理业务时,由于顾 客来的频繁,而银行职员处理业务较慢,不可能实现“随到随处理”,因此银行设置了等待 区,用于缓冲顾客流。

下面我们编写一个文件拷贝程序,功能是将用户指定的文件复制到文件夹 d:\backup 中。 假设内存容量有限或者 CPU 处理能力有限,导致每次只能处理 1024 个字符。为此,我们使 用 read(n)来读文件,其中参数 n 表示从文件读取 n 个字符。程序代码如下:

【程序 6.3】buffer.py

def main():
    fname = raw_input("Enter file name: ") 
    f = open(fname,"r")
    fcopy = open("d:/backup/"+fname,"w") 
    while True:
        buffer = f.read(1024) 
        if buffer == "":
            break 
        fcopy.write(buffer)
    f.close() 
    fcopy.close()

显然这里的字符串变量 buffer 相当于缓冲区,通过每次读入 1024 个字符,像蚂蚁搬家一样将整个文件复制到目的文件夹。