码迷,mamicode.com
首页 > 其他好文 > 详细

01 文件处理

时间:2020-03-13 20:25:44      阅读:53      评论:0      收藏:0      [点我收藏+]

标签:--   ase   中文   详细   rip   http   用户密码   文件的   copy   

01 文件处理

  • 主要围着open()功能的使用

一、引入

1、什么是文件

  • 文件是操作系统提供给 用户或者是应用程序 用于操作硬盘的虚拟 概念或者说接口。

2、为什么要有文件?

  • 用户或者应用程序可以通过文件,将数据永久保存到硬盘中。
  • 详细的说:用户和应用程序操作的是文件,对文件的所有操作,都是向操作系统发送系统调用,然后再由操作系统将其转换成具体的硬盘的操作。

二、文件操作的基本流程

1、基本流程

"""
伪代码示例:
    f = open(r'指定你要打开文件的文件路径', mode='rt,)
    r:
        raw_str,指的是原生得字符串,里面得反斜杠\,都会被视为普通字符。
    windows中路径分隔符解决方案:
        方案一(推荐):在文件路径前加r
        方案二:windows中会把左斜杠/,默认转换成右斜杠\。使用 'C:/a.txt/nb/c/d.txt',默认会转成 'C:\a.txt\nb\c\d.txt'。
    绝对路径与相对路径:
        相对路径:会以你当前执行文件所在的文件夹下为基准去找。
            优点:简洁
            缺点:当你执行文件移动,被操作文件将找不到。
        绝对路径:从盘符的根目录下开始直接定位到你需要操作的文件地址。
            优点:执行文件移动到任意目录中都可以找到所需要操作的文件地址。
            缺点:臃肿
    rt:
        默认控制文件读写操作的模式是r,只读模式。
        默认控制文件读写内容的模式是t,t文本模式。
    
原理解析:
    f = open 占用了2部分的内存空间:
        第一部分:open占用的是操作系统的的内存空间。由操作系统的映射到了应用程序的内存空间中。
        第二部分:我们知道f的值是一种变量,而变量都是归属于python的内存空间,也就是说。f占用的就是应用程序的内存空间。
"""

# 1、打开文件
f = open(r'aaa/a.txt', mode='rt')   # open是向操作系统发起系统调用。

# 2、操作文件:读写/文件
res = f.read()  # f.read()向操作系统发送请求,让操作系统把文件从硬盘读入内存。
print(res)

# 3、关闭文件
f.close()  # 告诉操作系统,回收刚刚读入文件内存占用的内存空间。(需要考虑的操作:操作系统打开文件,如果没有及时关闭,就会无意义的占用操作系统的内存空间,并且还会无意义的占用操作系统的操作文件数。如果没有指定关闭,操作系统不会立即清除该内存空间的占用,只有过了一定的时间,操作系统才会把没有意义的占用清除,而这种清除时间间隔对于我们来说感觉不到,但是对于计算机来说,是非常大的损耗。补充:操作系统打开文件的文件是有限的,如果开打文件过多,就会影响你的电脑性能。)

f.read()  # 注意:f.close()之后,不能在对文件进行操作了。这个时候操作系统已经把调用的文件关闭回收了,如果继续调用就会报错(ValueError: I/O operation on closed file.)。

del f  # 注意:del f 的顺序要放在f.close()后面。(不需要考虑的操作:有python的GC机制管理)

2、资源回收与with上下文管理

"""
引入:
    with称之为:上下文管理,上文帮你打开文件,下文帮你关闭文件。

    注意:a并不是(10.57)

强调:
    open对应的赋值对象f,称之为文件对象、又有人称之为‘文件句柄’(柄:游戏手柄干嘛的?就是用来操作游戏的。那么我也也可以推理出,其实‘文件句柄’,就是用来远程控制文件的。)
"""
# 1、with打开单个文件
with open('a.txt', mode='rt') as f:     
    res = f.read()
    print(res)
# 上面没有指定f.close(), with会等其子代码块群不运行完毕以后,会帮你自动调用f.close()。


# 2、with同时打开多个文件
# with open('a.txt', mode='rt') as f1, open('b.txt', mode='rt') as f2:  # 当你的一行代码过长,可以使用右斜杠\(注意:右斜杠\并不是换行,而是转义且分隔。)
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)

3、指定操作文本文件的字符编码

  • 上面没有指定操作文本的字符编码,接下来我们需要指定??:
# 强调:如果你操作的是文本文件,那么就使用t模式。(仅限于文本文件)
# 1、r模式下的读操作
with open('c.txt', mode='rt') as f:
    res = f.read()  # f.read()发生了什么过程?向操作系统发送请求,告诉操作系统,我要把c.txt的内容由硬盘往内存读。而我们需要注意的是这个时候硬盘里面躺的是一堆二进制,我们需要使用一种对应的编码格式把二进制由硬盘读入内存,并由unicode转换成相应的字符。
    # open发生的2步骤:1、定义1个变量,2、向操作系统发生请求,让操作系统帮我打开文件。{open第二个步骤中:如果没有指定编码,操作系统就会默认使用自己默认的编码打开文件,如果你的文本文件是用utf-8编码存入硬盘,那么如果你的操作系统是windows,它会使用默认的编码GBK去对应读取硬盘中的二进制文件,如果你之前文件中含有中文字符那么这个时候,GBk的编码表按照它二进制与表的对应关系读出(读出中文2个Bytes),但是我们要知道的是,存入的时候utf-8按照它的二进制与表的对应关系存入(存入中文3个Bytes),在这个时候就会报出解码错(Unicode解码错误:'gbk'编解码器无法解码16位的字节)}
    # 展示硬件当前状态??:
    # 内存:utf-8格式的二进制 --> 解码 --> unicode(t模式会将f.read()读出的utf-8结果,解码成unicode)
    # 硬盘(c.txt内容:utf-8格式的二进制)
    # 展示过程??:
    # 存入:内存中查看到c.txt内容 --> 相应字符按照unicode与utf-8编码对应表转成二进制 -->  把utf-8格式的二进制存入硬盘(c.txt内容)
    # 读出:硬盘(c.txt内容:utf-8格式的二进制) --> 把二进制按照utf-8编码格式对照表读入内存 --> 按照unicode与utf-8编码对应表转成相应字符 --> 打印内存中查看到c.txt内容
    print(res, type(res))
    
# 2、-------w模式的写操作 ------------(没整理)
with open('c.txt', mode='rt') as f:
    f.write()
    
    print(res, type(res))
    
# 单独讨论

# 把字符写入硬盘encode
# 读出decode
'哈哈哈'。

三、文件的操作模式

??控制文件读写内容的模式??

  • 控制文件读写内容的方式有2种:t模式、b模式,它们都不可以单独使用,必须更r/w/a这种控制文件读写的方式连用。
  • 强调:控制的是读入的是什么内容的格式,写入的是什么内容的格式。注意:并不是控制文件读写操作,而是控制文件读写内容,其必须要与操作文件的默认连用。

1、t:文本模式(默认的模式,默认的操作模式r)

  • 强调1:读写都是以str为单位。(python3中str也可以直接看成unicode)
  • 强调2:你的数据来源只能是文本文件(图片,视频都不适用)
  • 强调3:必须指定编码的参数:encoding=‘utf-8‘

2、b:二进制模式

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

1、r:只读模式

"""
r模式是默认的操作模式:只读模式。当文件不存在时,r模式会报错。当文件存在时,文件指针跳到开始位置,也就是说从文件开头位置开始。只能读,不能写。

先手动创建c.txt文件文件,文件内容如下:
哈哈哈哈
"""
# 1、以t模式为基础进行内存操作
with open('c.txt', mode='rt', encoding='utf-8') as f:
    print('res'.center(50, '-'))
    res = f.read()  # 执行f.read(),文件指针从开头一下子跳到文件末尾,同时也把文件内容一次性由硬盘读入内存。问题? 当文件过大时,会把内存干懵!!!
    print(res)

    print('res1'.center(50, '-'))
    res1 = f.read()  # 注意:上面执行了f.read()操作,文件指针在末尾,这个时候怎么读。都读不出来了。
    print(res1)

    # 注意:上面读出文件的每行内容,在每行内容末尾都有个换行符\n。
'''
-----------------------res------------------------
哈哈哈哈
-----------------------res1-----------------------
'''
    
# 2、案例:化之前的用户登录操作,之前的用户站账户信息不能永久保存,这里我们通过存入文件将用户账户信息永久保存。网址连接(第9题:编写用户登录接口写法一):https://www.cnblogs.com/yang1333/p/12357167.html
# 经验总结:for+else,用于用户登录功能中时,else中的子代码块放用户登录失败以后的打印信息。要知道用户登录成功,一定是break退出循环,这个else错误信息也就不执行,也没有执行的必要。但是反过来说,用户登录失败,break语句也就一定不会执行到,那么else中的子代码块的执行,也就不会被break打段。
'''
先手动创建user.txt文件文件,文件内容如下:
egon:123
lili:456
jack:777
tom:666
'''
inp_username = input("please input your username>>:").strip()
inp_password = input("please input your password >>:").strip()

with open('user.txt', mode='rt', encoding='utf-8') as f:
    for line in f:  # 遍历文件对象,line取出的是文件中的每1行的内容。(注意:取出的内容都是str类型,且每一行的末尾都有换行符\n,直接打印print(line)看不到,所以下面使用print([line])放入列表中显示)
        # print([line])
        # line.split()  # 注意:不能直接使用split(),因为文件每行内容末尾(除了最后1行文件内容没有换行符)都有换行符\n,我们要像下面??一样先使用strip()去除\n。
        res = line.strip()  # 使用strip()默认不加参数,去除空白,需要注意的是 \n这个换行符也叫空白符,也可以去除。
        # print([res])

        # 使用split(':')切分字符串,转换成列表。第一个值作为用户账号,第二个值作为用户密码。
        username, password = res.split(':')
        if username == inp_username and password == inp_password:
            print('登录成功!')
            break
    else:
        print('登陆失败!账号或密码错误!')

2、w:只写模式

"""
w:只写模式,当文件不存在时,会创建空文件。当文件存在时,会清空文件。文件指针位于开始位置。不可读,只能写。
"""
with open('d.txt', mode='wt', encoding='utf-8') as f:
    # f.read()  # 不可读,只能写。
    f.write('哈哈哈哈我擦嘞\n')  # 注意:每一次运行,在w模式下,都会先清空原内容。文件指针位于开始位置。(提示:这里的\n是位-------)
'''
d.txt文件中显示结果:
哈哈哈哈我擦嘞

'''    
    
# 强调1:w模式打开文件没有关闭的情况下,连续的写,新的内存总是更在旧的之后。
with open('d.txt', mode='wt', encoding='utf-8') as f:
    f.write('我擦嘞1\n')
    f.write('我擦嘞2\n')
    f.write('我擦嘞3\n')
'''
d.txt文件中显示结果:
我擦嘞1
我擦嘞2
我擦嘞3

'''
    
# 强调2:重新以w模式开打文件,则会先清空文件内容。
with open('d.txt', mode='wt', encoding='utf-8') as f:
    f.write('我擦嘞1\n')
with open('d.txt', mode='wt', encoding='utf-8') as f:
    f.write('我擦嘞2\n')    
with open('d.txt', mode='wt', encoding='utf-8') as f:
    f.write('我擦嘞3\n') 
# 以上内容,d.txt文件中,只有:我擦嘞3\n

# 案例:w模式用来创建全新文件(应用:文件与文件的copy工具)
import os

source_file = input("源文件路径>>:").strip()
destination_file = input("目标路径>>:").strip()

# 先判断源文件路径在不在,不在帮助用户在指定路径下创建源文件及其内容
if not os.path.isfile(source_file):
    with open(r'{}'.format(source_file), mode='wt', encoding="utf-8") as f:
        for i in range(4):
            f.write('我擦嘞:%s\n' % i)

with open(r'{}'.format(source_file), mode='rt', encoding='utf-8') as f,        open(r'{}'.format(destination_file), mode='wt', encoding='utf-8') as f1:
    # 将读出的源文件内容,写入用户指定的目标件中
    # source_file_content = f.read()
    # f1.write(source_file_content)

    # 优化:??上面2步我们发现使用的是f.read(),它是一下子把文件从硬盘读入内存,如果文件过大,会把内存干懵逼!
    for line in f:
        f1.write(line)

'''
copy后目标文件内容:
我擦嘞:0
我擦嘞:1
我擦嘞:2
我擦嘞:3
'''

3、a:只追加写模式

  • 这里总结了a模式与w模式区别以及a模式与w模式作用??:
"""
a:只追加写。在文件不存在时,会创建空文档,文件指针只能在开头,其实这里的开头也是末尾。在文件存在时,文件指针会直接跳到文件内容末尾。不能读,只能追加写。

a模式与w模式区别:
    相同之处:在文件打开不关闭的情况下,连续的写入,新写的内容总会跟在之前写的内容之后。
    不同之处:a模式重新开打文件,只要打开文件,它的指针就会跳到末尾。w模式重新打开文件,直接清空文件。
    
a模式与w模式作用:
    w模式用来创建新文件。(通常用来copy文件)
    a模式争对老文件。(通常用来记录日志文件,通常用与用户注册)
"""
with open('e.txt', mode='at', encoding='utf-8') as f:
    f.write('我擦嘞1\n')
    f.write('我擦嘞2\n')
    f.write('我擦嘞3\n')  
   
# a模式案例:实现用户注册功能(每来一个用户,打开文件,把新用户的信息追加写到已存在的用户账户末尾。)
'''
提前创建user.txt文件,写入以下内容
egon:123
alex:alex3714\n
'''
# 或者使用下面方法快速创建
"""
import os
if not os.path.isfile('user.txt'):
    with open(r'user.txt', mode='wt', encoding='utf-8') as f:
        f.write('egon:123\nalex:alex3714\n')
"""

register = False
while True:
    username = input('请输入注册账号>>:').strip()
    password = input('请输入注册密码>>:').strip()
    confirm_password = input('请确认注册密码>>:').strip()

    # 如果username,password,confirm_password有一个为空那么让用户重新注册
    if '' in [username, password, confirm_password]:
        print('注册账号、注册密码、确认注册密码不能为空。')
        continue
    # 如果用户2次密码不一致,那么让用户重新注册
    if password != confirm_password:
        print('用户2次密码不一致')
        continue
        # 如果用户以及存在,那么让用户重新注册
    with open(r'user.txt', mode='rt', encoding='utf-8') as f:
        for line in f:
            if username == line.strip().split(':')[0]:
                print('用户已经存在,重新注册')
                break
        else:
            register = True
            print('正在为您注册中'.center(50, '-'))
            import time
            time.sleep(2)
    if not register:
        continue

    # 用户注册满足条件,写入文件,注册该用户
    with open(r'user.txt', mode='at', encoding="utf-8") as f:
        f.write('{}:{}\n'.format(username, password))
    print('恭喜你!注册成功!'.center(50, '-'))
    break

4、+:r+、w+、a+模式(注意:具体操作都受限于左侧的模式)-->了解

"""
注意:+不能单独使用,必须配合r、w、a
"""
# 1、r+模式:以r基准,g.txt文件不存在,直接就报错
'''
提前创建user.txt文件,写入以下内容:
111
222
333
444
5555
444
5555

中国
中国
中国

'''
with open('g.txt', mode='rt+', encoding='utf-8') as f:
    print(f.read())  
    f.write('中国\n')  # 如果上面执行了f.read()操作,文件指针默认就会移动到文件末尾,f.write('中国\n')操作就会把内容写入到文件末尾。(类似于a操作)如果上面没有执行f.read()操作,文件指针默认在开始位置,输入的内容多少,就会把g.txt中的原内容覆盖多少。

# 2、w+模式:以w基准
with open('h.txt', mode='w+t', encoding='utf-8') as f:
    f.write('111\n')
    f.write('222\n')
    f.write('333\n')
    # w模式打开文件,清空源文件,文件指针在起始位置。以上f.write操作会按照先后顺序写入h.tx文件。
    print('=======>', f.read()) 
    # ??上面使用f.read()操作,这个时候文件指针在末尾,并不能读出任何内容。

# 3、a+模式:以a基准    
with open('g.txt',mode='at+',encoding='utf-8') as f:
    # print('f.read()')  # a模式下,一打开文件,文件指针就在末尾。f.read()操作并不能读出任何文件内容。
    f.write('中国')  # 更具上面得知文件指针就在末尾,f.write操作会把输入的内容追加到文件内容的末尾去。

四、文件操作的方法

  • 文件操作的方法主要就是争对读/写

1、重点

2、了解

五、文件高级操作:控制文件指针的移动

1、案例一: 0模式详解

3、案例二: 1模式详解

3、案例三: 2模式详解

六、文件的修改的两种方式

1、文件修改方式一

2、文件修改方式二

01 文件处理

标签:--   ase   中文   详细   rip   http   用户密码   文件的   copy   

原文地址:https://www.cnblogs.com/yang1333/p/12488503.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!