文件模块 - baibing0716/python GitHub Wiki

一. 文件模块

1.1 字节类型和字符串类型区分

String类型:表示文本信息,本质是Unicode编码中二进制类型【只可以存储文本】

bytes类型:既可以表示文本信息,也可以表示二进制类型; 本质是Utf-8/GBK等二进制类型【可用存储图片、视频等】

------------------------------------------------------
name = "Eric"

data = name.encode("utf-8")                    # 将name进行加码

print(data)                                    # 输出 b'Eric'(方便存储、网络传输)

res = data.decode("utf-8")                     # 将data进行解码 

print(data)                                    # Eric
------------------------------------------------------

##  r模式  文件不存在 报错
##  w模式  文件不存在会创建,文件存在,每次写文件,文件内容会被清空 

1.2 读文件

--------------------------------------------------------读文本文件----------------------------------------------------------------
file_obj = open("读.txt", mode="rb")                   # 路径:绝对路径、相对路径都可用  rb 只读以二进制的方式

# 获取文件内容
file_content = file_obj.read()

# 关闭文件
file_obj.close()

# 将二进制的文件内容转换为utf-8格式                  
res = file_content.decode("utf-8")                    # 不执行此行 print(file_content) b'1 Eric\r\n2 Lily\r\n3 Honey' 就是二进制的格式

print(res)

输出结果:
1 Eric
2 Lily
3 Honey                                            
--------------------------------------------------------读文本文件----------------------------------------------------------------
----------------------------------------------------------读图片------------------------------------------------------------------
file_obj = open(r"D:\python教程\mv.png", mode="rb")

file_content = file_obj.read()

file_obj.close()

print(file_content)                              # 输出 b'RIFFlV\x00\x00WEBPVP8 `V\x00\x00p\x92\x01\x9d\x01*j\x01...... 就是像素点的内容
----------------------------------------------------------读图片------------------------------------------------------------------
读文本文件快速方式 
file_obj = open("读.txt", mode="rt", encoding="utf-8")      # 在 file_content = file_obj.read()后不需要decode解码 直接可以输出文本文件

路径: 采取r“路径” 不然会要对\进行转义

判断路径是否存在:  exists = os.path.exists("路径")           # 返回的是bool类型值

                  filepath = "路径"
                  if os.path.exists(filepath):
                      # 执行体
                  else
                      print("文件不存在")

1.3 写文件

--------------------------------------------------------写文本文件----------------------------------------------------------------
file_obj = open("写.txt", "wb")                           # 写的方式是wb 即二进制的方式写进去
file_obj.write("1 - Eric".encode("utf-8"))                # 写的内容将其加码为 utf-8格式
file_obj.close()

写文本最好方式:
file_obj = open("写.txt", "wt", encode="utf-8")
--------------------------------------------------------写文本文件----------------------------------------------------------------
--------------------------------------------------------写图片文件----------------------------------------------------------------
# 复制图片
filepath = r"D:\python教程\1.webp"
if os.path.exists(filepath):
    f1 = open(filepath, "rb")
    f1content = f1.read()                                  # 以二进制的方式打开并读取一张文件内容保存到f1content 对象中
    f1.close()

    f2 = open(r"D:\python教程\mv2.png", "wb")
    f2content = f2.write(f1content)                        # 以二进制的方式打开并将第一张图片的内容写入到mv2.png文件中
    f2.close()
else:
    print("{} is not exist", filepath)
--------------------------------------------------------写图片文件----------------------------------------------------------------

二、写文件范例

2.1 多用户的登录信息保存在一个文件中

import os
while True:
    # 登录注册 用户保存
    username = input("请输入用户名: ")
    if username.upper() == 'Q':
        break
    password = input("请输入密码: ")

    # 判断文件夹是否存在
    data = "{}-{}\n".format(username, password)
    file_obj = open(r"./file/1.txt", "wt", encoding="utf-8")
    file_obj.write(data)
    file_obj.close()

存在的问题:
    (1)文件内容只能保留最后一次输入的 username 和 password         原因: w方式写入 会先将原文件内容清空,再写入
    (2)如果file这个文件夹不存在会报错                             原因: w方式写入文件,文件本身不存在会创建但文件夹不存在,则不会创建

解决方式:(1) file_obj = open(r"./file/1.txt", "wt", encoding="utf-8")    # 仅打开文件一次
               while True:
                   # 执行体不变
               file_obj.close()                                            # 仅关闭文件一次

         (2) flag = os.path.exists(r"./file/")                           # 判断文件夹是否存在
              if flag:
                  file_obj = open(r"./file/1.txt", "wt", encoding="utf-8")
                  while True:
                      # 执行体不变
                  file_obj.close()
              else:                                                        # 不存在则不会创建
                  print("path %s is not exist"%r"./file/")

2.2 从网上下载文本,并将文本信息写入本地文件

import requests

response = requests.get(
    url="https://baijiahao.baidu.com/s?id=1782123254571501279",
    headers= {
        "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36 QIHU 360SE"
    }
)
# 输出响应内容
file_obj = open(r"./file/2.log", "wb")
file_obj.write(response.content)                # 把网页内容写入到2.log文件中
file_obj.close()

2.3 从网上下载图片,并将图片保存到本地文件

import requests

response = requests.get(
    url="https://img2.baidu.com/it/u=2416149911,70500032&fm=253&fmt=auto&app=138&f=JPEG?w=362&h=500",
    headers= {
        "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36 QIHU 360SE"
    }
)
# 输出响应内容
file_obj = open(r"./file/美女.png", "wb")
file_obj.write(response.content)
file_obj.close()

# 同上面的对比而言 就是url地址的更换 视频、图片等内容都是一致的

三、读写的扩展

3.1 读的扩展

----------------------------------------------------------------------------------------
// 读取单个字符
file_obj = open(r"./file/1.txt", "r", encoding="utf-8")              # 打开方式 默认其实为 rt模式
ch = file_obj.read(1)                                                # 读取一个字符串
print(ch)
ch1 = file_obj.read(2)                                               # 接着读取两个个字符串 (文件指针会后移)
print(ch1)
----------------------------------------------------------------------------------------
// 读取单个字节
file_obj = open(r"./file/1.txt", "rb")                               # 打开方式指定了 rb模式 读出的就是单个字节
byte = file_obj.read(1)                                              # 汉字默认是三个字节构成 读取第一个字节
print(byte)
byte1 = file_obj.read(2)                                             # 读取后两个字节
print(byte1)
----------------------------------------------------------------------------------------
// 读取一行
file_obj = open(r"./file/1.txt", "r", encoding="utf-8")
line = file_obj.readline()                                           # 读取单行 返回的line是string类型
print(line)
----------------------------------------------------------------------------------------
// 读取多行
file_obj = open(r"./file/1.txt", "r", encoding="utf-8")
datalist = file_obj.readlines()                                      # 读取文件的所有行,返回的是一个List类型
print(datalist)
----------------------------------------------------------------------------------------
// 通常读取大文件方式
file_obj = open(r"./file/1.txt", "r", encoding="utf-8")
for line in file_obj:
    print(line.strip())                                              # 循环读取文件每一行 去除每行结尾的\n和每行字符串前后空格 
file_obj.close()

3.2 写的扩展

写时写到缓冲区: 
file_obj.flush()                                                     # 写完之后从缓冲区刷到磁盘
file_obj.seek(3)                                                     # 移动文件指针到特点位置(按字节移动)
file_obj.tell()                                                      # 获取文件指针的位置

四、with文件上下文管理(不需要再主动调用close函数)

通常文件操作:
     file_obj = open()
     # 执行体
     file_obj.close()                                                # 不close会有内存泄漏

通过with实现文件的上下文管理:                                         # 不需要close 当with语句结束会自动close

# 打开单个文件
     with open("xxx.txt", "rb") as file_obj:
         data = file_obj.read()
         print(data)

# 打开多个文件     
     with open("xxx.txt", "rb") as file_obj1, open("xxx.txt", "rb") as file_obj2:
         pass