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.closedTrue表示文件已经被关闭,否则为False
File.encoding文件所使用的编码-当Unicode字符串被写入数据时,它们将自动使用file.encoding转换为字节字符串;若file.encoding为None时使用系统默认编码
file.modeAccess文件打开时使用的访问模式
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()两个路径名是否指向同个文件