文件IO

1、文件的打开方式

  • 文件路径说明

    相对路径:

    • 文件与python执行文件在同一个文件夹内(当前文件夹),就不用写路径,直接写文件名就好了,不在同个文件夹内都是要用绝对路径的。

    • 只要和运行路径拼接起来可以找到这个文件,那么就可以是用的相对路径。

    绝对路径:

    • 对文件进行右键单击,在属性里面就可以查看到文件的绝对路径了

  • 文件的mode

    • 如果没有写文件的mode,那么默认是 'r'

    • 如果使用 ‘w’, 'w+', 'a', 'a+' 的方式写入时,当文件不存在系统也会默认去新建文件后写入数据

    • 字符含义
      r
      w
      a 追加
      r+、 w+、a+ 读写
      rb 二进制读,不用encode/bytes,可以用来读图片
      wb 二进制写, 不用encode/bytes,可以用来写入图片
      ab 二进制追加,不用encode/bytes,可以用来写入图片
      rb+、wb+、ab+ 二进制读写,不用encode/bytes,可以用来读写图片

 

# open 用于打开一个文件,进行读写操作
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
file: 必需,文件路径(相对或者绝对路径)。
mode: 可选,文件打开模式,默认为 'r'
buffering: 设置缓冲
encoding: 一般使用utf8
errors: 报错级别
newline: 区分换行符
closefd: 传入的file参数类型
    
# 打开文件的方式一
fp = open('a.txt', encoding="utf8")
print(fp.read())
fp.close()

# 打开文件的方式二 这个方法不用写close()
with open('a.txt', encoding="utf8") as fp:
    print(fp.read())
    
# 打开文件的方式三 打开多个文件进行操作
with open('a.txt', encoding="utf8") as f,open('D:\\test_file\\b.txt', encoding="utf8") as f1:
    print(f.read())
    print(f1.read())

 

2、文件的读取方法

  .read() # 括号里面可以加数字,表示读的字数,可以跨行读

# read()方法是读取所有的数据,包括换行符,以字符串的形式展示出来

fp = open("a.txt", encding="utf8")
fp.read()

'read2\nread3\nread4\nread5\nread6\nread7\nread8\nread9\nread10\nread11\nread12\nread13\nread14\nread15\nread16\nread17\nread18\nread19\nread20\nread21\nread22\nread23\nread24\nread25\nread26\nread27\nread28\nread29\nread30\nread31\nread32\nread33\nread34\nread35\nread36\nread37\nread38\nread39\nread40\nread41\nread42\nread43\nread44\nread45\nread46\nread47\nread48\nread49\nread50\nread51\nread52\nread53\nread54\nread55\nread56\nread57\nread58\nread59\nread60\nread61\nread62\nread63\nread64\nread65\nread66\nread67\nread68\nread69\nread70\nread71\nread72\nread73\nread74\nread75\nread76\nread77\nread78\nread79\nread80\nread81\nread82\nread83\nread84\nread85\nread86\nread87\nread88\nread89\nread90\nread91\nread92\nread93\nread94\nread95\nread96\nread97\nread98\nread99\nread100\nhello python'

>>> fp.read(10)
'hello\nad1\n' # 读到10个字数为止,readline()的区别

  .readline() # # 括号里面可以加数字,表示读的字数,不跨行读

# 使用readline方法每次只读取一行数据,包括换行符

with open('a.txt', encoding="utf8") as f:
    print(f.readline())
    print(f.readline(1)) # 制度1个字符
D:\>py -3.5 test.py
hello world1
h
# 注意这里有两个换行:一个是文件自带的换行,一个是print函数自带的换行

>>> fp.readline(20)
'hello\n'  # 一行最多读20个字符,如果没有则自读到1行

  .readlines()

# 使用readlines方法一次性读取完所有数据,包括换行符,并以列表的形式返回,列表中的每个元素就是原文件的一行

with open('a.txt', encoding="utf8") as f:
    print(f.readlines())

D:\>py -3.5 test.py
['hello world1\n', 'read2\n', 'read3\n', 'read4\n', 'read5\n', 'read6\n', 'read7\n', 'read8\n', 'read9\n', 'read10\n', 'read11\n', 'read12\n', 'read13\n', 'read14\n', 'read15\n', 'read16\n', 'read17\n', 'read18\n', 'read19\n', 'read20\n', 'read21\n', 'read22\n', 'read23\n', 'read24\n', 'read25\n', 'read26\n', 'read27\n', 'read28\n', 'read29\n', 'read30\n', 'read31\n', 'read32\n', 'read33\n', 'read34\n', 'read35\n', 'read36\n', 'read37\n', 'read38\n', 'read39\n', 'read40\n', 'read41\n', 'read42\n', 'read43\n', 'read44\n', 'read45\n', 'read46\n', 'read47\n', 'read48\n', 'read49\n', 'read50\n', 'read51\n', 'read52\n', 'read53\n', 'read54\n', 'read55\n', 'read56\n', 'read57\n', 'read58\n', 'read59\n', 'read60\n', 'read61\n', 'read62\n', 'read63\n', 'read64\n', 'read65\n', 'read66\n', 'read67\n', 'read68\n', 'read69\n', 'read70\n', 'read71\n', 'read72\n', 'read73\n', 'read74\n', 'read75\n', 'read76\n', 'read77\n', 'read78\n', 'read79\n', 'read80\n', 'read81\n', 'read82\n', 'read83\n', 'read84\n', 'read85\n', 'read86\n', 'read87\n', 'read88\n', 'read89\n', 'read90\n', 'read91\n', 'read92\n', 'read93\n', 'read94\n', 'read95\n', 'read96\n', 'read97\n', 'read98\n', 'read99\n', 'read100\n', 'hello python']

  .writelines()

# 可以一次性写入多行,传的是一个列表
>>> with open('D:\\test\\a.txt', 'w') as f:
...     f.writelines(['gloryroad1\n', 'gloryroad2\n']) 
...
>>> fp = open('D:\\test\\a.txt', 'r')
>>> fp.read()
'gloryroad1\ngloryroad2\n'

  使用while读取

with open('a.txt', encoding='utf-8') as file_obj:
    line = file_obj.readline()
    while line != '':
        print(line)
        line = file_obj.readline()
        
gloyroad0

gloyroad1

gloyroad2

gloyroad3

gloyroad4

gloyroad5

gloyroad6

gloyroad7

gloyroad8

gloyroad9

hello world

  使用for循环迭代读取

# 和readline()的结果一样, 但实现的内部机制不一致
fp = open("a.txt", encoding="utf8")
for i in fp:
    print(i.strip())

D:\>py -3.5 test.py
hello world1
read2
read3
read4
read5
read6
read7
read8
.
.
.
read97
read98
read99
read100
hello python

  使用列表推导式来将文件的每一行都读取到列表中去

# 和readlines()的结果一致,但实现的内部机制不一致
content_list = [i.strip() for i in open('a.txt', encoding="utf8")]
print(content_list)

D:\>py -3.5 test.py
['hello world1', 'read2', 'read3', 'read4', 'read5', 'read6', 'read7', 'read8', 'read9', 'read10', 'read11', 'read12', 'read13', 'read14', 'read15', 'read16', 'read17', 'read18', 'read19', 'read20', 'read21', 'read22', 'read23', 'read24', 'read25', 'read26', 'read27', 'read28', 'read29', 'read30', 'read31', 'read32', 'read33', 'read34', 'read35', 'read36', 'read37', 'read38', 'read39', 'read40', 'read41', 'read42', 'read43', 'read44', 'read45', 'read46', 'read47', 'read48', 'read49', 'read50', 'read51', 'read52', 'read53', 'read54', 'read55', 'read56', 'read57', 'read58', 'read59', 'read60', 'read61', 'read62', 'read63', 'read64', 'read65', 'read66', 'read67', 'read68', 'read69', 'read70', 'read71', 'read72', 'read73', 'read74', 'read75', 'read76', 'read77', 'read78', 'read79', 'read80', 'read81', 'read82', 'read83', 'read84', 'read85', 'read86', 'read87', 'read88', 'read89', 'read90', 'read91', 'read92', 'read93', 'read94', 'read95', 'read96', 'read97', 'read98', 'read99', 'read100', 'hello python']

  备注:比较推荐的是使用for循环和列表推导式来读取,这样会更加节省资源,也更灵活

 

3、文件的写入方法

  .write() :只有 ‘r’ /‘rb’模式下不能使用,其他都可以

# 文件的写入方法只有这一个,需要注意的是有写模式的才能使用,否则会报错
with open('a.txt', 'r', encoding='utf8') as f:
    f.write('aa')
    

D:\>py -3.5 test.py
Traceback (most recent call last):
  File "test.py", line 2, in <module>
    f.write('aa')
io.UnsupportedOperation: not writable

  .writelines() :写入列表

list1 = ['asdasd\n', 'adasd\n']
with open('D:\\a.txt', 'w', encoding='utf-8') as f:
    f.writelines(list1)

  几个特殊模式,请注意

# 'w' 模式清空写入,默认都是写在一行,如果需要换行还需手动输入换行符'\n'
with open('a.txt', 'w+', encoding='utf8') as f:
    for i in range(10):
        f.write('gloyroad{}\n'.format(i))
  
gloyroad0
gloyroad1
gloyroad2
gloyroad3
gloyroad4
gloyroad5
gloyroad6
gloyroad7
gloyroad8
gloyroad9

# 'w+'是清空了读再写,所以一般读取到的都是空字符串
with open('a.txt', 'w+', encoding="utf8") as f:
    f.write('aaaaaaaaa')
    print('--------',f.read())
    
D:\>py -3.5 test.py
--------               # 读取到的是空字符串,但文件的内容是'aaaaaaaaa',是因为读的时候把游标位子还在                        # 末尾,所以需要使用f.seek(0,0)就能读到了

>>> with open('D:\\a.txt', 'w+', encoding="utf-8") as f:
...     f.write("光荣之路1\n")
...     f.write("光荣之路2\n")
...     f.write("光荣之路3\n")
...     f.seek(0,0)  # 重置游标位置就可以读到内容了
...     f.read()
...
6
6
6
0
'光荣之路1\n光荣之路2\n光荣之路3\n'

# 'r+'是去覆盖

with open('a.txt', 'r+', encoding="utf8") as f:
    f.write('bbb')
    print('--------',f.read())
    
D:\>py -3.5 test.py
-------- aaaaaa  # 读取到的是文件原始的数据, 文件的内容为'bbbaaaaaa'是覆盖了一部分



# 'r+'模式写入是写入到文件的第一行,并且覆盖文件的第一行相应的字符数
with open('a.txt', 'r+', encoding='utf8') as f:
    f.write('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
    
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaloyroad3
gloyroad4
gloyroad5
gloyroad6
gloyroad7
gloyroad8
gloyroad9

# 'a' 追加内容,默认是在文件的末尾追加
# 'a+'不删除原有的内容,在后面追加
with open('a.txt', 'a', encoding='utf8') as f:
    f.write('hello world')
   
gloyroad0
gloyroad1
gloyroad2
gloyroad3
gloyroad4
gloyroad5
gloyroad6
gloyroad7
gloyroad8
gloyroad9
hello world

 

4、文件的游标使用

  • 设置游标位置 fp.seek(0,0)

  • 获取游标 fp.tell()

  • 不管是读还是写都是从游标开始的,只是打开一个文件是游标默认是0而已,所有我们可以通过游标的控制读写的位置

# file.seek()方法标准格式是:seek(offset,[whence=0])

# offset:相对于whence的偏移量,字节数,可以为负数,whence省略时,默认从文件开头算起

# whence:给offset参数的偏移参考,表示要从哪个位置开始偏移;0代表从文件开头开始算起,1代表从当前位置开始,2代表从末尾开始读f.seek(-5,2)

# 1和2 是基于 'rb' 模式
with open('a.txt', 'r', encoding="utf8") as f:
    print(f.tell())
    print(f.readline())
    print(f.tell())
    f.seek(20) # 设置游标的位置,然后  read()会去读取游标后面的内容
    print(f.read())
    
D:\>py -3.5 test.py
0
gloyroad0

11  # 从1开始,包含了换行符

gloyroad2  # read()是读取游标后面的内容,注意这里为什么没有返回字符串,是因为我们用的print,他自动把
gloyroad3  # 换行符显示成换行且自带一个换行符,所以我们看到的时这个样子,最后面还会多出来一行
gloyroad4
gloyroad5
gloyroad6
gloyroad7
gloyroad8
gloyroad9
hello world

 

5、序列化:就是把变量存在文件里面,在下次就可以使用

# 序列化:在交互模式下生成一个变量,a=100, 退出程序后再进入,那么a就不见了,如果需要得到这个a,那么就要用序列# 化
# 就是把变量存在文件里面,在下次就可以使用

>>> a = 100
>>> fp.close()
>>>
>>> import pickle
>>> fp = open('D:\\test\\a.txt', 'wb')
>>> pickle.dump(a, fp)
>>> pickle.dump(b, fp)
>>> fp.close()
>>> ^Z

C:\Users\suyongai>py -3
Python 3.6.7 (v3.6.7:6ec5cf24b7, Oct 20 2018, 13:35:33) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.

>>> import pickle
>>> with open('D:\\test\\a.txt', 'rb') as f:
...     pickle.load(f)
...     pickle.load(f)
...
100
[1, 2, 3]

 

posted @ 2020-03-18 09:35  海澜时见鲸  阅读(166)  评论(0)    收藏  举报