文件操作相关知识

文本文件和二进制文件

  • 文本文件:可用文本编辑器查看
  • 二进制文件:保存的文件不可以直接查看,但是可以用专用软件查看,如视频、图片等。

    操作文件基本流程

  1. 打开文件
  2. 读写文件
    1. 读文件:将文件数据读入内存
    2. 写文件:将内存内容写入文件
  3. 关闭文件

    操作文件的函数/方法

    | 序号 | 函数 | 说明 | | —- | —- | —- | | 1 | open | 打开文件,返回文件操作对象 | | 2 | read | 将文件内容读入内存 | | 3 | write | 将指定内容写入文件 | | 4 | close | 关闭文件 |
  • open函数负责打开文件,并且返回文件对象
  • read/write/close三个方法都需要通过文件对象来调用。
  1. open函数:
    1. 第一个参数是文件名(区分大小写),第二个参数是打开方式;
    2. 如果文件存在返回文件操作对象
    3. 如果文件不存在抛出异常
  2. read函数:可以一次性读入并返回文件所有内容; ```python

    1. 打开 - 文件名需要注意大小写

    file = open(“README”)

2. 读取

text = file.read() print(text)

3. 关闭

file.close()

  1. <a name="xOiVj"></a>
  2. ### 文件打开方式
  3. > f = open("文件名","打开方式")
  4. | 访问方式 | 说明 |
  5. | --- | --- |
  6. | r | 以**只读**的方式打开文件。文件的指针会放在文件的开头,这是**默认模式**。如果文件不存在抛出异常 |
  7. | w | 以**只写**方式打开文件。如果文件存在会被覆盖。如果文件不存在,创建新文件 |
  8. | a | 以**追加**方式打开文件。如果该文件已存在,文件指针将会放在文件的结尾。如果文件不<br />存在,创建新文件进行写入 |
  9. | r+ | 以**读写**方式打开文件。文件的指针将会放在文件的开头。如果文件不存在,抛出异常 |
  10. | w+ | 以**读写**方式打开文件。如果文件存在会被覆盖。如果文件不存在,创建新文件 |
  11. | a+ | 以**读写**方式打开文件。如果该文件已存在,文件指针将会放在文件的结尾。如果文件不<br />存在,创建新文件进行写入 |
  12. 对于非文本文件,我们只能使用b模式,"b"表示以字节的方式操作(而所有文件也都是以字节的形式存<br />储的,使用这种模式无需考虑文本文件的字符编码、图片文件的jgp格式、视频文件的avi格式)
  13. - rb
  14. - wb
  15. - ab
  16. 注:
  17. - 以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型,不能指定编码
  18. - 频繁的移动文件指针,会影响文件的读写效率,开发中更多的时候会以 只读、只写 的方式来操作
  19. 文件
  20. <a name="ESUA2"></a>
  21. ### 按行读取文件内容
  22. - read方法一次性将文件所有内容读取到内存
  23. - readline方法可以一次读取一行内容,读完之后指针移动到下一行准备再次读取
  24. ```python
  25. # 方式一、通过循环按行读取文件所有内容
  26. file1 = open("README.txt")
  27. i = 1
  28. while True:
  29. text1 = file1.readline().strip()
  30. if text1:
  31. print("这是第%s行内容" % i)
  32. i += 1
  33. print(text1)
  34. else:
  35. break
  36. file1.close()
  37. # 方式二、通过for遍历按行读取文件所有内容
  38. file2 = open("README.txt")
  39. for i in file2.readlines():
  40. print(i.strip())
  41. file2.close()

with结构

在操作完毕文件后,一定要记住f.close(),推荐操作方式:使用with关键字来帮我们管理上下文。
用with结构打开的文件会在文件操作结束后自动关闭文件。

  1. with open("README.txt", "r") as read_f,open("README[BACKUP].txt", "w") as write_f:
  2. while True:
  3. text = read_f.readline()
  4. if not text:
  5. break
  6. write_f.write(text)
  7. print(text)
  8. with open("README.txt", "r") as read_f,open("README[BACKUP].txt", "w") as write_f:
  9. for i in read_f.readlines():
  10. write_f.write(i)
  11. print(i)

文件编码

f=open(…)是由操作系统打开文件,那么如果我们没有为open指定编码,那么打开文件的默认编码很明
显是操作系统说了算了,操作系统会用自己的默认编码去打开文件,在windows下是gbk,在linux下是
utf-8。

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

文件操作方法

  1. def close(self, *args, **kwargs): # real signature unknown
  2. 关闭文件
  3. pass
  4. def fileno(self, *args, **kwargs): # real signature unknown
  5. 文件描述符
  6. pass
  7. def flush(self, *args, **kwargs): # real signature unknown
  8. 刷新文件内部缓冲区
  9. pass
  10. def isatty(self, *args, **kwargs): # real signature unknown
  11. 判断文件是否是同意tty设备
  12. pass
  13. def read(self, *args, **kwargs): # real signature unknown
  14. 读取指定字节数据
  15. pass
  16. def readable(self, *args, **kwargs): # real signature unknown
  17. 是否可读
  18. pass
  19. def readline(self, *args, **kwargs): # real signature unknown
  20. 仅读取一行数据
  21. pass
  22. def seek(self, *args, **kwargs): # real signature unknown
  23. 指定文件中指针位置
  24. pass
  25. def seekable(self, *args, **kwargs): # real signature unknown
  26. 指针是否可操作
  27. pass
  28. def tell(self, *args, **kwargs): # real signature unknown
  29. 获取指针位置
  30. pass
  31. def truncate(self, *args, **kwargs): # real signature unknown
  32. 截断数据,仅保留指定之前数据
  33. pass
  34. def writable(self, *args, **kwargs): # real signature unknown
  35. 是否可写
  36. pass
  37. def write(self, *args, **kwargs): # real signature unknown
  38. 写内容
  39. pass
  40. def __getstate__(self, *args, **kwargs): # real signature unknown
  41. pass
  42. def __init__(self, *args, **kwargs): # real signature unknown
  43. pass
  44. @staticmethod # known case of __new__
  45. def __new__(*args, **kwargs): # real signature unknown
  46. """ Create and return a new object. See help(type) for accurate signature.
  47. """
  48. pass
  49. def __next__(self, *args, **kwargs): # real signature unknown
  50. """ Implement next(self). """
  51. pass
  52. def __repr__(self, *args, **kwargs): # real signature unknown
  53. """ Return repr(self). """
  54. pass

案例一:文件的修改

  1. 文件的数据是存放在硬盘上的,因此只存在覆盖、不存在修改的说法,我们平时修改文件看到的都是模拟出来的效果,具体有两种实现方法:
  1. 将文件全部读入到内存,内存是可以修改的,将内存里修改好的文件覆盖到硬盘上的原文件。

    1. import os
    2. with open('a.txt') as read_f,open('a.txt.new','w') as write_f:
    3. data = read_f.read()
    4. data = data.replace('Hello','nihao')
    5. write_f.write(data)
    6. os.remove('a.txt')
    7. os.rename('a.txt.new','a.txt')
  2. 将文件一行一行读入到内存,修改好后,覆盖原文件

    1. import os
    2. with open('a.txt') as read_f,open('a.txt.new','w') as write_f:
    3. for line in read_f:
    4. line = line.replace('nihao','Hello')
    5. write_f.write(line)
    6. os.remove('a.txt')
    7. os.rename('a.txt.new','a.txt')

    案例二:文件的复制

    ```python with open(“README.txt”, “r”) as read_f,open(“README[BACKUP].txt”, “w”) as write_f: while True:

    1. text = read_f.readline()
    2. if not text:
    3. break
    4. write_f.write(text)
    5. print(text)

with open(“README.txt”, “r”) as read_f,open(“README[BACKUP].txt”, “w”) as write_f: for i in read_f.readlines(): write_f.write(i) print(i)

———————————————————————————————————————-

小文件复制

file1 = open(“README”, “r”) file2 = open(“README[复件]”, “w”) text = file1.read() file2.write(text) file1.close() file2.close()

———————————————————————————————————————-

大文件复制

file3 = open(“README”, “r”) file4 = open(“README[大文件复制]”, “w”) while True: text = file3.readline() if not text: break file4.write(text) file3.close() file4.close()

  1. <a name="IOp6i"></a>
  2. # 案例三:计算总价
  3. 文件a.txt内容:每一行内容分别为商品名字,价钱,个数。<br />apple 10 3<br />tesla 100000 1<br />mac 3000 2<br />lenovo 30000 3<br />chicken 10 3<br />通过代码,将其构建成这种数据类型:[{'name':'apple','price':10,'amount':3},<br />{'name':'tesla','price':1000000,'amount':1}......] 并计算出总价钱。
  4. ```python
  5. list1 = []
  6. with open("a.txt", "r", encoding="utf-8") as file:
  7. for line in file.readlines():
  8. text = line.strip().split(" ")
  9. dict1 = {"name": text[0], "price": text[1], "amount": text[2]}
  10. list1.append(dict1)
  11. pass
  12. print(list1)
  13. price = 0
  14. for i in list1:
  15. price += int(i["price"]) * int(i["amount"])
  16. pass
  17. print(price)