文件操作

所谓文件,就是系统提供给你的直接操作硬盘的快捷方式。

计算机三大组成部分, CPU,内存, 硬盘, 其中CPU负责计算,内存和硬盘负责存储数据, 内存特点是存取快,但是无法永久化存储数据(断电数据就会丢失), 硬盘存取数据慢,但是可以 用来永久存储。

 

  1. 文件的打开

f = open("a.txt", mode="rt")

这里有两点需要说明,python解释器是无法操作计算机硬件的,只有操作系统有权限能够操作其对应的硬件,因此,我们在python代码中操作文件的动作,其实只是python解释器向操作系统发送请求。

因此,明白了上边的前提,我们就可以知道,上边的open()语句其实是做了两方面的资源占用,一个是创建了python变量f,指向一个内存中的文件对象,另一个是向操作系统发请求, 然后操作系统创建了一个对象,该对象指向硬盘中的文件存储区域,并把操作系统中的文件和文件对象映射起来。

我们在打开之后,对文件对象的读写操作,其实都是通过文件对象,对操作系统中的文件进行修改。由操作系统再将修改内容写入硬盘。

 

  1. 文件的读写模式

    f = open("文件路径", mode="wt")

2.1 从读写模式看,有三种:w, r, a

(1)w模式,只读模式,如果文件存在,则清空,如果文件不存在,则创建一个新的文件出来。

(2)r模式, 只读模式, 如果文件存在,则打开,如果文件不存在,则报错

(3)a模式,追加模式,如果文件存在,则再最后边添加文本,如果文件不存在,则创建文件。

2.2 从文件的读写内容来看,由两种 t模式(默认)和b模式

(1)t模式,是默认的实现模式,就是读写是字符串的形式,需要指定读取的编码格式

f= open("memcheck/b.txt", mode="wt", encoding="gbk")

(2)b模式,

  1. 文件的关闭

f.close() #表示文件的关闭

这里f.close()并不是python对象的关闭,而是向系统发送请求,关闭打开的文件,如果不及时关闭文件,就会造成系统资源的浪费,而且系统可以同时打开的文件数量也由上限。

而f对象,则由python的垃圾回收机制负责清理。

  1. with上下文管理器

针对文件打开忘记关闭的情况,python提供了with上下文管理器,进行自动关闭。with句块再执行完代码之后,会自动调用文件对象的close()方法,关闭系统的文件对象。

#这两种方式是一样的,第二种是python提供的语法糖,看起来简洁,但本质上是一致的。
f=  open("memcheck/b.txt", mode="wt", encoding="gbk")
f.write("双击666!")
f.close()

with open("memcheck/b.txt", mode="wt", encoding="gbk")as f:
    f.write("双击666!")
  1. 文件的编码问题

文件的编码问题主要是文件的存储和读取。ptyhon2的默认编码方式ascii码python3 的默认编码方式是utf-8, 不同的操作系统,编码方式也不同,windows的默认编码方式gbk, linux和mac系统的默认编码方式是utf-8.

乱码问题只有两种,一种是存乱了,一种是读乱了。这里不考虑存乱了的问题,只看读乱了的情况。如果文件以b模式打开,因为硬盘中存放的就是二进制的数据,因此是不存在读乱的问题,因为它是将硬盘中的二进制直接加载到内存中,内存中也是二进制,不存在编码解码的问题,(如果我们将内容打印出来,会出现)

python解释器执行open(mode='rt')方法时,是向系统发送了一个打开文件的请求,系统会创建一个对象,并让该对象指向硬盘中的指定区域,系统在打开文件时,将硬盘上的二进制加载到内存并解码成字符串形式, 这时,需要指定解码格式,如果没有指定的话,就会采用系统默认 的解码方式。

 

  1. 文件的读操作

    with open("memcheck/a.txt", mode='rt', encoding="utf-8") as f:
        res = f.read()  # 将文件一次性全部读到内存中。。(不推荐)
        print(res)
    
    with open("memcheck/a.txt", mode='rt', encoding="utf-8") as f:
        res = f.readline()  #从文件光标处开始读取1行,并将字符串返回
        print(res)
        print(f.readable())  #判断文件是否可读,以读模式打开,则为true
        ress = f.readlines()   # 将文件按行读出,以列表形式返回,列表,不是可迭代对象。
        print(ress,  type(ress)) # ['age 15\n', 'gender male\n', 'heighht 1.89\n', 'wight 76'] <class 'list'>
    

如果以b模式打开文件,读的话,则不需要添加encoding,因为系统会将硬盘中的二进制数完整的读取出来并返回给python解释器。我们以t模式打开文本的本质,其实也是以b模式打开文件,然后系统替我们做了解码的步骤而已。

with open("memcheck/a.txt", mode='rb') as f:
    res = f.read()
    # ress = f.readlines() 
    print(res.decode("utf-8"))
  

r+ 模式,依赖于r, 如果文件不存在,则会报错,如果文件存在,则会将文件指针移向文件开头。 r+ 模式打开的文件,既可以读文件,也可以写文件,

with open("memcheck/a.txt", mode='r+t', encoding="utf-8") as f:
    res = f.read()  
    print(res)  # 这里的会将文件全部读取到内存中,记住,这里的文件指针在文件末尾
    f.write("666")  # 这里在文件指针处写入字符“666”,写完之后,文件指针刚好在文末。
    print(f.read()) # 由于文件指针在末尾,所以这里读取不到任何内容

with open("memcheck/a.txt", mode='r+t', encoding="utf-8") as f:
    f.write("abc")  # 这里r+模式打开,文件指针在开头,因此写入的话,会从头开始写,原先的内容会被覆盖掉,刚好验证了,utf-8中一个中文占三个字节。
    print(f.read())  # 由于指针移动到abc后边,因此从这里开始读取数据,666就不会显示出来。
修改前:
用户名 peter
age 15 年龄
gender male  性别
heighht 1.89 身高
wight 76  体重666
修改后:
abc户名 peter
age 15 年龄
gender male  性别
heighht 1.89 身高
wight 76  体重666
  1. 文件的写操作

文件如果存在,则将文件清空, 如果文件不存在,则创建新的文件。

以t模式写入文件和读取文件一样的原理,如果不指定编码方式,系统会采用 默认编码方式 来编码,windows的话就是GBK,如果在pycharm中打开的话(默认编码方式utf-8),就会显示乱码

# 不合理的写入方式
with open("memcheck/c.txt", mode='w') as f:
    f.write('铁子666呀!!!')
    f.writelines(["第二行的数据", "third row", '123548646'])  #如果不添加换行符,所有的内容都会写入一行。
  
# 合理的写入
with open("memcheck/c.txt", mode='w', encoding="utf-8") as f:
    f.write('铁子666呀!!!\n')
    f.writelines(["第二行的数据\n", "third row\n", '123548646\n'])

 b模式和w+和读文件基本一致。 
w+模式以w为主,如果文件存在,则删除,如果文件不存在则创建。文件可读可写。。       
  1. 文件的追加写模式(a模式)

如果文件存在,则打开文件,并将指针移向文件末尾。如果文件不存在,则创建。

with open("memcheck/d.txt", mode="a", encoding="utf-8") as f:
    print(f.write('德莱文的魅力就是德莱文'))  # 如果不指定编码方式,就按照 系统默认 方式编码, 在文件的末尾追加

 

  1. 文件的指针操作

文件是按指针位置对文件读写进行操作的,操作文件指针就可以实现,在任意位置对文件进行读写操作了。

只有t模式下的read(n), 这里的n是字符数,其他的文件操作中,n都是字节数

文件指针的移动是seek(移动的字节数, 模式)方式实现。

移动的字节数,可以是正的,也可以是负的, 代表从前往后以及从后往前的顺序

模式的值为三种:0, 1,2。 其中 0表示相对于文件开头,进行字节位移,1表示相对于指针当前位置进行移动,2表示相对于文件末尾进行字节移动。(utf-8的中文都是三个字节表示,如果移动的字节数不对,则会乱码,例如三个中文,9个字节,如果从第四个字节读,会乱。)

模式0 可以在t模式下的r模式下进行移动,模式1和模式2则会报错,但是在b模式下,三种模式都可使用。

with open("memcheck/d.txt", mode="rb") as f:
    print(f.read().decode("utf-8"))
    f.seek(-9,1)
    print(f.read().decode("utf-8")

硬盘中的文件修改的原理

 

posted @ 2023-08-28 17:26  往昔遗忘  阅读(26)  评论(0编辑  收藏  举报