欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Day_08 万恶之源-文件操作

程序员文章站 2023-08-22 23:04:43
一. 昨日内容回顾 1. join() 可以把列表变成字符串 split() 把字符串变成列表 2. 删除的问题. list和dict在循环迭代的时候不要改变大小. 把要删除的内容记录在新列表中. 循环新列表. 删除目标列表 3. dict.fromkeys() 返回给你新字典 4. set集合. ......

一. 昨日内容回顾
  1. join() 可以把列表变成字符串 split() 把字符串变成列表
  2. 删除的问题.
    list和dict在循环迭代的时候不要改变大小.
    把要删除的内容记录在新列表中. 循环新列表. 删除目标列表
  3. dict.fromkeys() 返回给你新字典
  4. set集合. 不重复. 无序. 不可哈希. 内部必须是可哈希的.
  5. frozenset 冻结集合. 不可变的. 可哈希的
  6. 深浅拷贝
    1. = 不会产生新对象. 两个变量指向的是同一个对象
    2. 浅拷贝. 只拷贝第一层. 创建新对象
    3. 深拷贝. 把这个对象完全的进行拷贝. 创建出全新的对象

三. 今日主要内容
  文件操作:
    1. r  读

        f = open("文件.txt",mode="r", encoding="utf-8")
        content = f.read()  读取文件
        print(content)
        f.close()  关闭文件
          需要注意:  encoding表示编码集. 根据文件的实际保存编码进行获取数据, 对于我们而言. 更多的是utf-8.

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

            

          rb的作用: 在读取非文本文件的时候. 比如读取MP3. 图像. 视频等信息的时候就需要用到
          rb. 因为这种数据是没办法直接显⽰示出来的. 在后面我们文件上传下载的时候还会用到. 还有.
          我们看的直播. 实际上都是这种数据.
          绝对路路径和相对路路径:
          1. 绝对路路径:从磁盘根目录开始一直到文件名.

                Day_08    万恶之源-文件操作
          2. 相对路路径:同一个文件夹下的文件. 相对于当前这个程序所在的文件夹而言. 如果在同
          一个文件夹中. 则相对路路径就是这个文件名. 如果在上一层文件夹. 则要用   ../
          我们更更推荐大家使用相对路路径. 因为在我们把程序拷贝给别人使用的时候. 直接把项目拷贝走

          就能运行. 但是如果用绝对路路径. 那还需要拷贝外部的文件.

          

            我们更推荐大家使用相对路径. 因为在我们把程序拷贝给别人使用的时候. 直接把项目拷贝走
          就能运行. 但是如果用绝对路径. 那还需要拷贝外部的文件.


    2. w  写

        

 写模式(w, wb)
写的时候注意. 如果没有文件. 则会创建文件, 如果文件存在. 则将原件中原来的内容删除, 再
写入新内容
f = open("小娃娃", mode="w", encoding="utf-8")
f.write("金毛狮王")
f.flush() # 刷新. 养成好习惯
f.close()
尝试读一读
f = open("小娃娃", mode="w", encoding="utf-8")
f.write("金金毛狮王")
f.read() # not readable 模式是w. 不可以执行读操作
f.flush()
f.close()
wb模式下. 可以不指定打开文件的编码. 但是在写文件的时候必须将字符串串转化成utf-8的
bytes数据
f = open("小娃娃", mode="wb")
f.write("金毛狮王".encode("utf-8"))
f.flush()
f.close()


    3. a  追加

追加(a, ab)
在追加模式下. 我们写入的内容会追加在文件的结尾.
f = open("小娃娃", mode="a", encoding="utf-8")
f.write("麻花藤的最爱")
f.flush()
f.close()


    4. r+  读写

追加(a, ab)
在追加模式下. 我们写入的内容会追加在文件的结尾.
f = open("小娃娃", mode="a", encoding="utf-8")
f.write("麻花藤的最爱")
f.flush()
f.close()


    读写模式.
      需要移动光标进行反复读写
    5. w+  写读

写读(w+, w+b)
先将所有的内容清空. 然后写入. 最后读取. 但是读取的内容是空的, 不常⽤用
f = open("小娃娃", mode="w+", encoding="utf-8")
f.write("哈哈")
content = f.read()
print(content)
f.flush()
f.close()
有人会说. 先读不就好了么? 错. w+ 模式下, 一开始读取不到数据. 然后写的时候再将原来
的内容清空. 所以, 很少用.


    6. a+  写读(追加并进行度)

追加读(a+)
a+模式下, 不论先读还是后读. 都是读取不到数据的.
f = open("小娃娃", mode="a+", encoding="utf-8")
f.write("马化腾")
content = f.read()
print(content)
f.flush()
f.close()
还有一些其他的带b的操作. 就不多赘述了. 就是把字符换成字节. 仅此而已


    7. b bytes 读写操作的是字节. 用在非文本上
    8. seek() 移动光标到xx位置
     开头: seek(0), 末尾: seek(0,2)

其他相关操作
1. seek(n) 光标移动到n位置, 注意, 移动的单位是byte. 所以如果是UTF-8的中文部分要
是3的倍数.
通常我们使用seek都是移动到开头或者结尾.
移动到开头: seek(0)
移动到结尾: 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()
2. tell() 使用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()
3. truncate() 截断文件
f = open("小娃娃", mode="w", encoding="utf-8")
f.write("哈哈") # 写入两个字符
f.seek(3) # 光标移动到3, 也就是两个字中间
f.truncate() # 删掉光标后面的所有内容
f.close()
f = open("小娃娃", mode="r+", encoding="utf-8")
content = f.read(3) # 读取12个字符
f.seek(4)
print(f.tell())
f.truncate() # 后面的所有内容全部都删掉
# print(content)
f.flush()
f.close()
深坑请注意: 在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", "小娃娃") # 重命名新⽂文件


    9. 文件修改
      创建新文件. 把修改后的内容写入新文件. 删除老文件. 重命名新文件
    import os  导入os模块
    os.remove("")  删除文件
    os.rename("源文件", "新文件名")  重命名文件

    for line in f:#  line 一行数据

    with open("文件名") as f:         不需要关闭文件句柄

 

 

修改⽂文件以及另⼀一种打开⽂文件的⽅方式
⽂文件修改: 只能将⽂文件中的内容读取到内存中, 将信息修改完毕, 然后将源⽂文件删除, 将新
⽂文件的名字改成老⽂文件的名字.
# ⽂文件修改
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", "小娃娃") # 重命名新文件