zoukankan      html  css  js  c++  java
  • 文件操作

    一 什么是文件

    文件是操作系统提供给用户/应用程序操作硬盘的一种虚拟的概念/接口

    用户/应用程序

    操作系统(文件)

    计算机硬件(硬盘)

    二 为何要用文件

    用户/应用程序可以通过文件将数据永久保存在硬盘中,即操作 文件就是操作硬盘

    用户/应用程序直接操作的是文件,对文件进行的所有的操作,都是在向操作系统发送系统调用,然后再由操作将其转换成具体的硬盘操作

    三 如何用文件:open()

    控制文件读写内容的模式:t和b

    ​ 强调:t和b不能单独使用,必须跟r/w/a连用

    1、t文本(默认的模式)

    ​ 1、读写都以str(unicode)为单位的
    ​ 2、文本文件
    ​ 3、必须指定encoding='utf-8'

    2、b二进制/bytes

    b:binary 模式

    ​ 1、读写都是以 bytes 为单位

    ​ 2、可以针对所有模式

    ​ 3、b 模式下,一定不能指定字符编码,即一定不能指定 encoding参数

    总结:

    ​ 1、在操作纯文本方面 t 模式帮我们省去了编码与解码的环节

    ​ 2、针对文本文件(如图片、视频、音频等)只能使用 b 模式

    ​ 通用模式为 b 模式

    bytes 类型转换

    x = 10 #int(10)
    '你'.encode('gbk') # bytes( )
    

    控制文件读写操作的模式:

    ​ r只读模式
    ​ w只写模式
    ​ a只追加写模式
    ​ +:r+、w+、a+

    ps:

    ​ x 模式(控制文件操作的模式)-->了解

    ​ x:只写模式(不可读,不存在则创建,存在则报错)

    ​ x+ :可读可写

    四 文件基本操作

    1、打开文件

    ​ windows 路径分隔符问题解决方法:

    ​ 绝对路径:

    ​ 从根目录下一层一层找

    open(r 'c:/a/nb/c.text ')  #假如写右斜杠也行,open()会帮你转换成,用 r 表示告诉你这只是普通的字符,没有转义
    

    ​ 相对路径:

    ​ 必须以当前文件为基准

    open('c.txt') #打开文件, 后面才能操作文件内容
    
    f = open('c.txt' mode='rt')   #f的值是一种变量,占用的应用程序的内存空间,open操作占用操作系统的内存(因为它想操作系统发送的打开文件的请求)
    print(f) 
    

    2、操作文件:读/写文件

    ​ 应用程序对文件的读写请求都是在向操作系统发送系统调用,然后由操作系统控制硬盘把输入读入内存、或者写入硬盘。

    res = f.read()#向操作系统发送请求,把文件读入内存
    print(res)
    

    3、关闭文件

    f.close( ) #  关闭文件, 回收操作系统资源
    f.read( ) #变量 f 是仍然存在的,但是不能再读了
    #del f #回收应用程序资源  在 python 中回收应用程序资源不需要考虑,python 会帮你回收
    

    五 with 上下文管理

    由于大部分程序员还是会不由自主地忘记f.close(),考虑到这一点,python提供了with关键字来帮我们管理上下文

    f:文件句柄

    with open('a.txt' mode='rt')as f:  # ===> f= open('a.txt' mode='rt')
      res = f.read()
      print(res)
    
    with open('a.txt' mode='rt')as f1, 
    	open('b.txt' mode='rt')as f2:
      res1 = f1.read()
      res2 = f2.read()
      print(res1)
      print(res2)
    

    2、指定字符编码

    强调:t 和 b 不能单独使用, 必须跟 rwa 连用

    t 文本(默认的模式):

    1、读写都以 str(unicode)为单位的

    2、文本文件

    3、必须指定 encoding = 'utf-8'

    没有指定 encoding 参数操作系统会使用自己默认的编码

    linux 系统默认 utf-8

    windows 系统默认 gbk

    with open('c.txt', mode='rt', encoding= 'utf-8')as f:
    		res= f.read() #t模式会将 f.read()读出的结果解码成 unicode
    		print(res, type(res))
    

    内存:utf-8格式的二进制----------解码--------------->unicode

    硬盘:c.txt内容:utf-8格式的二进制

    3、文件操作模式详解

    以t模式为基础进行内存操作

    1、r(默认的操作模式):只读模式,当文件不存在时报错,当文件存在时文件指针跳到开始位置

    with open('c.txt',mode='rt',encoding='utf-8') as f:
        print('第一次读'.center(50,'*'))
        res=f.read() # 把所有内容从硬盘读入内存
        print(res) #哈哈哈哈
        print('第二次读'.center(50,'*'))
        res1=f.read()
        print(res1)#换行符
    

    案例:

    inp_username=input('your name>>: ').strip()
    inp_password=input('your password>>: ').strip()
    
    with open('user.txt',mode='rt',encoding='utf-8') as f:
        for line in f:
            # print(line,end='') # egon:123
    
            username,password=line.strip().split(':')
            if inp_username == username and inp_password == password:
                print('login successfull')
                break
        else:
            print('账号或密码错误')
    

    应用程序======》文件

    应用程序=》数据库管理软件=》文件

    2、w:只写模式,当文件不存在时会创建空文件,当文件存在会清空文件,指针位于开始位置

    注:如果重新以w模式打开文件,则会清空文件内容

    with open('d.txt',mode='wt',encoding='utf-8') as f:
        f.read() # 报错,不可读
        f.write('擦勒
    ')
    

    在以w模式打开文件没有关闭的情况下,连续写入,新的内容总是跟在旧的之后

    with open('d.txt',mode='wt',encoding='utf-8') as f:
        f.write('擦勒1
    ')
        f.write('擦勒2
    ')
        f.write('擦勒3
    ')
    

    w 模式一般用来创建全新的文件

    文本文件的 copy 工具

    src_file=input('源文件路径>>: ').strip()
    dst_file=input('源文件路径>>: ').strip()
    with open(r'{}'.format(src_file),mode='rt',encoding='utf-8') as f1,
        open(r'{}'.format(dst_file),mode='wt',encoding='utf-8') as f2:
        res=f1.read()
        f2.write(res)
    

    3、a:只追加写,在文件不存在时会创建空文档,在文件存在时文件指针会直接调到末尾

    with open('e.txt',mode='at',encoding='utf-8') as f:
        # f.read() # 报错,不能读
        f.write('擦嘞1
    ')
        f.write('擦嘞2
    ')
        f.write('擦嘞3
    ')
    

    w 模式 与a 模式 的异同:

    1、相同点:在打开的文件不关闭的情况下,连续的写入,新写的内容总会跟在前写的内容之后;

    2、不同点:以 a 模式重新打开文件,不会清空原文件内容,会将文件指针直接移动到文件;

    案例:a模式用来在原有的文件内存的基础之上写入新的内容,比如记录日志、注册

    注册功能

    name=input('your name>>: ')
    pwd=input('your name>>: ')
    with open('db.txt',mode='at',encoding='utf-8') as f:
        f.write('{}:{}
    '.format(name,pwd))
    

    了解:+ 不能单独使用,必须配合 r、w、a,而且它是继承自己(r/w/a)的特性的。其实就是在(r/w/a)的基础特性上增加了一个可读可写的功能。

    with open('a.txt',mode='r+t', encoding='utf-8')as f:
    		print(f.read()) #读出硬盘的二进制 —>t模式控制将二进制转换成unicode->字符。
    		f.write('中国')
    
    with open('a.txt', mode='w+', encoding='utf-8')as f:
        print(f.read()) # 读不到 ,w 模式下文件以前的数据会被清除
        f.write('中国
    ')
        f.write('222
    ')
        f.write('333
    ')
        print(f.read())#读不到, 指针处于末尾位置
    
    
    with open('a.txt', mode='a+', encoding='utf-8')as f:
        print(f.read()) #读不到,因为 a模式下指针会指向末尾位置
        f.write('中国
    ')
        print(f.read()) #读不到,写入后指针还是处于末尾位置
    

    Ps:

    open(打开文件(文件很大))是不涉及读和写操作的,只是将文件指针控制到开头或者末尾,并不会阻塞,当data =f.read()(赋值:把硬盘的内容读入内存)操作时,才会会阻塞。

    错误演示:t 模式只能读文本文件

    with open('qq.mp4', mode='rt', encoding='utf-8')as f:
    		f.read()#硬盘的二进制读入内存->t 模式会将读入内存的内容进行 decode解码操作
    

    以b模式为基础进行内存操作

    b 模式下:硬盘文件内容读入内存是不做任何转换的

    一定不能指定 encoding 参数

    读写都是以 bytes

    with open(r'a.txt', mode='rb')as f: 
      	res = f.read() #硬盘的二进制(utf-8格式)直接读入内存->b模式下不做转换
      	print(res,type(res)) #b'xe4xbdxa0xe5xa5xbd' class<bytes>  -->当成二进制
        print(res.decode('utf-8'))#你好
    

    b 模式下:不能写入字符串格式数据,所以需要 encode成硬盘的编码格式(utf-8)

    with open('a.txt', mode='wb')as f:
    	f.write('你好')#报错
      f.write('你好'.encode('utf-8'))
    
    with open(r'b.txt', mode='wb')as f:
    	f.write('你好 hello'.encode('gbk')) #��� hello  #你好显示乱码是因为pycharm打开默认是 utf-8解码,所以使用gbk编码导致中文显示会乱码
      
    

    文件拷贝工具

    src_file=input('源文件路径>>: ').strip()
    dst_file=input('源文件路径>>: ').strip()
    with open(r'{}'.format(src_file),mode='rb') as f1,
        open(r'{}'.format(dst_file),mode='wb') as f2:
        # res=f1.read() # 内存占用过大
        # f2.write(res)
    
        for line in f1:
            f2.write(line)
    

    4、循环读取文件

    方式一 : while + f.read(数据长度参数)

    ​ 数据长度参数:自己控制每次读取的数据量

    ​ 数据长度为字节长度

    with open(r'test.jbg', mode='rb')as f:
    		while True:
          	res = f.read(1024)#1024个字节
            if len(res)== 0:
            		break
            print(len(res)) #1024
    
    

    方式二: for : 以行数为单位读, 当一行内容过长时会导致一次性读入内存的数据量过大

    for 循环区分行是以换行符区分的

    with open(r'g.txt', mode='rb')as f:
      for line in f:
        print(line, len(line))
    
    

    注:当文件内容一行过长时,可以用 while,它可以控制每次读取的量

    f.readline:一次读一行

    相当于 for 循环,不指定默认每次读一行

    f.readline(n):

    t模式下:

    ​ 1)当 n 不超过一行字符个数时,读n 个字符

    '''
    你好 hello
    haha
    1111
    '''
    with open('aaa.txt', mode='rt', encoding='utf-8') as f:
        res = f.readline(2)
        print(res)  ##你好 t模式下read(n): n代表的是字符个数
        
    
    

    ​ 2)当 n超过一行字符个数时,读一行字符

    '''
    你好 hello
    haha
    1111
    '''
    with open('aaa.txt', mode='rt', encoding='utf-8') as f:
        res = f.readline(100)
        print(res)  #你好 hello
        						#空行(换行符)    							
    
    

    b 模式下:

    ​ n 代表的是字节数

    f.readlines:一次读所有行

    f.readlines( ):默认读所有行,存放于列表中

    '''
    你好 hello
    haha
    1111
    '''
    with open('aaa.txt', mode='rt', encoding='utf-8') as f:
        res = f.readlines()
        print(res) #['你好 hello
    ', 'haha
    ', '1111
    ']
    
    

    f.readlines( n): t 模式下的n 代表读的字符数

    1)如果字符数没有超过一行的字符数,那么就读一行

    2)如果字符数超过或等于一行的字符数,指针会读到换行符移至第二行,所以也会读取下一行内容,依次往下类推

    '''
    你好 hello
    haha
    1111
    '''
    with open('aaa.txt', mode='rt', encoding='utf-8') as f:
        res = f.readlines(1)
        print(res) #['你好 hello
    ']
        res = f.readlines(9) #读到了
        print(res) #['你好 hello
    ', 'haha
    ']
    		res = f.readlines(13)
        print(res) #['你好 hello
    ', 'haha
    ']
        ['你好 hello
    ', 'haha
    ', '1111
    ']
    
    

    f.read( n): b 模式下的n 代表读的字节数

    with open('1.mp4',mode='rb') as f:
        while True:
            data=f.read(1024) # 同一时刻只读入1024个Bytes到内存中
            if len(data) == 0:
                break
            print(data)
    
    
    

    强调:

    f.read( )与 f.readlines( )都是将内容一次性读入内存,如果内容过大会导致内存溢出。

    5、循环写入操作

    f.writelines( 列表)

    t 模式下写入时, 列表内部的元素必须为字符串类型,相当于一个 for 循环写入

    with open('h.txt',mode='wt',encoding='utf-8') as f:
        # f.write('1111
    222
    3333
    ')
    
        # l=['11111
    ','2222','3333',4444] #列表中的有元素为不是字符串类型,所有写入是会报错
        l=['11111
    ','2222','3333']
        # for line in l:
        #     f.write(line)
        f.writelines(l)
    
    

    b模式下写入时,必须要将字符串类型 进行encode成 ’ 硬盘类型编码格式’,否则 f.write( )报错

    with open('h.txt', mode='wb')as f:
    		l = [
    		'111aa
    '.encode('utf-8'), 
        '222bb
    '.encode('utf-8'),
    		]
        f.writelines(l)
    
    

    补充:

    #如果字符串是是纯数字,英文字符组成,可以直接加前缀b 得到 bytes 类型
    l = [
      b'111aa
    ',
      b'222bb
    '
    ]
    
    
    #'上'.encode('utf-8')等同于 bytes('上', encoding='utf-8')
    l = [
      bytes('上啊
    ',encoding='utf-8'),
      bytes('冲啊
    ',encoding='utf-8')
    ]
    
    

    f.flush

    立即将文件内容从内存存入硬盘

    一般会用于文件测试

    with open('h.txt', mode='wt',encoding='utf-8') as f:
        f.write('哈')
        # f.flush()
    
    

    了解:

    f.readable( ) :文件是否可读

    f.writeable( ):文件是否可写

    f.closed : 文件是否关闭

    f.encoding :如果文件打开模式为 b,则没有该属性

    f.flush( ): 立刻将文件内容从内存刷到硬盘

    f.name: 文件名

    with open('aaa.txt', mode='wt', encoding='utf-8') as f:
        print(f.readable()) #False  
        print(f.writable()) #True
        print(f.name) #aaa.txt
        print(f.encoding) #utf-8
    
    

    六 控制文件指针操作

    指针移动的单位都是以 bytes(字节)为单位,只有一种情况特殊:t模式下的 read( n) ,n 代表的是字符个数

    '''
    你好 hello
    haha
    1111
    '''
    with open('aaa.txt', mode='rt', encoding='utf-8') as f:
        res = f.read(4)
        print(res) #你好 h
    
    

    1、f.seek:移动指针

    f.seek( n,模式): n 指的是移动的字节个数

    注:不管是否是在 t 或者 b 模式下,f.seek都是以字节个数移动

    模式

    模式 0:参照物是文件开头位置

     f.seek(9,0)
     f.seek(3,0) # 3
    
    

    模式 1:参照物是当前指针所在位置

    f.seek(9,1)
    f.seek(3,1) # 12
    
    

    模式2:参照物是文件末尾位置,应该倒着移动

    f.seek(-9,2)#3
    f.seek(-3,2)#9
    
    

    强调

    t模式下只能使用模式 0,而b 模式下可以使用模式 0,1,2

    '''
    你好 hello
    haha
    1111
    '''
    
    with open('aaa.txt', mode='rb') as f:
        f.seek(2, 0) #2
        f.seek(3, 0) #3
        print(f.tell()) #3
        res =f.read()
        print(res) #b'xe5xa5xbd hello
    haha
    1111'
        print(res.decode('utf-8')) 
        '''
        好 hello
        haha
        1111
        '''
    
    

    Ps:硬盘压根没有修改操作,都是新数据完全覆盖旧数据;都是修改内存的数据保存覆盖硬盘原数据。

    七 文件修改

    文件修改的两种方式

    方式一:文本编辑采用的就是这种方式

    实现思路:将文件内容发一次性全部读入内存,然后在内存中修改完毕后再覆盖写回原文件

    ​ 优点:在文件修改过程中同一份数据只有一份(硬盘)

    ​ 缺点:会过多地占用内存

    with open('c.txt',mode='rt',encoding='utf-8') as f:
        res=f.read()
        data=res.replace('alex','dsb')
        print(data)
    
    with open('c.txt',mode='wt',encoding='utf-8') as f1:
        f1.write(data)
    
    

    方式二:

    ​ 实现思路:以读的方式打开原文件,以写的方式打开一个临时文件,一行行读取原文件内容,修改完后写入临时文件...,删掉原文件,将临时文件重命名原文件名

    ​ 优点:不会占用过多的内存

    ​ 缺点: 在文件修改过程中同一份数据存了两份(硬盘)

    with open('c.txt', mode='rt', encoding='utf-8') as f, 
            open('.c.txt.swap', mode='wt', encoding='utf-8') as f1:
        for line in f:
            f1.write(line.replace('alex', 'dsb'))
    
    os.remove('c.txt')
    os.rename('.c.txt.swap', 'c.txt')
    
    
  • 相关阅读:
    新增html元素的使用
    音频的使用和插入以及动态文字的使用
    创建表单以及表单元素的使用
    今天学习image在html中的应用
    Repeater里查找控件
    CSS 基础教程
    自然图像的颜色统计特征 Image Color Statistics
    [转]UE中使用正则表达式的一些技巧
    [转]SQL Server 的事务和锁
    [转]Amtura 商务智能项目实现手记
  • 原文地址:https://www.cnblogs.com/xy-han/p/12489492.html
Copyright © 2011-2022 走看看