python基础 -16- IO(只读,创建,追加,编码,截断,修改,相关方法,文件打开方式)

介绍

 用word操作一个文件的流程如下:

  1. 找到文件,双击打开
  2. 读或修改
  3. 保存&关闭

 用python操作文件也差不多:

f=open(filename)  # 打开文件
f.write("我是野生程序员") # 写操作
f.read()  #读操作
f.close() #保存并关闭

操作模式

  • r 只读模式
  • w 创建模式,若文件已存在,则覆盖旧文件
  • a 追加模式,新数据会写到文件末尾

创建模式

# 新增文件
file = open(file="F:\\Animation\\0.txt", mode="w")
file.write("""开始
    你好呀!
    快来吧!!
结束""")
file.flush()
file.close()

追加模式

# 追加文件
file = open(file="F:\\Animation\\1.txt", mode="a")
file.write("增加一行\n")
file.close()

只读模式

import chardet

# 只读文件
file = open(file="F:\\Animation\\0.txt", mode="r")

print("是否可读:", file.readable())
print("是否可写:", file.writable())

file.seek(2, 0)  # 把操作文件的光标移到指定位置,从0开始
print("此时位置:", file.tell(), file.readline(1))  # 数字为限制读取该行几个字符,默认为-1,即为全部

file.seek(2)
print("此时位置:", file.tell(), file.readlines(2))  # 数字为限制读取到 当前位置行的剩余数据~第hint个字符的那一行所有数据,默认为-1,即全部

info = file.read(6)
print(info)  # 数字为读取几个字符,默认为-1,即全部字符
print("编码格式:", chardet.detect(info.encode()).get("encoding"))

file.close()

 输出

是否可读: True
是否可写: False
此时位置: 2 始
此时位置: 2 ['始\n', '    你好呀!\n']
    快来
编码格式: utf-8

编码格式要安装 pip install chardet

我发现我的编译器和文件设置的都是utf-8编码,但是文件存储的还是GBK格式,因为win上面默认的文件编码格式就是GBK,linux和mac上面默认是UTF-8

可以通过设置encoding来改变格式

file = open(file="F:\\Animation\\4.txt", mode="r",  encoding="utf-8")

至于为什么编码格式输出为utf-8,因为编译器自动帮我们将GBK转为了utf-8


循环

 文件数据

马纤羽     深圳    173    50    13744234523
乔亦菲     广州    172    52    15823423525
罗梦竹     北京    175    49    18623423421
刘诺涵     北京    170    48    18623423765
岳妮妮     深圳    177    54    18835324553
贺婉萱     深圳    174    52    18933434452
叶梓萱     上海    171    49    18042432324

 循环读取

# 循环
file = open(file="F:\\Animation\\2.txt", mode="r")
for line in file:  # line <class 'str'>  叶梓萱     上海    171    49    18042432324
    line = line.split()  # line <class 'list'>  ['贺婉萱', '深圳', '174', '52', '18933434452']
    name, address, height, weight, phone = line
    height = float(height)
    weight = float(weight)
    if height > 170 and weight <= 50:
        print(line, name, "--", address, "--", height, "--", weight, "--", phone)
file.close()

 输出

['马纤羽', '深圳', '173', '50', '13744234523'] 马纤羽 -- 深圳 -- 173.0 -- 50.0 -- 13744234523
['罗梦竹', '北京', '175', '49', '18623423421'] 罗梦竹 -- 北京 -- 175.0 -- 49.0 -- 18623423421
['叶梓萱', '上海', '171', '49', '18042432324'] 叶梓萱 -- 上海 -- 171.0 -- 49.0 -- 18042432324

截断

file = open(file="F:\\Animation\\0.txt", mode="a")
print("截断所有:", file.truncate())  # 截断所有,即不变
print("截断指定:", file.truncate(4))  # 截断到第4个字节,值剩下两个字符(中文):开始
file.close()

 输出

截断所有: 38
截断指定: 4

修改(注意覆盖问题)

file = open("F:\\Animation\\3.txt", "r+")
file.seek(7)
file.write("二柱")  
file.close()

 结果

file = open("F:\\Animation\\3.txt", "r+")
file.seek(7)
file.write("二柱子")
file.close()

 结果

没错,进行了一个覆盖,那么,为什么原有数据会被覆盖呢?

 这是硬盘的存储原理导致的,当你把文件存到硬盘上,就在硬盘上划了一块空间,存数据,等你下次打开这个文件 ,seek到一个位置,每改一个字,就是把原来的覆盖掉,如果要插入,是不可能的,因为后面的数据在硬盘上不会整体向后移。所以就出现 当前这个情况 ,你想插入,却变成了会把旧内容覆盖掉。

但是人家word, vim 都可以修改文件 呀,你这不能修改算个什么玩意?

 我并没说就不能修改了,你想修改当然可以,就是不要在硬盘上修改,把内容全部读到内存里,数据在内存里可以随便增删改查,修改之后,把内容再全部写回硬盘,把原来的数据全部覆盖掉。vim word等各种文本编辑器都是这么干的。

说的好像有道理,但你又没看过word软件的源码,你凭什么这么笃定?

 哈哈,我不需要看源码,硬盘 的存储原理决定了word必须这么干 ,不信的话,还有个简单的办法来确认我说的,就是用word or vim读一个编辑一个大文件 ,至少几百MB的,你 会发现,加载过程会花个数十秒,这段时间干嘛了? cpu 去玩了?去上厕所啦? 当然不是,是在努力把数据 从硬盘上读到内存里。

但是文件如果特别大,比如5个GB,读到内存,就一下子吃掉了5GB内存,好费资源呀,有没有更好的办法呢?

 如果不想占内存,只能用另外一种办法啦,就是边读边改, 什么意思? 不是不能改么?是不能改原文件 ,但你可以打开旧文件 的同时,生成一个新文件呀,边从旧的里面一行行的读,边往新的一行行写,遇到需要修改就改了再写到新文件 ,这样,在内存里一直只存一行内容。就不占内存了。 但这样也有一个缺点,就是虽然不占内存 ,但是占硬盘,每次修改,都要生成一份新文件,虽然改完后,可以把旧的覆盖掉,但在改的过程中,还是有2份数据 的。

 来个例子吧!!!GO!!

import os

file_name = "F:\\Animation\\3.txt"
file_new_name = "F:\\Animation\\4.txt"
file = open(file_name, "r")
file_new = open(file_new_name, "w")
str_old = "深圳"
str_new = "杭州"

# 循环修改,产生一个新文件
for line in file:
    if str_old in line:
        line = line.replace(str_old, str_new)
    file_new.write(line)
file_new.close()
file.close()

# 再修改和文件名称
os.replace(file_new_name, file_name)


查看编码方式

先安装 pip install chardet

import chardet

file = open(file="F:\\Animation\\0.txt", mode="r")
print("编码格式:", chardet.detect(info.encode()).get("encoding"))
file.close()

 输出

编码格式: utf-8

注意:此例子看的并不是文件的编码格式,而是获取的数据编码格式


二进制读

# 二进制方式不能指定encoding,因为获取的就是二进制字节码
file = open(file="F:\\Animation\\4.txt", mode="rb")
print("完整数据:", file.read().decode("utf-8"))

file.seek(3)  # 默认是0,从头开始移动3个字节
print(file.readline(3).decode("utf-8"))

file.seek(-3, 1)  # 从当前位置移动-3个字节,只有1和2才能是offset<0
print(file.readline(3).decode("utf-8"))

file.seek(-3, 2)  # 从文件末尾移动-3个字节
print(file.readline(3).decode("utf-8"))

file.seek(-3, 2)  # 从文件末尾移动-3个字节
print(file.readline(3).decode("utf-8").encode("GBK"))  # 转成GBK编码

file.close()

 输出

完整数据: 你好呀去吧
好
好
吧
b'\xb0\xc9'

相关方法

表格
序号方法及描述
1close()关闭文件。关闭后文件不能再进行读写操作。
2file.flush() 刷新文件内部缓冲,直接把内部缓冲区的数据立刻写入文件, 而不是被动的等待输出缓冲区写入。
3file.fileno() 返回一个整型的文件描述符(file descriptor FD 整型), 可以用在如os模块的read方法等一些底层操作上。
4file.isatty() 如果文件连接到一个终端设备返回 True,否则返回 False。
5file.next() 返回文件下一行。
6[file.read(size]) 从文件读取指定的字节数,如果未给定或为负则读取所有。size指定读取几个字节
7[file.readline(size]) 读取整行,包括 “\n” 字符。size可以指定读取当前行的几个字符
8[file.readlines(sizeint]) 读取所有行并返回列表,若给定sizeint>0,则是设置一次读多少字节,这是为了减轻读取压力。注意的是:sizeint为限制读取到 当前位置行的剩余数据~第hint个字符的那一行所有数据
9[file.seek(offset, whence]) 设置文件当前位置 ,offset: 偏移量,whence:三种方式(0:从头开始;1:从当前位置开始;2:从末尾开始)。1和2:open函数只能以二进制模式打开文件,才能正常运行,否则就会报出上面的错误。如果没有以二进制b的方式打开,则offset无法使用负值(即向左侧移动)
10file.tell() 返回文件当前位置。
11[file.truncate(size]) 截取文件,截取的字节通过size指定,默认为当前文件位置。
12file.write(str) 将字符串写入文件,返回的是写入的字符长度。
13file.writelines(sequence) 向文件写入一个序列字符串列表,如果需要换行则要自己加入每行的换行符。

open方法
def open(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True)

可选模式

模式描述
t文本模式 (默认)。
x写模式,新建一个文件,如果该文件已存在则会报错。
b二进制模式。
+打开一个文件进行更新(可读可写)。
U通用换行模式(不推荐)。
r以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
rb以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等。
r+打开一个文件用于读写。文件指针将会放在文件的开头。
rb+以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等。
w打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
wb以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。
w+打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
wb+以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。
a打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
ab以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
a+打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
ab+以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值