python 文件操作

  open函数使用一个文件名作为唯一的强制参数,然后返回一个文件对象。

一 r 模式与 rb 模式的区别

  r 模式,需要指定编码,windows下默认是gbk编码。rb模式直接读取二进制,与编码没有关系,加上就报错。

with open('1.txt','rb') as f:
    data=f.read()
    print(data,type(data))

  输出:

b'\xe4\xbc\x98\xe9\x85\xb7\n' <class 'bytes'>

  

  如果在 rb模式下,强行加上encoding,报错。

with open('1.txt',encoding='utf-8',mode='rb') as f:
    data=f.read()
    print(data,type(data))

  报错信息:

ValueError: binary mode doesn't take an encoding argument

  

  一般情况下要指定encoding,windows下默认是gbk,如果保存的时候是gbk,不加上encoding是可以的。

  以下代码是在windows下运行。

with open('1.txt','r') as f:
    data=f.read()
    print(data,type(data))

  输出:

优酷
 <class 'str'>

  因为文件1.txt,我是以gbk编码格式保存的。

 

二  w 模式与 wb 模式

  与 r 模式 和 rb 模式类似,b指的就是bytes类,所以采用 wb模式,写入的必须是bytes格式。同样不要指定encoding,否则会报错!

with open('1.txt',encoding='utf-8',mode='wb') as f:
    f.write('中国'.encode(encoding='utf-8'))

  报错信息:

ValueError: binary mode doesn't take an encoding argument

  

  更改如下:

with open('1.txt',mode='wb') as f:
    f.write('中国'.encode(encoding='utf-8'))

  没有报错,正常写入。b 模式下,一定要写入bytes格式!!!!

  总结: b 模式下,一定要注意,不要写encoding模式,一定不要!!!!!

  

  

三 文件方法:  

  '+'参数可以用到其他任何模式中,指明读和写都是允许的。

  b 模式一般是用于声音剪辑或者图像,原理比较复杂。

  1 f.read() 可以传整数格式的参数,在不同模式下,整数的含义并不一样。

  在 r 模式下,代表的是一个字符。因为我在1.txt中写的是汉字,所以输出结果是3.,代表3个字节。如果文件中是数字或者字母,返回的则是 1 。

with open('1.txt',encoding='utf-8',mode='r+') as f:
    f.read(1)
    print(f.tell())

  输出:3

  

  在 rb 模式下,代表的是一个字节,所以不管是一个汉字还是数字还是字母,返回的都是 1 。

with open('1.txt',mode='rb+') as f:
    f.read(1)
    print(f.tell())

  输出:1

 

  2  seek方法:

  Change the stream position to the given byte offset。

  指定指针位置,两个参数,第一个参数表示移动的    字节数,特别强调,是字节数。 。 第二个参数。0代表从文件开始位置,1 代表从文件当前位置,2 代表从文件末尾,可以省略,默认是0

Move to new file position and return the file position.
        
        Argument offset is a byte count.  Optional argument whence defaults to
        SEEK_SET or 0 (offset from start of file, offset should be >= 0); other values
        are SEEK_CUR or 1 (move relative to current position, positive or negative),
        and SEEK_END or 2 (move relative to end of file, usually negative, although
        many platforms allow seeking beyond the end of a file).
        
        Note that not all file objects are seekable

  seek方法的应用:

f=open('1.txt',mode='r+',encoding='utf-8')
f.write('dsdfdfsd')
# f.seek(0)
a=f.read()
f.close()
print(a)

  在注释掉f.seek()后,输出 空。

  注意:

  当文件是以 r 模式打开时,seek方法只支持第二个参数为 0,强行从当前位置,或者末尾位置会报错。

  只有文件以 b 模式打开,seek方法才允许 偏移位置从当前位置(参数为1)或者从末尾位置(参数为2)开始。

  举例:

f=open('1.txt',mode='r+',encoding='utf-8')

f.seek(-6,2)
print(f.tell())

f.truncate()
f.close()

  会报错:

io.UnsupportedOperation: can't do nonzero end-relative seeks

  

  换成 b 模式就可以了。 

f=open('1.txt',mode='rb+')

f.seek(-6,2)
print(f.tell())

f.truncate()
f.close()

  正常运行

  

f=open('1.txt',mode='r+',encoding='utf-8')
f.write('hello world')
f.seek(0)
a=f.read()
f.close()
print(a)

  f.seek()没被注释的情况下,输出‘hello world’。

  输出:

hello world

  总结:

  f.write()调用后,光标移到了white所写的内容末尾。

  f.read()是从光标开始的位置开始读取。

  要有这两个概念,所以上述两个例子,就说明了这个问题,也把seek方法的作用展示出来了。

  

  3 truncate方法:用于截断文件,如果指定了可选参数 size,则表示截断文件为 size 个字符,指的是从文件开头截取size字节大小的字符串,注意是字节大小,其余的都删掉,这种情况下,不会考虑光标在什么位置。 如果没有指定 size,则从当前光标位置起截断,光标后面的字符串都被删掉。

 

四  重中之重!

with open('1.txt',encoding='utf-8',mode='r+') as f:
    for line in f:                                  #非常经常的会遇到,会使用到。
        print(line)

  

l=[]
from collections import Iterable
with open('1.txt',encoding='utf-8',mode='r+') as f:           #文件句柄 f 是可迭代对象,单论这一点和列表,字符串,字典,元组没什么区别。所以可以 for line in f:line取到的是字符串格式。
    print(f,type(f))
    print(isinstance(f,Iterable))
    print(isinstance(l,Iterable))

  

五 类文件

  类文件对象是支持一些file类方法的对象,最重要的是支持read方法或者write方法。类文件对象,有时成为 流。

  比如sys模块中的  sys,stdin   sys.stdout     sys.stderr

 

  1  关于 f 的说明

f=open('1.txt','w',encoding='utf-8')
f.write('123')
f.close()
print(f)
f.read()

  输出:

<_io.TextIOWrapper name='1.txt' mode='w' encoding='utf-8'>
Traceback (most recent call last):
  File "D:/Program Files/JetBrains/s7/day29/client1.py", line 23, in <module>
    f.read()
ValueError: I/O operation on closed file.

  解释器打开文件,解释器内存中存执 f ,这个就是一个单纯的变量名。

  打开的文件是在计算机内存中,文件的打开与关闭涉及到硬件底层,这是由操作系统来干的,不可能有解释器执行。打开的文件是在计算机内存中。f.close()是系统调用,告诉操作系统这个文件已经没用的,可以关闭了。

  但 f 这个变量名还是在python解释器的内存中。不过,此时,再用 f 去调用 read 方法,就会报错,因为在内存中的文件已经没有了。

  2  关于f=open(filename,encoding='utf-8')

  为什么指定encoding,因为 f =open ,只是有python提出系统调用,但真正执行打开操作的是操作系统。所以encoding是给操作系统设定的。一句话,open,send,close,是系统调用,真正执行时操作系统,因为涉及到底层硬件。

posted @ 2017-08-24 14:12  骑者赶路  阅读(2665)  评论(0编辑  收藏  举报