Python学习笔记【第七篇】:编码、文件、文件夹操作

 介绍

  我们用pytthon、C#、Java等这些编程语言,想要把文件(文字、视频....)永久保存下来就必须将文件写入到硬盘中,这就需要我们应用程序去操作硬件,我们这些编程语言是无法直接操作硬件的。就需要操作系统把复杂的硬件操作封装成接口给应用程序调用。这样用户\应用程序就能对文件进行操作了。

 

字符编码:

  1:python读/写文本文件会涉及到编码 2:python关于识别到定义变量的时候

 

ASCII:只支持英文字符串 采用8位二进制对应一个英文字符粗

GBK: 支持英文、中文字符串 采用8位(8bit=1Bytes)二进制数对应一个英文字符串 采用16位(16bit=2Bytes)二进制对应一个中文字符串

unicode:兼容万国字符串 采用16位(16bit=2Bytes)二进制对应一个中文字符串,个别生僻字采用4Bytes、8Bytes

现代计算机统一使用Unicode编码。

 

utf-8 :unicode transform (精简)版

文本文件存取乱码问题:

  存乱了:编码格式因该设置成支持的文件内字符串

  取乱了:文本以什么编码存,就因该以什么编码取

 

文件路径说明:

  1:windows路径  如:C:\a\b\c\d.txt

  使用 open(r'C:\a\b\c\d.txt')  在路径字符串前面加一个r

     使用 open('C:/a/b/c/d.txt')

  使用 open('d.txt')   绝对路径

 

操作文件

  在Python中内置一个open对象是操作文件的方法。

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

  

 文件操作流程

#1. 打开文件,得到文件句柄并赋值给一个变量
#2. 通过句柄对文件进行操作
#3. 关闭文件

  

#1. 打开文件,得到文件句柄并赋值给一个变量
f=open('a.txt','r',encoding='utf-8') #默认打开模式就为r

#2. 通过句柄对文件进行操作
data=f.read()

#3. 关闭文件
f.close()

 

注意!!!  

#第一点:
打开一个文件包含两部分资源:操作系统级打开的文件+应用程序的变量。在操作完毕一个文件时,必须把与该文件的这两部分资源一个不落地回收,回收方法为:
1、f.close() #回收操作系统级打开的文件
2、del f #回收应用程序级的变量
 
推荐傻瓜式操作方式:使用with关键字来帮我们管理上下文
with open('a.txt','w') as f:
    pass
 
with open('a.txt','r') as read_f,open('b.txt','w') as write_f:
    data=read_f.read()
    write_f.write(data)
#第二点:
f=open(...)是由操作系统打开文件,那么如果我们没有为open指定编码,操作系统会用自己的默认编码去打开文件,在windows下是gbk,在linux下是utf-8。
文件以什么方式存的,就要以什么方式打开。

f=open('a.txt','r',encoding='utf-8')

 打开文件的模式

访问模式说明
r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
w 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
a 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
rb 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。
wb 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
ab 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
r+ 打开一个文件用于读写。文件指针将会放在文件的开头。
w+ 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
rb+ 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
wb+ 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
ab+ 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。

 

操作文件的方法

   f.read() # 读取所有内容,光标移动到文件末尾

   f.readline() # 读取一行的内容,光标移动到第二行首部

   f.readlines() # 读取每一行内容,返回列表

 

  data = '写入内容'

  f.write(data) # 写入文件,需要自己添加换行   

  f.write(data,encoding='utf-8')# 写入文件并且指定写入文件的编码格式

     f.writeline(['1','2','3']) # 文件以列表形式写入

 

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

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

   f.closed #  文件是否关闭

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

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

   f.name # 文件名称

 

文件内光标移动

  一: read(3):

     1. 文件打开方式为文本模式时,代表读取3个字符

        2. 文件打开方式为b模式时,代表读取3个字节

  二: 其余的文件内光标移动都是以字节为单位如seek,tell,truncate

  注意:

     1. seek有三种移动方式0,1,2,其中1和2必须在b模式下进行,但无论哪种模式,都是以bytes为单位移动的

        2. truncate是截断文件,所以文件的打开方式必须可写,但是不能用w或w+等方式打开,因为那样直接清空文件了,所以truncate要在r+或a或a+等模式下测试效果

文件的修改

 

  文件是存在硬盘上的,因而只存在覆盖,不存在修改如果想要修改文件就如下两种方式。

  方式一:将硬盘存放的该文件的内容全部加载到内存,在内存中是可以修改的,修改完毕后,再由内存覆盖到硬盘

  方式二:将硬盘存放的该文件的内容一行一行地读入内存,修改完毕就写入新文件,最后用新文件覆盖源文件

# -*- coding: utf-8 -*-

# 声明字符编码
# coding:utf-8
import os

# with open('../files/a.txt', 'r', encoding='utf-8') as a_f, open('../files/b.txt', 'w', encoding='utf-8') as b_f:
#     a_data = a_f.read()
#     a_data = a_data + "方式二:将硬盘存放的该文件的内容一行一行地读入内存,修改完毕就写入新文件,最后用新文件覆盖源文件"
#     b_f.write(a_data)
# os.remove('../files/a.txt')
# os.rename('../files/b.txt', '../files/a.txt')


with open('../files/a.txt', 'r', encoding='utf-8') as a_f, open('../files/b.txt', 'w', encoding='utf-8') as b_f:
    for line in a_f:
        b_f.write(line)
    b_f.write("方式二:将硬盘存放的该文件的内容一行一行地读入内存,修改完毕就写入新文件,最后用新文件覆盖源文件")
os.remove('../files/a.txt')
os.rename('../files/b.txt', '../files/a.txt')

  

文件操作练习

# -*- coding: utf-8 -*-

# 声明字符编码
# coding:utf-8
# 文件全类容
file_list = []


# 定义文件生成器
def file_generator():
    with open('../files/haproxy.conf', 'r', encoding='utf-8') as f:
        for row in f:
            yield row


# 判断当前内容是否包含
def is_contain(str):
    str = "backend %s" % str
    flag = False
    # 获取读取文件生成器
    generator = file_generator()
    for row in generator:
        r = row.strip()
        file_list.append(r)
        if r == str:
            flag = True

    print(file_list)
    return flag


# 查询
def fetch():
    # 是否查到标识
    flag = False
    print('=========欢迎进入查询功能=========')
    content = input('请输入您要查询的内容:')
    # 获取读取文件生成器
    generator = file_generator()
    backend_data = "backend %s" % content
    for row in generator:
        r = row.strip()
        # 查到了,如果开头为"backend"说明已经结束了。
        if flag is True and r.startswith('backend'):
            break
        if r == backend_data or flag is True:
            flag = True
            # 打印查询到的信息
            print(r)
    else:
        if flag is False:
            print('未查到当前节点下的内容。。。。')


# 新增
def insert():
    # 直接在文件中新加内容
    print('=========欢迎进入新增功能=========')
    content = input('请输入您要新增的内容:')
    if content is None:
        print("新增内容不能为空")
    # 思路也是先查询出原内容,组成列表,通过索引添加内容,在重写到原来的文件中
    pass


# 修改
def update():
    print('=========欢迎进入修改功能=========')
    # data = [{'backend': 'www.oldboy1.org', 'record': {'server': '2.2.2.4', 'weight': 20, 'maxconn': 3000}},{'backend': 'www.oldboy1.org', 'record': {'server': '3.3.3.3', 'weight': 30, 'maxconn': 1000}}]
    content = input('请输入您要查询的内容:').strip()
    # eval 转为列表结构
    data = eval(content)

    if is_contain(data[0]['backend']) is True:
        # 获取要修改的源数据
        old_server_record = '%sserver %s %s weight %s maxconn %s\n' % (' ' * 8, data[0]['record']['server'],
                                                                       data[0]['record']['server'],
                                                                       data[0]['record']['weight'],
                                                                       data[0]['record']['maxconn'])
        # 要修改的数据
        new_server_record = '%sserver %s %s weight %s maxconn %s\n' % (' ' * 8, data[1]['record']['server'],
                                                                       data[1]['record']['server'],
                                                                       data[1]['record']['weight'],
                                                                       data[1]['record']['maxconn'])

        old_server_record = old_server_record.strip()
        new_server_record = new_server_record.strip()
        print(old_server_record)
        print(new_server_record)

        print('修改前列表:')
        print(file_list)
        if old_server_record not in file_list:
            print('你要修改的记录不存在')
        else:
            index = file_list.index(old_server_record)
            file_list[index] = new_server_record
            print('修改后列表:')
            print(file_list)
            # 重新覆盖文件
            with open('../files/haproxy.conf', 'w+', encoding='utf-8') as f:
                # 写入后就变成一行了???
                f.writelines(file_list)

    else:
        print('对不起你要修改的内容不存在。。。')


# 删除
def delete():
    # 思路也是先查询出原内容,组成列表,通过索引删除内容,在重写到原来的文件中
    pass


if __name__ == "__main__":
    msg = """
    1:查询
    2:新增
    3:修改
    4:删除
    5:退出
    """
    msg_dic = {
        '1': fetch,
        '2': insert,
        '3': update,
        '4': delete
    }
    while True:
        print(msg)
        # 接收用户输入并且去除空格
        choice = input("请输入功能选择:").strip()
        if choice == '5': break
        operation = msg_dic.get(choice)
        # print(operation) # 打印的是函数地址
        if operation is not None:
            # 调用函数
            operation()
        else:
            print("系统暂无此功能。。。")

  

 文件夹及路径操作方法

  对于文件夹的操作,首先我们要导入os模块

import os

=====OS模块====

os.getcwd():获取当前路径
os.listdir():展示当前目录内容 返回一个列表
os.chdir():改变当前路径
os.mkdir():创建目录
os.rmdir():删除目录
os.remove():删除文件
os.rename():重命名

os.path.isdir():判断是否是一个目录
os.path.isfile():判断是否是一个文件
os.path.join():路径拼接
os.path.dirname():所在目录/父及目录
os.path.abspath():绝对路径
os.path.relpath():相对路径
os.path.normpath():规范化路径
os.path.getsize():资源大小
os.path.getctime/getatime/getmtime:资源时间
os.path.exists():路径是否存在
os.path.isabs():是否是绝对路径


'''

  

 

posted @ 2018-06-28 11:23  begrateful  阅读(539)  评论(1编辑  收藏  举报