Python回顾与整理7:文件和输入输出

0.说明python

        

        主要是下面的内容:
程序员

  • 文件对象:内建函数、内建方法、属性json

  • 标准文件bash

  • 文件系统:访问方法、文件执行数据结构

  • 持久化存储ide

  • 标准库中与文件有关的模块函数




1.文件对象测试


        文件对象是用来访问文件的接口,而文件只是连续的字节序列,数据的传输常常会用到字节流,不管字节流是由单个字节仍是大块数据组成。
编码




2.文件内建函数(open()和file())spa


        内建函数open()以及file()提供了初始化输入/输出(I/O)操做的通用接口,若是打开文件成功,则会返回一个文件对象,不然会引起IOError异常,open()和file()并无任何区别,能够任意替换,基本语法以下:

file_object = open(file_name, access_mode='r', buffering=-1)

        说明以下:

  • file_name:包含要打开的文件名的字符串表示,能够是相对路径或绝对路径

  • access_mode:访问模式,可选参数,若是没有指定,默认值为'r'(字符串表示)

        访问模式主要有下面几种:

模式 说明
'r' 读取,文件必需要存在
'w' 写入,文件存在则清空原来文件内容再写入;文件不存在则自动建立该文件并写入内容
'a' 追加,文件存在只会在文件后面追加数据;文件不存在则自动建立该文件并写入内容
'+' 表示可读可写,但不能单独使用,通常与'r'一块儿使用
'b'

以二进制模式访问文件,但不能做为第一个字符出现,对于Unix系统来讲,可能会被忽略掉,由于Unix系统默认把全部文件看成进制文件,因此使用'b'模式时,通常是但愿在全部系统平台上都是用二进制模式来访问文件(好比在Windows上)

'U'

通用换行符支持(UNS),用来处理不一样操做系统平台上的换行符(\n,\r或者\r\n),使用该模式时,文件对象的newlines属性会记录它曾“看到的”文件的行结束符,文件刚打开时,程序尚未遇到换行符,newlines值为None,在文件第一行被读取后,它被设置为第一行的结束符,若是遇到其余类型的行结束符,newlines会成为一个包含每种格式的元组。

不过须要注意的是,UNS中用于读取文本文件,没有对应的处理文件输出的方法。默认状况下该模式是打开的,若是不须要,能够在执行脚本文件时使用参数--without-universal-newlines

        经常使用的访问模式组合以下:

文件对象的访问模式
文件模式 操做
r 以读方式打开
rU或U 以读方式打开,同时提供通用换行符支持
w 以写方式打开(必要时清空)
a 以追加模式打开(从EOF开始,必要时建立新文件)
r+ 以读写模式打开
w+ 以读写模式打开(参见w)
a+ 以读写模式打开(参见a)
rb 以二进制读模式打开
wb 以二进制写模式打开(参见w)
ab 以二进制追加模式打开(参见a)
rb+ 以二进制读写模式打开(参见r+)
wb+ 以二进制读写模式打开(参见w+)
ab+ 以二进制读写模式打开(参见a+)
  • buffering:用于指示访问文件所采用的缓冲方式,采用默认方式便可

        0表示不缓冲,1表示缓冲一行数据,任何其余大于1的值表明使用给定值做为缓冲区大小。

        



3.文件内建方法


        open()成功执行后会返回一个文件对象,对该文件的全部操做都经过这个句柄来完成,其操做方法以下:


(1)输入

        主要以下:

  • read(size=-1):读取给定数目个字节并以字符串返回,size默认为-1或其余负值时,表示所有读取

>>> f = open('test.txt', 'r')
>>> f.readlines()
['xpleafclyyh\n', 'cl\n']
>>> f = open('test.txt', 'r')
>>> f.read()
'xpleafclyyh\ncl\n'
>>> f = open('test.txt', 'r')
>>> f.read(6)
'xpleaf'
>>> f.close()
  • readline(size=-1):读取文件的一行并以字符串返回,size默认为-1或其余负值时,表示所有读取,给定size值时,若是小于当前行的字节数,则不完整地读取一行,不然则会完整读取该行

>>> f = open('test.txt', 'r')
>>> f.readlines()
['xpleafclyyh\n', 'cl\n']
>>> f = open('test.txt', 'r')
>>> f.readline()
'xpleafclyyh\n'
>>> f = open('test.txt', 'r')
>>> f.readline(6)
'xpleaf'
>>> f.readline(10)
'clyyh\n'
>>> f.close()
  • readlines([size]):以列表的方式返回全部的行,不过在测试时size参数没有起做用

>>> f = open('test.txt', 'r')
>>> f.readlines()
['xpleafclyyh\n', 'cl\n']
>>> f.close()

        另外还有一个xreadlines()的方法,能够不用所有读取全部的行以节省空间,不过因为如今文件读取可使用for循环迭代的方式,即for eachLine in file,因此能够不使用xreadlines()便可以节省内存空间。

        在读取操做时能够看到,Pytthon不会自动为咱们去掉换行符,因此通常咱们这样处理:

f = open('myFile', 'r')
data = [line.strip() for line in f.readlines()]
f.close()

        一样,在下面的输出中,Python也不会自动为咱们加上换行符,这个操做要咱们本身完成。


(2)输出

        主要以下:

  • write(str):把数据写入到文件中,须要写入一行数据时能够在字符串后面加行结束符便可,因此输出的方法并无writeline()

>>> f = open('test.txt', 'w')
>>> f.write('xpleaf')
>>> f.write('clyyh\n')
>>> f.write('cl\n')
>>> f.close()
>>> f = open('test.txt', 'r')
>>> f.readlines()
['xpleafclyyh\n', 'cl\n']
>>> f.close()
  • writelines(seq):接受一个字符串列表做为参数,将它们写入文件,不过行结束符并不会被自动加上

>>> f = open('test.txt', 'w')
>>> data = ['xpleaf', 'test\n', 'clyyh\n']
>>> f.writelines(data)
>>> f.close()
>>> f = open('test.txt', 'r')
>>> f.readlines()
['xpleaftest\n', 'clyyh\n']
>>> f.close()


(3)文件内移动

        主要是下面的两个方法:

  • seek(offset[, whence]):移动文件指针到不一样的位置,offset字节表示相对于位置whence的偏移量,whence的默认值为0,表示相对于文件的开头,1表明从当前位置算起,2表明从文件末尾算起

  • tell():返回当前文件指针所在的位置

        举例以下:

>>> f = open('test.txt', 'r')
>>> f.readlines()
['xpleafclyyh\n', 'cl\n']
>>> f.seek(0)
>>> f.read(6)
'xpleaf'
>>> f.tell()
6
>>> f.seek(8)
>>> f.tell()
8
>>> f.read()
'yyh\ncl\n'
>>> f.tell()
15
>>> f.seek(-3, 1)
>>> f.tell()
12
>>> f.read()
'cl\n'
>>> f.seek(0)
>>> f.tell()
0
>>> f.seek(-3, 2)
>>> f.tell()
12
>>> f.read()
'cl\n'
>>> f.close()


(4)文件迭代

        在Python2.2以后,引进了迭代器和文件迭代,文件对象成为了它们本身的迭代器,所以能够经过使用for循环迭代(for line in file)的方式来取代xreadlines()的功能,这样的话就能够大大节省内存空间。由于文件对象自己就是一个迭代器,因此它有next()方法,而且在迭代完全部数据后会引起StopIteration异常。


(5)其余

        其余内建方法以下:

  • close():经过关闭文件来结束对它的访问,若是不显式地关闭文件,那么可能丢失输出缓冲区的数据

  • flush():直接把内部缓冲区中的数据马上写入文件

        在执行f.write()的操做时,其实并无把内容实时地写入到磁盘中,而是保存到内部缓冲区中,在文件关闭或执行flush()时都会保存在磁盘中。

  • flieno():返回打开文件的描述符

>>> f = open('welcome.txt', 'r')
>>> f.fileno()
3
  • isatty():当文件是一个类tty设备时返回True,不然返回False

  • truncate([size]):将文件截取到当前文件指针位置或者到给定size,以字节为单位

        所谓的截取其实就是把当前位置以后的文件内容删除,给定了size参数,代表从第几个字节开始截取(包括该字节),若是size没有给定,则默认从当前位置开始,以下:

>>> f = open('test.txt', 'r+')
>>> f.read()
'clyyh'
>>> f.truncate()
>>> f.seek(0)
>>> f.read()
'clyyh'
>>> f.truncate(2)
>>> f.seek(0)
>>> f.read()
'cl'


(6)行分隔符与路径分隔符在不一样操做系统中的差别

        以下:

  • 行分隔符:在POSIX(Unix系列或Mac OX X)系统上是'\n'字符,在旧的MacOS下是'\r',而DOS和Wind32系统下结合了二者'\r\n'

  • 路径分隔符:POSIX使用'/',DOS和Windows使用'\',旧版本的MacOS使用':'

        若是要建立跨平台的应用时,就须要处理这些差别,不过Python中的os模块已经有相关属性来为咱们处理这些差别:

有助于跨平台开发的os模块属性
os模块属性 描述
linesep 用于在文件中分隔行的字符串
sep 用来分隔文件路径名的字符串
pathsep 用于分隔文件路径的字符串
curdir 当前工做目录的字符串名称
pardir (当前工做目录的)父目录字符串名称

        下面是在Linux操做系统上的例子:

>>> import os
>>> os.linesep
'\n'
>>> os.sep
'/'
>>> os.pathsep
':'
>>> os.curdir
'.'
>>> os.pardir
'..'

        下面是在Windows操做系统上的例子:

>>> import os
>>> os.linesep
'\r\n'
>>> os.sep
'\\'
>>> os.pathsep
';'
>>> os.curdir
'.'
>>> os.pardir
'..'

        不过另外须要注意的是,print语句在输出时会自动为咱们添加一个换行符,若是不须要该换行符,能够在输出语句后面加一个逗号','。




4.文件内建属性


        主要以下:

文件对象的属性
属性 描述
flie.closed 若是文件已经关闭返回True,不然返回False
file.encoding 文件所使用的编码——当Unicode字符串被写入数据时,它们将自动使用file.encoding转换为字节字符串;若file.encoding为None时使用系统默认编码
file.mode 文件打开时使用的访问模式
file.name

文件名

file.newlines 未读取到行分隔符时为None, 只有一种行分隔符时为一个字符串,当文件有多种类型的行结束符时,则为一个包含全部当前所遇到的行结束符的列表
file.softspace 为0表示在输出一数据后,要加上一个空格符,1表示不加。这个属性通常程序员用不着,由程序内部使用

        举例以下:

>>> f = open('test.txt', 'r+')
>>> f.read()
'xpleaf\nclyyh\ncl'
>>> f.closed
False
>>> f.encoding
>>> f.mode
'r+'
>>> f.name
'test.txt'
>>> f.newlines
>>> f.softspace
0

        可是能够看到的是,newlines并无任何输出。




5.标准文件


        只要Python程序一执行,其实就能够访问到下面的这三个标准文件:

  • 标准输入:键盘或磁盘的输入

  • 标准输出:到显示器的缓冲输出

  • 标准错误:到屏幕的非缓冲输出

        注意上面的缓冲指的是open()的第三个参数,而之因此说程序一执行就能够访问这3个标准文件,是由于这些文件预先已经被打开了,只要知道它们的文件句柄主能够随时访问这些文件,Python中能够经过sys模块来访问这些文件的句柄:

  • sys.stdin

  • sys.stdout

  • sys.stderr

        print语句一般是输出到sysy.stdout,而raw_input()则一般是从sys.stdin接收输入,以下:

>>> import sys
>>> sys.stdout.write('xpleaf\n')
xpleaf
>>> sys.stdin.readline()
xpleaf
'xpleaf\n'

        其实上面的三个模块的属性也是file文件类型:

>>> for stream in [sys.stdin, sys.stdout, sys.stderr]:
...   print type(stream)
... 
<type 'file'>
<type 'file'>
<type 'file'>




6.命令行参数


        在C语言中有argc和argv两个变量,分别表明参数个数和参数向量,在Python中,argc其实就是sys.argv列表的长度,而该列表的第一项sys.argv[0]永远是程序的名称。举例以下:

        程序代码:

#!/usr/bin/env python

import sys

print 'you entered', len(sys.argv), 'arguments...'
print 'they were', str(sys.argv)

        执行结果:

xpleaf@leaf:~$ python argv.py xpleaf clyyh cl
you entered 4 arguments...
they were ['argv.py', 'xpleaf', 'clyyh', 'cl']

        PYthon中关于命令行参数处理的模块以下:

  • getopt模块:不是很精细,可是简单

  • optparse模块:功能强大,更面向对象




7.文件系统


        Python对文件系统的访问经过os模块实现,该模块是Python访问操做系统功能的主要接口,但不是真正的接口,真正的接口是由操做系统提供的,因此能够有以下的关系:

Python程序—os模块—操做系统文件系统接口模块(由os模块根据不一样的操做系统进行选择)

        而最经常使用的是os和os.path,这两个模块提供了与平台和操做系统无关的统一文件系统访问方法,以下:

  • os模块

os模块的文件/目录访问函数
函数 描述
文件处理
mkfifo()/mknod() 建立命名管道/建立文件系统节点
remove()/unlink() 删除文件
rename()/renames() 重命名文件
stat(),lstat(),xstat() 返回文件信息
symlink() 建立符号连接
utime() 更新时间戳
tmpfile() 建立并打开('w+b')一个新的临时文件
目录/文件夹
chdir()/fchdir() 改变当前工做目录/经过一个文件描述符改变当前工做目录
chroot() 改变当前进程的根目录
listdir() 列出指定目录的文件
getcwd()/getcwdu() 返回当前工做目录/功能相同,但返回一个Unicode对象
mkdir()/makedirs() 建立目录/建立多层目录
rmdir()/removedirs() 删除目录/删除多层目录
访问/权限
access() 检验权限模式
chmod() 改变权限模式
chown()/lchown() 改变owner和group ID/功能相同,但不会跟踪连接
umask() 设置默认权限模式
文件描述符操做
open() 底层的操做系统open(对于文件,使用标准的内建open()函数)
read()/write() 根据文件描述符读取/写入数据
dup()/dup2() 复制文件描述符号/功能相同,可是是复制到另外一个文件描述符
设备号
makedev() 从major和minor设备号建立一个原始设备号
major()/minor() 从原始设备号得到major/minior设备号
  • os.path模块

os.path模块中的路径名访问函数
函数 描述
分隔
basename() 去掉目录路径,返回文件名
dirname() 去年文件名,返回目录路径
join() 将分离的各部分组合成一个路径名
split() 返回(dirname(), basename())元组
splitdrive() 返回(dirname, pathname)元组
splitext() 返回(filename, extension)元组
信息
getatime() 返回最近访问时间
getctime() 返回文件建立时间
getmtime() 返回最近文件修改时间
getsize() 返回文件大小(以字节为单位)
查询
exists() 指定路径(文件或目录)是否存在
isabs() 指定路径是否为绝对路径
isdir() 指定路径是否存在且为一个目录
isfile() 指定路径是否存在且为一个文件
islink() 指定路径是否存在且为一个符号连接
ismount() 指定路径是否存在且为一个挂载点
samefile() 两个路径名是否指向同一个文件


        关于os和os.path,一个经典的例子以下:

#!/usr/bin/env python

import os
for tmpdir in ('/tmp', r'c:\temp'):
    if os.path.isdir(tmpdir):
        break
else:
    print 'no temp directory available'
    tmpdir = ''

if tmpdir:
    os.chdir(tmpdir)
    cwd = os.getcwd()
    print '*** current temporary directory'
    print cwd

    print '*** creating example directory...'
    os.mkdir('example')
    os.chdir('example')
    cwd = os.getcwd()
    print '*** new working directory: '
    print cwd
    print '*** original directory listing: '
    print os.listdir(cwd)

    print '*** creating test file...'
    fobj = open('test', 'w')
    fobj.write('foo\n')
    fobj.write('bar\n')
    fobj.close()
    print '*** updated directory listing: '
    print os.listdir(cwd)

    print "*** renaming 'test' to 'filetest.txt' "
    os.rename('test', 'filetest.txt')
    print '*** updated directory listing: '
    print os.listdir(cwd)

    path = os.path.join(cwd, os.listdir(cwd)[0])
    print '*** full file pathname'
    print path
    print '*** (pathname, basename) =='
    print os.path.split(path)
    print '*** (filename, extension) =='
    print os.path.splitext(os.path.basename(path))

    print '*** displaying file contents: '
    fobj = open(path)
    for eachLine in fobj:
        print eachLine,
    fobj.close()

    print '*** deleting test file'
    os.remove(path)
    print '*** updated directory listing: '
    print os.listdir(cwd)
    os.chdir(os.pardir)
    print '***  deleting test directory'
    os.rmdir('example')
    print '*** DONE'

        在Linux操做系统执行以下:

xpleaf@leaf:~$ python ospathex.py 
*** current temporary directory
/tmp
*** creating example directory...
*** new working directory: 
/tmp/example
*** original directory listing: 
[]
*** creating test file...
*** updated directory listing: 
['test']
*** renaming 'test' to 'filetest.txt' 
*** updated directory listing: 
['filetest.txt']
*** full file pathname
/tmp/example/filetest.txt
*** (pathname, basename) ==
('/tmp/example', 'filetest.txt')
*** (filename, extension) ==
('filetest', '.txt')
*** displaying file contents: 
foo
bar
*** deleting test file
*** updated directory listing: 
[]
***  deleting test directory
*** DONE

        在Windows操做系统上执行以下:

C:\Users\xpleaf\Source_code>python ospathex.py
*** current temporary directory
c:\temp
*** creating example directory...
*** new working directory:
c:\temp\example
*** original directory listing:
[]
*** creating test file...
*** updated directory listing:
['test']
*** renaming 'test' to 'filetest.txt'
*** updated directory listing:
['filetest.txt']
*** full file pathname
c:\temp\example\filetest.txt
*** (pathname, basename) ==
('c:\\temp\\example', 'filetest.txt')
*** (filename, extension) ==
('filetest', '.txt')
*** displaying file contents:
foo
bar
*** deleting test file
*** updated directory listing:
[]
***  deleting test directory
*** DONE




8.文件执行


        关于如何启动其余程序,以及如何与它们进行通讯,或者是Python执行环境的通常信息,能够参考《Python回顾与整理12:执行环境》。




9.永久存储模块


        以二进制数据的形式来存储Python的复杂数据结构(如列表、字典等),主要是pickle和json,其它的在须要用到时查阅便可。




10.相关模块


        在须要使用时查阅便可。

相关文章
相关标签/搜索