温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Python 关于文件操作

发布时间:2020-09-14 15:24:46 来源:网络 阅读:309 作者:nineteens 栏目:编程语言

  文件操作

  初识文件操作

  使用python来读写文件是非常简单的操作,我们使用open()函数来打开某个文件,获取到文件句柄,然后通过文件句柄就可以进行各种各样的操作了。根据打开形式的不同能够执行的操作也会有相应的差异。操作文件的方式一般有如下:

  r, w, a, r+, w+, a+, rb, wb, ab, r+b, w+b, a+b

  默认使用的是r(只读)模式

  只读操作(r, rb)

  f = open("python", mode="r", encoding="utf-8")

  content = f.read()

  print(content)

  f.close()

  python.txt

  这是python文件

  运行结果:

  这是python文件

  Process finished with exit code 0

  需要注意encoding表示编码集,根据文件的实际保存编码进行获取数据,对于我们来说,使用更多的是utf-8。

  rb. 读取出来的数据是bytes类型,,在rb模式下,不能选择encoding字符集。

  f = open("python", mode="rb")

  content = f.read()

  print(content)

  f.close()

  python.txt

  这是python文件

  运行结果:

  b'\xe8\xbf\x99\xe6\x98\xafpython\xe6\x96\x87\xe4\xbb\xb6'

  Process finished with exit code 0

  rb的作用: 在读取非文本文件的时候. 比如读取MP3、图像、视频等信息的时候就需要用到rb。因为这种数据是没办法直接显示出来的. 在后面文件上传下载的时候还会用到。还有,我们看的直播,实际上都是这种数据。

  路径

  一般分为绝对路径和相对路径:

  1. 绝对路径:从磁盘根目录开始一直到文件名。

  2. 相对路径:同一个文件夹下的文件,相对于当前这个程序所在的文件夹而言,如果在同一个文件夹中。则相对路径就是这个文件名,如果在上一层文件夹,则要使用../表示上一层文件,如果在上多层文件夹中,则需要使用多次../。

  一般在开发过程中推荐大家使用相对路径。因为在我们把程序拷贝给别人使用的时候. 直接把整个项目文件拷贝出去就能运行,但是如果使用绝对路径,那还需要拷贝外部的文件。

  获取文件

  read()

  将文件中的内容全部读取出来。弊端:占内存。如果文件过大,容易导致内存崩溃,使用时应该小心谨慎。

  f = open("../FileOne/静夜思.txt", mode="r", encoding="utf-8")

  content = f.read()

  print(content)

  静夜思.txt

  床前明月光

  疑是地上霜

  举头望明月

  低头思故乡

  运行结果:

  床前明月光

  疑是地上霜

  举头望明月

  低头思故乡

  Process finished with exit code 0

  read(n)

  读取n个字符,需要注意的是,如果再次读取,那么会在当前位置继续去读而不是从头读,如果使用的是rb模式,则读取出来的是n个字节。

  f = open("../FileOne/静夜思.txt", mode="r", encoding="utf-8")

  content = f.read(4)

  contentOne = f.read(5)

  print(content)

  print(contentOne)

  静夜思.txt

  床前明月光

  疑是地上霜

  举头望明月

  低头思故乡

  运行结果:

  床前明月

  光

  疑是地

  Process finished with exit code 0

  值得注意的是,在这里换行符表示一个字节。前面4个字节,后面接着输出5个字节。

  f = open("../FileOne/静夜思.txt", mode="rb")

  content = f.read(4)

  contentOne = f.read(5)

  print(content)

  print(contentOne)

  静夜思.txt

  床前明月光

  疑是地上霜

  举头望明月

  低头思故乡

  运行结果:

  b'\xe5\xba\x8a\xe5'

  b'\x89\x8d\xe6\x98\x8e'

  Process finished with exit code 0

  readline()

  一次读取一行数据,注意:readline()结尾,注意每次读取出来的数据都会有一个\n 。所以呢,需要我们使用strip()方法来去掉\n或者空格,当然,我们也可以在print后面加上end=""去掉空格。

  f = open("../FileOne/静夜思.txt", mode="r", encoding="utf-8")

  contentOne = f.readline()

  contentTwo = f.readline()

  contentThree = f.readline()

  contentFour = f.readline()

  print(contentOne.strip())

  print(contentTwo.strip())

  print(contentThree, end="")

  print(contentFour, end="")

  静夜思.txt

  床前明月光

  疑是地上霜

  举头望明月

  低头思故乡

  运行结果:

  床前明月光

  疑是地上霜

  举头望明月

  低头思故乡

  Process finished with exit code 0

  readlines()

  将每一行形成一个元素,放到一个列表中,将所有的内容都读取出来,所以也是,容易出现内存崩溃的问题,一般不推荐不推荐使用。

  f = open("../FileOne/静夜思.txt", mode="r", encoding="utf-8")

  lst = f.readlines()

  print(lst)

  for line in lst:

  print(line.strip())

  静夜思.txt

  床前明月光

  疑是地上霜

  举头望明月

  低头思故乡

  ['床前明月光\n', '疑是地上霜\n', '举头望明月\n', '低头思故乡']

  床前明月光

  疑是地上霜

  举头望明月

  低头思故乡

  Process finished with exit code 0

  从列表里面我们可以看出,每次获取的行后面都会有换行符/n。因此,打印过程中我们应该使用strip()或者end = ()去掉换行。

  循环读取

  f = open("../FileOne/静夜思.txt", mode="r", encoding="utf-8")

  for line in f:

  print(line.strip())

  静夜思.txt

  床前明月光

  疑是地上霜

  举头望明月

  低头思故乡

  运行结果:

  床前明月光

  疑是地上霜

  举头望明月

  低头思故乡

  Process finished with exit code 0

  这种方式是事先就组好了,每次读取一行的内容,不会产生内存溢出的问题。

  注意:

  在每次读取完文件时,应该关闭文件句柄。f.closed()

  在执行操作过后可使用刷新机制对文件进行刷新。f.flush()

  写模式(r,rw)

  写的时候注意,如果没有文件,则会创建文件,如果文件存在,则将原件中原来的内容删除,再写入新内容。

  f = open("⼩娃娃", mode="w", encoding="utf-8")

  f.write("⾦⽑狮王")

  # f.read() # 尝试读取文件,此时只是写,抛出io.UnsupportedOperation: not readable

  f.flush() # 刷新. 养成好习惯

  f.close()

  创建了文件:小娃娃

  ⾦⽑狮王

  运行结果:

  Process finished with exit code 0

  本次文件写操作执行完毕后,程序结束,控制台没有输出值,只是在列表中创建了文件。

  f = open("⼩娃娃", mode="wb")

  f.write("⾦⽑狮王".encode("utf-8"))

  f.flush()

  f.close()

  创建文件:小娃娃

  ⾦⽑狮王

  运行结果:

  Process finished with exit code 0

  wb模式下,可以不指定文件的编码,但是在写文件的时候必须将字符串转换为utf-8的bytes数据,如果不转化,将会出现一下的错误。

  TypeError: a bytes-like object is required, not 'str'

  追加(a,ab)

  在追加模式下. 我们写入的内容会追加在文件的结尾.

  f = open("⼩娃娃", mode="a", encoding="utf-8")

  f.write("麻花藤的最爱")

  f.write("是小学生")

  f.flush()

  f.close()

  创建文件:小娃娃

  麻花藤的最爱是小学生

  运行结果:

  Process finished with exit code 0

  f = open("⼩娃娃", mode="ab")

  f.write("麻花藤的最爱".encode())

  f.write("是小学生".encode())

  f.flush()

  f.close()

  创建文件:小娃娃

  麻花藤的最爱是小学生

  运行结果:

  Process finished with exit code 0

  由于编译器默认的是utf-8,所以在小娃娃文件中显示的是未改变的字符。

  读写模式(r+,r+b)

  对于读写模式,必须是先读。因为默认光标是在开头的,准备读取的,当读完了之后再进行写入,我们以后使用频率最高的模式就是r+。

  f = open("⼩娃娃", mode="r+", encoding="utf-8")

  content = f.read()

  f.write("麻花藤的最爱")

  print(content)

  f.flush()

  f.close()

  运行前的文件:小娃娃

  麻花藤的最爱

  运行后的文件:小娃娃

  麻花藤的最爱麻花藤的最爱

  运行结果:

  麻花藤的最爱

  Process finished with exit code 0

  在正常的读取后,文件的写入在结尾。

  下面演示错误操作:

  f = open("⼩娃娃", mode="r+", encoding="utf-8")

  f.write("哈哈")

  content = f.read()

  print(content)

  f.flush()

  f.close()

  运行前的文件:小娃娃

  麻花藤的最爱

  运行后的文件:小娃娃

  哈哈藤的最爱

  运行结果:

  藤的最爱

  Process finished with exit code 0

  在没有任何操作之前,默认的光标在开头,当写入“哈哈”以后,“麻花”二字被覆盖,且光标往后移动了两个位置,默认读取从光标后开始读取。

  总结,在r+模式下,必须是先读取,再写入。

  写读(w+,w+b)

  先将所有的内容清空,然后写入,最后读取,但是读取的内容是空的,一般不常用。

  f = open("⼩娃娃", mode="w+", encoding="utf-8")

  f.write("哈哈")

  content = f.read()

  print(content)

  f.flush()

  f.close()

  运行前的文件:小娃娃

  麻花藤的最爱

  运行后的文件:小娃娃

  哈哈

  运行结果:

  Process finished with exit code 0

  那么可能有同学会问,先读不就好了么?

  错。理由:w+ 模式下, 一开始读取不到数据,然后写的时候再将原来的内容清空,所以这种操作方式很少用。

  追加读(a+)

  a+模式下,不论先读还是后读,都是读取不到数据的。

  f = open("⼩娃娃", mode="a+", encoding="utf-8")

  f.write("麻花藤")

  content = f.read()

  print(content)

  f.flush()

  f.close()

  运行前的文件:小娃娃

  爱笑的眼睛

  运行后的文件

  爱笑的眼睛麻花藤

  运行结果:

  Process finished with exit code 0

  还有一些其它带b的操作,就不多赘述了,就是把字符换成字节,仅此而已。

  其它相关操作

  seek(n)

  光标移动到n位置,注意,移动的单位是byte,所以如果是utf-8的中文部分要是3的倍数。

  通常我们使用seek都是移动到开头或者结尾。

  移动到开头:seek(0) 。郑州人流价格 http://www.zzzykdfk.com/

  移动到结尾:seek(0,2),seek的第一个参数表示的是从哪个位置进行偏移,默认是0,表示开头,1表示当前位置,2表示结尾。

  f = open("⼩娃娃", mode="r+", encoding="utf-8")

  f.seek(0) # 光标移动到开头

  content = f.read() # 读取内容, 此时光标移动到结尾

  print(content)

  f.seek(0) # 再次将光标移动到开头

  f.seek(0, 2) # 将光标移动到结尾

  content2 = f.read() # 读取内容. 什么都没有

  print(content2)

  f.seek(0) # 移动到开头

  f.write("张国荣") # 写⼊信息. 此时光标在9 中⽂3 * 3个 = 9

  f.flush()

  f.close()

  运行前的文件:小娃娃

  123456789

  运行后的文件:小娃娃

  张国荣

  运行结果:

  123456789

  Process finished with exit code 0

  tell()

  获取到当前光标位置。

  f = open("⼩娃娃", mode="r+", encoding="utf-8")

  f.seek(0) # 光标移动到开头

  content = f.read() # 读取内容, 此时光标移动到结尾

  print(content)

  f.seek(0) # 再次将光标移动到开头

  f.seek(0, 2) # 将光标移动到结尾

  content2 = f.read() # 读取内容. 什么都没有

  print(content2)

  f.seek(0) # 移动到开头

  f.write("张国荣") # 写⼊信息. 此时光标在9 中⽂3 * 3个 = 9

  print(f.tell()) # 光标位置9

  f.flush()

  f.close()

  运行前的文件:小娃娃

  123456789

  运行后的文件:小娃娃

  123456789

  9

  Process finished with exit code 0

  truncate()

  截断文件光标后的内容,日常操作过程中几乎不用。

  f = open("小娃娃", mode="w", encoding="utf-8")

  f.write("哈哈") # 写⼊两个字符

  f.seek(3) # 光标移动到3, 也就是两个字中间

  f.truncate() # 删掉光标后⾯的所有内容

  f.close()

  运行前的文件:小娃娃

  麻花藤最爱的人

  运行后的文件

  哈

  运行结果:

  Process finished with exit code 0

  深坑请注意:在r+模式下,如果读取了内容,不论读取内容多少,光标显示的是多少,再写入或者操作文件的时候都是在结尾进行的操作。

  所以如果想做截断操作,记住了,要先挪动光标,挪动到你想要截断的位置,然后再进行截断关于truncate(n), 如果给出了n. 则从开头开头进行截断,如果不给n,则从当前位置截断,后面的内容将会被删除。

  修改文件以及另一种打开文件的方式

  import os

  with open("⼩娃娃", mode="r", encoding="utf-8") as f1, \

  open("⼩娃娃_new", mode="w", encoding="UTF-8") as f2:

  content = f1.read()

  new_content = content.replace("冰糖葫芦", "⼤⽩梨")

  f2.write(new_content)

  os.remove("⼩娃娃") # 删除源⽂件

  os.rename("⼩娃娃_new", "⼩娃娃") # 重命名新⽂件

  弊端:一次将所有内容进行读取,导致内存溢出,解决⽅案: 一行一行的读取和操作。

  import os

  with open("⼩娃娃", mode="r", encoding="utf-8") as f1, \

  open("⼩娃娃_new", mode="w", encoding="UTF-8") as f2:

  for line in f1:

  new_line = line.replace("⼤⽩梨", "冰糖葫芦")

  f2.write(new_line)

  os.remove("⼩娃娃") # 删除源⽂件

  os.rename("⼩娃娃_new", "⼩娃娃") # 重命名新⽂件


向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI