输出:

    1. Python

    标示符’r’表示读。

    如果打开的文件不存在,会直接报错:

    1. Traceback (most recent call last):
    2. File "/Projects/python/code/file.py", line 3, in <module>
    3. f = open('test.txt1', 'r')
    4. IOError: [Errno 2] No such file or directory: 'test.txt1'

    报错后,后面的f.close()不会调用。一般我们会使用try ... finally来操作文件:

    1. try:
    2. f = open('test.txt', 'r')
    3. print(f.read())
    4. finally:
    5. if f:
    6. f.close()

    但是每次都这么写还是太繁琐,所以,Python引入了with语句来自动帮我们调用close()方法:

    1. with open('test.txt', 'r') as f:
    2. print(f.read())

    这和前面的try ... finally是一样的,但是代码更佳简洁,并且不必调用f.close()方法。

    如果文件很大,使用read()方法一下子读到内存,内存会占满。保险起见,可以反复调用read(size)方法,每次最多读取size个字节的内容。

    另外,调用readline()可以每次读取一行内容,调用readlines()一次读取所有内容并按行返回list:

    1. with open('test.txt', 'r') as f:
    2. for line in f.readlines():
    3. print(line)

    打开二进制文件

    要读取二进制文件(例如图片、音频、视频)内容,使用rb模式打开:

    1. >>> f = open('test.jpg', 'rb')
    2. >>> f.read()
    3. b'\xff\xd8\xff\xe1\x00\x18Exif\x00\x00...' # 十六进制表示的字节

    读取非utf-8编码的文本

    如果要读取非utf-8编码的文本,需要给open()传入编码参数encoding,默认是utf-8:

    1. >>> f = open('gbk.txt', 'r', encoding = 'gbk')
    2. >>> f.read()
    3. '测试GBK'

    如果不传入,读取的内容是乱码的。

    open()还支持第4个参数errors,用于当读取的内容编码不规范(会返回UnicodeDecodeError错误),示例:

    1. >>> f = open('gbk.txt', 'r', encoding = 'gbk', errors='ignore')

    这样将忽略错误。

    读取大文件方法

    方法一:将文件切分成小段,每次处理完小段,释放内存

    1. def read_in_block(file_path):
    2.   BLOCK_SIZE=1024
    3.   with open(file_path,"r") as f:
    4.     while True:
    5.       block =f.read(BLOCK_SIZE) #每次读取固定长度到内存缓冲区
    6.       if block:
    7.       else:
    8.         return #如果读取到文件末尾,则退出
    9.   print block

    这个方法,速度很快,但有个问题,若满足了1024时,会将正好在1024位置的数据切开。

    方法二:利用open()方法生成的迭代对象:

    1. with open(file_path) as f:
    2. for line in f:
    3. print line

    这种用法是把文件对象f当作迭代对象,系统将自动处理IO缓存和内存管理。

    耗时较第1种方法慢一点。 但每个Line, type都是str, 都是自己需要的一行数据(一行是一个id)。

    文件打开模式

    open()函数返回的这种有个read()方法的对象,在Python中统称为file-like Object。除了file外,还可以是内存的字节流,网络流,自定义流等等。file-like Object不要求从特定类继承,只要写个read()方法就行。

    StringIO就是在内存中创建的file-like Object,常用作临时缓冲。

    StringIO

    StringIO就是在内存中读写str。

    读取:

    1. # coding : utf-8
    2. from io import StringIO
    3. with StringIO('hello\nworld\n') as f:
    4. while True:
    5. s = f.readline()
    6. if s == '':
    7. break
    8. print(s.strip())

    输出:

    1. hello
    2. world

    写入:

    1. from io import StringIO
    2. with StringIO() as f:
    3. f.write('hello\nworld\n')
    4. print(f.getvalue())

    输出:

    1. hello
    2. world

    getvalue()方法用于获得写入后的str。

    BytesIO

    BytesIO就是在内存中读写二进制数据。

    1. # coding:utf-8
    2. from io import BytesIO
    3. with BytesIO() as f:
    4. f.write('测试Bytes'.encode('utf-8'))
    5. print(f.getvalue())

    输出:

    1. b'\xe6\xb5\x8b\xe8\xaf\x95'

    注意这里写入的是经过UTF-8编码的bytes。

    读取:

    输出:

    1. b'\xe6\xb5\x8b\xe8\xaf\x95'

    StringIOBytesIO是在内存中操作str和bytes的方法,使得和读写文件具有一致的接口。

    Python内置的os模块可以直接调用操作系统提供的接口函数来操作文件和目录。

    1. >>> import os
    2. >>> os.name
    3. 'nt'
    4. >>> os.environ
    5. environ({'PATHEXT': '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.wlua;.lexe;.PY', ...})

    要获取某个环境变量的值,可以调用os.environ.get('key')
    unix操作系统提供os.uname()来获取详细的系统信息。

    1. >>> import os
    2. >>> os.path.abspath('.')
    3. '/Projects/python/code'
    4. # 把两个路径合成一个时,不要直接拼字符串,而要通过os.path.join()函数,这样可以正确处理不同操作系统的路径分隔符:
    5. >>> os.path.join('/Projects', 'python')
    6. '/Projects/python'
    7. # 把一个路径拆分为两部分,后一部分总是最后级别的目录或文件名:
    8. >>> os.path.split('/Projects/python/code/os.py')
    9. ('/Projects/python/code', 'os.py')
    10. >>> os.path.split('/Projects/python/code/')
    11. ('/Projects/python/code', '')
    12. >>> os.path.split('/Projects/python/code')
    13. ('/Projects/python', 'code')
    14. # 获取文件扩展名:
    15. >>> os.path.splitext('/Projects/python/code/os.py')
    16. ('/Projects/python/code/os', '.py')
    17. # 然后创建一个目录:
    18. >>> os.mkdir('/Projects/python/code/testdir')
    19. # 删掉一个目录:
    20. >>> os.rmdir('/Projects/python/code/testdir')
    21. # 对文件重命名:
    22. >>> os.rename('test.txt', 'test.py')
    23. # 删掉文件:
    24. >>> os.remove('test.py')

    os模块中并没有复制文件的方法。原因是复制文件并非由操作系统提供的系统调用。

    幸运的是shutil模块提供了copyfile()的函数,我们还可以在shutil模块中找到很多实用函数,它们可以看做是os模块的补充。

    1. # coding : utf-8
    2. import shutil
    3. shutil.copyfile('os.py', 'os2.py')
    1. # coding : utf-8
    2. import os
    3. dirs = os.listdir('.')
    4. L = []
    5. for d in dirs:
    6. if os.path.isdir(d):
    7. L.append(d)
    8. print(L)

    输出:

    1. ['.idea', 'class', 'module']

    当然,利用Python的列表生成式,可以很简单:

    1. L = [x for x in os.listdir('.') if os.path.isdir(x)]
    2. print(L)

    要列出所有的.py文件:

    输出:

    参考:
    1、python 如何读取大文件 - guohuino2 - 博客园
    http://www.cnblogs.com/guohuino2/p/6043196.html