1.1文件对象
文件只是连续的字节序列。数据的传输经常会用到字节流,无论字节流是由单个字节还是大块数据组成.
1.2文件内建函数open()和file()
内建函数open()的基本语法是:
file_object=open(file_name,access_mode='r',buffering=-1)
file_name是包含要打开的文件名字的字符串,它可以是相对路径或者绝对路径。
access_mode可选变量也是一个字符串,代表文件打开的模式.
'r'代表:读取;
'w'代表:写入;
'a'代表:追加;
'U'代表:通用换行符支持
使用'r'或'U'模式打开的文件必须是已经存在的
使用'w'模式打开的文件若存在则首先清空,然后(重新)创建
以'a'模式打开的文件是为追加数据作准备的,所有写入的数据都将追加到文件的末尾.即使你seek到了其它的地方.如果文件不存在,将被自动创建。
包括'b'的使用-如果你选择使用它的话.如果没有给定access_mode,它将自动采用默认值'r'.
buffering可选参数用于指示访问文件所采用的缓冲方式:
0表示不缓冲
1表示只缓冲一行数据
任何其它大于1的值代表使用给定值作为缓冲区大小
不提供该参数或者给定负值代表使用系统默认缓冲机制,既对任何类电报机(tty)设备使用行缓冲,其它设备使用正常缓冲.一般情况下使用系统默认方式即可.表9.1文件对象 文件模式 操作
r 以读方式打开
rU或Ua 以读方式打开,同时提供通用换行符支持
w 以写方式打开(必要时清空)
a 以追加模式打开(从EOF开始,必要时创建新文件)
r+ 以读写模式打开
w+ 以读写模式打开(参见w)
a+ 以读写模式打开(参见a)
rb 以二进制读模式打开
wb 以二进制写模式打开(参见w)
ab 以二进制追加模式打开(参见a)
rb+ 以二进制读写模式打开(参见r+)
wb+ 以二进制读写模式打开(参见w+)
ab+ 以二进制读写模式打开(参见a+)
一些打开文件的例子:
fp=open('/etc/motd') #以读方式打开
fp=open('test','w') #以写方式打开
fp=open('data','r+') #以读写方式打开
fp=open(r'c:\io.sys','rb') #以二进制读模式打开
1.2.1工厂函数file()
任何使用open()的地方,都可以使用file()替换它
建议使用open()来读写文件,在处理文件对象时使用file()
1.2.2通用换行符支持(UNS)
不同平台用来表示行结束的符号是不同的,例如\n,\r,或者\r\n,特别是在导入模块时分外重要。用相同的方式处理所有文件需要UNS。
当你使用'U'标志打开文件的时候,所有的行分割符(或行结束符,无论它原来是什么)通过Python的输入方法(例如read*())返回时都会被替换为换行符NEWLINE(\n).('rU'模式也支持'rb'选项).这个特性还支持包含不同类型行结束符的文件.文件对象的newlines属性会记录它曾“看到的”文件的行结束符.如果文件刚被打开,程序还没有遇到行结束符,那么文件的newlines为None.在第一行被读取后,它被设置为第一行的结束符.如果遇到其它类型的行结束符,文件的newlines会成为一个包含每种格式的元组.注意UNS只用于读取文本文件.没有对应的处理文件输出的方法.
在编译Python的时候,UNS默认是打开的.如果你不需要这个特性,在运行configure脚本时,你可以使用--without-universal-newlines开关关闭它.如果你非要自己处理行结束符,请查阅核心笔记,使用os模块的相关属性.
1.3文件内建方法open()
成功执行并返回一个文件对象之后,所有对该文件的后续操作都将通过这个"句柄"进行.文件方法可以分为四类:输入,输出,文件内移动,以及杂项操作
1.3.1输入
read()方法
用来直接读取字节到字符串中,最多读取给定数目个字节.如果没有给定size参数(默认值为-1)或者size值为负,文件将被读取直至末尾.未来的某个版本可能会删除此方法.
readline()方法
读取打开文件的一行(读取下个行结束符之前的所有字节).然后整行,包括行结束符,作为字符串返回.和read()相同,它也有一个可选的size参数,默认为-1,代表读至行结束符.如果提供了该参数,那么在超过size个字节后会返回不完整的行.
readlines()方法
并不像其它两个输入方法一样返回一个字符串.它会读取所有(剩余的)行然后把它们作为一个字符串列表返回.它的可选参数sizhint代表返回的最大字节大小.如果它大于0,那么返回的所有行应该大约有sizhint字节(可能稍微大于这个数字,因为需要凑齐缓冲区大小).
1.3.2输出
write()内建方法功能与read()和readline()相反.它把含有文本数据或二进制数据块的字符串写入到文件中去.
和readlines()一样,writelines()方法是针对列表的操作,它接受一个字符串列表作为参数,将它们写入文件.行结束符并不会被自动加入,所以如果需要的话,你必须在调用writelines()前给每行结尾加上行结束符.注意这里并没有"writeline()"方法,因为它等价于使用以行结束符结尾的单行字符串调用write()方法.
1.3.3文件内移动
seek()方法可以在文件中移动文件指针到不同的位置.offset字节代表相对于某个位置偏移量.位置的默认值为0,代表从文件开头算起(即绝对偏移量),1代表从当前位置算起,2代表从文件末尾算起.当人们打开文件进行读写操作的时候就会接触到seek()方法。
text()方法是对seek()的补充;它告诉你当前文件指针在文件中的位置-从文件起始算起,单位为字节.
1.3.4文件迭代
file.readlines()来读取所有数据,这样程序员可以尽快释放文件资源.如果不需要这样 file.readline()一次读取一行
file.next()可以用来读取文件的下一行
在所有行迭代完成后引发StopIteration异常
for eachLine in f.readline():
:
文件迭代更为高效,而且写(和读)这样的Python代码更容易
1.3.5其它
close()通过关闭文件来结束对它的访问.
良好的编程习惯要求在重新赋另个文件对象前关闭这个文件.如果你不显式地关闭文件,那么你可能丢失输出缓冲区的数据.
fileno()方法返回打开文件的描述符.这是一个整数,可以用在如os模块(os.read())的一些底层操作上.
调用flush()方法会直接把内部缓冲区中的数据立刻写入文件,而不是被动地等待输出缓冲区被写入.isatty()是一个布尔内建函数,当文件是一个类tty设备时返回True,否则返回False.truncate()方法将文件截取到当前文件指针位置或者到给定size,以字节为单位.
1.3.6文件方法杂项
print语句默认在输出内容末尾后加一个换行符,而在语句后加一个逗号就可以避免这个行为.readline()和readlines()函数不对行里的空白字符做任何处理(参见本章练习),所以你有必要加上逗号.如果你省略逗号,那么显示出的文本每行后会有两个换行符,其中一个是输入是附带的,另个是print语句自动添加的.
filename = raw_input('Enter file name:')
fobj = open(filename,'w')
while True:
aLine = raw_input("Enter a line('.' to quit):")
if aLine != ".":
fobj.write('%s%s'%(aLine,os.linesep)
else:
break
fobj.close()
这里我们每次从用户接收一行输入,然后将文本保存到文件中.由于raw_input()不会保留用户输入的换行符,调用write()方法时必须加上换行符。而且,在键盘上很难输入一个EOF(end-of-file)字符,所以,程序使用句号(.)作为文件结束的标志,当用户输入句号后会自动结束输入并关闭文件.第二个例子以可读可写模式创建一个新的文件(可能是清空了一个现有的文件).在向文件写入数据后,我们使用seek()方法在文件内部移动,使用tell()方法展示我们的移动过程.
>>>f=open('/tmp/x','w+')
>>>f.tell()
0
>>>f.write('test line 1\n') #加入一个长为12的字符串[0-11]
>>>f.tell()
12
>>>f.write('test line 2\n') #加入一个长为12的字符串[12-23]
>>>f.tell() #告诉我们当前的位置
24
>>>f.seek(-12,1) #向后移12个字节
>>>f.tell() #到了第二行的开头
12
>>>f.readline()
'test line 2\012'
>>>f.seek(0,0) #回到最开始
>>>f.readline()
'test line 1\012'
>>>f.tell() #又回到了第二行
12
>>>f.readline()
'test line 2\012'
>>>f.tell() #又到了结尾
24
>>>f.close() #关闭文件
文件对象的内建方法列表
文件对象的方法 操作
file.close() 关闭文件
file.fileno() 返回文件的描述符(file descriptor,FD,整数值)
file.flush() 刷新文件的内部缓冲区
file.isatty() 判断file是否是一个类tty设备
file.next() 返回文件的下一行(类似于file.readline()),或在没有 其它行时引发StopIteration异常
file.read(size=-1) 从文件读取size个字节,当未给定size或给定负值的时 候,读取剩余的所有字节,然后作为字符串返回 file.readline(size=-1) 从文件中读取并返回一行(包括行结束符),或返回最大 size个字符
file.readlines(sizhint=0) 读取文件的所有行并作为一个列表返回(包含所有的行结 束符);如果给定sizhint且大于0,那么将返回总和大约 为sizhint字节的行(大小由缓冲器容量的下一个值决定) (比如说缓冲器的大小只能为4K的倍数,如果sizhint 为15k,则最后返回的可能是16k按)
file.xreadlines() 用于迭代,可以替换readlines()的一个更高效的方法 file.seek(off,whence=0) 在文件中移动文件指针,从whence(0代表文件其始,1代 表当前位置,2代表文件末尾)偏移off字节
file.tell() 返回当前在文件中的位置 file.truncate(size=file.tell()) 截取文件到最大size字节,默认为当前文件位置 file.write(str) 向文件写入字符串
file.writelines(seq) 向文件写入字符串序列seq
1.4文件内建属性
文件对象的属性
文件对象的属性 描述
file.closed True表示文件已经被关闭,否则为False
File.encoding 文件所使用的编码-当Unicode字符串被写入数据时,它们将 自动使用file.encoding转换为字节字符串;若 file.encoding为None时使用系统默认编码
file.mode Access文件打开时使用的访问模式
file.name 文件名
file.newlines 未读取到行分隔符时为None,只有一种行分隔符时为一个字 符串,当文件有多种类型的行结束符时,则为一个包含所有当 前所遇到的行结束符的列表
file.softspace 为0表示在输出一数据后,要加上一个空格符,1 表示不加。 这个属性一般程序员用不着,由程序内部使用。
1.5标准文件
一般说来,只要你的程序一执行,那么你就可以访问三个标准文件.它们分别是标准输入(一般是键盘),标准输出(到显示器的缓冲输出)和标准错误(到屏幕的非缓冲输出).(这里所说的"缓冲"和"非缓冲"是指open()函数的第三个参数.)这些文件沿用的是C语言中的命名,分别为stdin,stdout和stderr.我们说"只要你的程序一执行就可以访问这三个标准文件",意思是这些文件已经被预先打开了,只要知道它们的文件句柄就可以随时访问这些文件.
Python中可以通过sys模块来访问这些文件的句柄.导入sys模块以后,就可以使用sys.stdin,sys.stdout和sys.stderr访问.print语句通常是输出到sys.stdout;而内建
raw_input()则通常从sys.stdin接受输入.记得sys.*是文件,所以你必须自己处理好换行符.而print语句会自动在要输出的字符串后加上换行符。
1.6命令行参数
sys模块通过sys.argv属性提供了对命令行参数的访问
sys.argv是命令行参数的列表,第一项sys.argv[0]永远是程序的名称.
len(sys.argv)是命令行参数的个数
1.7文件系统
对文件系统的访问大多通过Python的os模块实现.该模块是Python访问操作系统功能的主要接口.os模块实际上只是真正加载的模块的前端,而真正的那个"模块"明显要依赖与具体的操作系统.
os模块的文件/目录访问函数
函数 描述
文件处理
mkfifo()/mknod() 创建命名管道/创建文件系统节点
remove()/unlink() 删除文件
rename()/renames() 重命名文件
*stat() 返回文件信息
symlink() 创建符号链接
utime() 更新时间戳
tmpfile() 创建并打开('w+b')一个新的临时文件
walk() 生成一个目录树下的所有文件名
目录/文件夹
chdir()/fchdir() 改变当前工作目录/通过一个文件描述符改变当前工作目录 chroot() 改变当前进程的根目录
listdir() 列出指定目录的文件
getcwd()/getcwdu() 返回当前工作目录/功能相同,但返回一个Unicode对象 mkdir()/makedirs() 创建目录/创建多层目录
rmdir()/removedirs() 删除目录/删除多层目录访问/权限
access() 检验权限模式
chmod() 改变权限模式
chown()/lchown() 改变owner和groupID/功能相同,但不会跟踪链接
umask() 设置默认权限模式文件描述符操作
open() 底层的操作系统open,对于文件,使用标准的内建open()函数 read()/write() 根据文件描述符读取/写入数据
dup()/dup2() 复制文件描述符号/功能相同,但是是复制到另一个文件描述符
设备号
makedev() 从major和minor设备号创建一个原始设备号
major()/minor() 从原始设备号获得major/minor设备号
os.path模块中的路径名访问函数
函数 描述
分隔
basename() 去掉目录路径,返回文件名
dirname() 去掉文件名,返回目录路径
join() 将分离的各部分组合成一个路径名
split() 返回(dirname(),basename())元组
splitdrive() 返回(drivename,pathname)元组
splitext() 返回(filename,extension)元组
信息
getatime() 返回最近访问时间
getctime() 返回文件创建时间
getmtime() 返回最近文件修改时间
getsize() 返回文件大小(以字节为单位)
查询
exists() 指定路径(文件或目录)是否存在
isabs() 指定路径是否为绝对路径
isdir() 指定路径是否存在且为一个目录
isfile() 指定路径是否存在且为一个文件
islink() 指定路径是否存在且为一个符号链接
ismount() 指定路径是否存在且为一个挂载点
samefile() 两个路径名是否指向同个文件