Python文件操作

本文主要记录Python中的文件的常用操作

1.文件操作的流程

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

2.打开文件的常用模式

有以下2个示例文件:

# hello_gbk.txt文件为GBK编码,hello_utf8.txt文件为utf-8编码

Somehow, it seems the love I knew was always the most destructive kind
不知为何,我经历的爱情总是最具毁灭性的的那种
Yesterday when I was young
昨日当我年少轻狂
The taste of life was sweet
生命的滋味是甜的
As rain upon my tongue
就如舌尖上的雨露
I teased at life as if it were a foolish game
我戏弄生命 视其为愚蠢的游戏
View Code

2.1.一般模式

"r"模式

#"r"只读模式,是默认模式,默认编码是gbk,不可写

# print(f.read(10))        # 默认读全文,可以按照指定字符数量读文件内容
# print(f.readline(10))     # 默认读取一行,遇到\r或者\n为止,适合读小文件,也可以按照指定字符数量读文件内容
# print(f.readlines(1))       # 默认读取全文转换为带\n的列表,括号中指定数字,读取第一行
# print(f.readlines()[3])     # 可以用这种方式读取出某4行

实例1:文件读取

f = open(file='hello_gbk.txt',mode='r',encoding='gbk')    # 标准完整格式,文件名可以加绝对路径
# f = open('hello_gbk.txt')                   # 最简单的写法
# f = open('hello_gbk.txt',encoding='gbk')           # 简写2,最后的encoding必须写上
print(f.readline())                      # 读一行内容
print('分隔线'.center(50,'-'))
data = f.read()                                   # 读取剩下的所有内容,文件大时不要用
print(data)                                     #打印文件
f.close()                                      #关闭文件

注解:
mode='r' encoding='utf-8' #表示 只读 硬盘上的0101按照utf-8的规则去‘断句’,再将断句后的每一段0101转换成Unicode的01010,Unicode对照表中0101和字符的对应关系。
mode='rb' # 以什么形式存的就以什么形式读 ,二进制打开,给机器看的,用于视频,图片,网络传输

实例2:读前3行内容--->思路:使用循环
# 简单想法:尝试以下3种方式

# 方法1:
f = open(file='hello_gbk.txt',mode='r',encoding='gbk')
for i in range(3):
    print(f.readline().strip())

# 方法2:
f = open(file='hello_gbk.txt',mode='r',encoding='gbk')
for index,line in enumerate(f.readlines()):
    if index == 5:
        print("--------")
        exit()
    print(line.strip())
# 注意:以上2中方法在读大文件的时候可能会把内存撑爆,所以readline()的方式不能用于读大文件

# 方法3:优化后,读一行删一行,内存中只保留一行内容,如下:
f = open(file='hello_gbk.txt',mode='r',encoding='gbk')
count = 0
for line in f:                            # 不是列表了,变成了文件迭代器
    if count == 5:
        print("----------")
        count += 1
        exit()
    print(line.strip())
    count += 1
# 这种方法3是读取文件的最优方法

"w"模式 

# "w"创建文件,不可读文件,如果有同名文件则相当于清空数据,重新写入,所以要慎用

实例1:创建文件

f = open("hello2.txt",'w')                      # 不指定编码,默认创建gbk格式的文件
f.write("hello2")
f.close()

f = open("hello2.txt",'w',encoding='utf-8')         # 如果要创建指定编码格式的文件,需要加“encoding=”字段
f.write("hello2") 
f.close()
注意:在pycharm中写的内容用的是unicode,但在保存成txt文件时会自动转码为GBK的

"a"模式 

# "a"追加,但不可读文件,使用a可以直接打开文件,然后直接追加内容

实例1:追加内容

f = open("hello2.txt",'a',encoding='gbk')
f.write("\n我是追加的内容1")                   # 写入的内容需要和原文件编码相同,否则会出现部分乱码,\n用于换行
f.close()

2.2.混合读写模式

"r+"模式  

# "r+"读写模式。可读,可写,可追加。偶尔用

实例1:追加写入文件内容

f = open("hello2.txt",'r+',encoding='gbk')         # 使用"r+",不管怎样移动光标,文字都会追加到文件最后
data = f.read()                                 # 必须先读到内存中,然后追加,最后写回文件中
print(data)
f.write("\n再写点东西")
f.close()

"w+"模式

# "w+",写读模式,会先创建一个文件再写入,也就是清空文件内容,慎用(不用)

实例1:

f = open("hello2.txt",'w+',encoding='gbk')
data = f.read()
print(data)                                       # 先创建空文件,所以读不出内容,也就无打印
f.write("\n我还要写点东西")
f.close()

"a+"模式 

# "a+",同a,追加模式,可读(可用)

2.3.二进制模式,"b"表示处理二进制文件

二进制"rb"模式

#1)网络传输:FTP发送上传ISO镜像文件,linux可忽略,windows处理二进制文件时需标注
#2)音视频文件读写

实例1:

f = open("hello3.txt",'rb')                   # 使用二进制写模式rb打开文件,不需要使用encoding='gbk'
print(f.read())                               # 打印的是二进制额bytes数据
f.close()

# 实例2:调用chardet模块(需要单独安装),推断文件的编码格式

pip3 install chardet 
import chardet
result = chardet.detect(open(file='hello3.txt',mode='rb').read())
print(result)
--->{'encoding': 'GB2312', 'confidence': 0.99, 'language': 'Chinese'}

二进制"wb"模式 

# 用二进制创建文件,音视频,图片或者其他任何数据等,可以直接传输,可以手动编码
实例1:

f = open("hello3.txt",'wb')                      # 使用二进制写模式wb打开文件,不需要使用encoding='gbk'
f.write("hello3中国你好,二进制写一句".encode('gbk'))    # 使用二进制写入“hello3”,需要转码,否则报错,可以指定GBK,utf-8等进行编码
f.close()   

二进制"ab"模式

# 二进制方式追加文件内容
实例1:

f = open("hello3.txt",'ab')                        # 使用二进制追加模式ab打开,进行追加,不需要使用encoding='gbk'
f.write("\n我是用二进制追加的内容".encode('gbk'))      # 如果使用二进制方式ab写文件,需要转码,否则报错
f.close()

2.4.兼容读写模式

# 用于windows和linux的兼容
"U"表示在读取时,可以将 \r \n \r\n自动转换成 \n (与 r 或 r+ 模式同使用)

rU
r+U

3.文件的其他操作方法:

3.1.刷新缓存 

# f.flush()将内存中的内容手动刷新到硬盘中,需要到windows的客户端里测试刷新效果--------------------------------

f = open("hello3.txt", 'w')
f.write("\ntest flush")
f.flush()
f.close()

# 拓展:进度条

import sys,time
for i in range(50):
    sys.stdout.write("#")     # 默认不换行
    sys.stdout.flush()
    time.sleep(0.5)

3.2.移动光标

# f.tell()返回当前操作的文件的光标位置
# f.seek()移动光标到指定位置
# f.read()是按照字符读文件,f.tell()和.seek()是按照字节读文件

# 拓展:不同的字符编码中,每个字符所占用的字节长度不一样,所以在不同的编码中同一个字的seek就不同
1)ASCII码一个字符默认占1个字节,8位,不能存中文,所以出了Unicode
2)GBK中:一个中文字符占用2个字节,1个英文字符占用1个字节
3)utf-8是一个汉字占用3个字节,所有的英文用ASCII码存,一个字符默认占1个字节,8位
4)unicode中:一个中文字符占2个字节,16位,

# 实例:不同字符编码下的光标位置

使用GBK

f = open("hello_gbk.txt","r",encoding="gbk")
f.seek(13)                             # 光标移动13个字节,在GBK下中文占2个字节,英文占1个字节
print(f.read(10))                      # 读10个字符,不区分中英文
print(f.tell())                        # 回车\n也计算了一个字节
f.close()

使用utf-8

f = open("hello_utf8.txt","r",encoding="utf8")
f.seek(13)                              # 光标移动13个字节,在utf-8下中文占3个字节,英文占1个字节,注意文件开头占3个字节
print(f.read(10))                       # 可以看到与上面的结果不相同
print(f.tell())
f.close()

3.3.截取文件内容

# .truncate()从第n个字符截断(去掉)文件内容
1)指定长度:截取文件开头到指定长度位置的字符内容
2)不指定长度:截取文件开头到光标所在位置的字符内容

# 实例1:截取开头10个字符的内容

# 方法1:截取开头到指定长度的字符,简单高效
f = open("hello3.txt", 'r+', encoding='gbk')      # 使用"r+"或"a"
f.seek(100)                                       # 与光标在哪无关
print(f.tell())
f.truncate(10)
f.close()

# 方法2:移动光标,从开头截取到光标位置
f = open("hello3.txt",'r+',encoding='gbk')        # 使用"r+"或"a"
f.seek(10)
print(f.tell())
f.truncate()
f.close()

3.4.其他一些简单的方法:

f.fileno()      用于返回文件句柄在内核中的索引值,在做IO多路复用时可以用到,一般用不到
f.isatty()      判断是否是个终端文件
f.seekable()     判断文件是否可进行seek操作 
f.readable()     判断文件是否可读,w不可读
f.writable()     判断文件是否可写
f = open("hello_gbk.txt",'r+',encoding='utf-8')    # 使用"r+"
print(f)
print(f.encoding)                       # 打印文件的编码格式,注意后面不加括号
print(f.name)                           # 打印文件的名字
print(f.buffer)
print(f.errors)

4.with语句,自动关闭文件

# 为了避免打开文件后忘记关闭,可以通过with方法打开文件

with open("hello2.txt",'r',encoding='gbk') as f:
    print(f.read())

# 如果一次打开较多文件,建议换行书写代码

with open("hello2.txt") as f1 ,\
     open("hello3.txt") as f2:
    for i1 in f1:
        print(i1.strip())
    for i2 in f2:
        print(i2.strip())

5.修改文件内容的一般方法:

1)类似vim这种,将修改的文件内容加载到内存中,修改完保存到源文件中
内存中的内容不存在写数据就覆盖的问题会自动移位
但是如果打开大文件,内存可能不够,或者系统变慢
2)读到缓存文件中逐行读写,修改完使用临时文件覆盖原文件

import os
f_name = "hello3.txt"
f_new_name = "%s.new" %(f_name)
old_str = "[[改了又改]]"                        # find_str = sys.argv[1]
new_str = "[想改就改,改的响亮]"                 # replace_str = sys.argv[2]
f = open(f_name,'r',encoding="gbk")
f_new = open(f_new_name,'w',encoding="gbk")
for line in f:
    if old_str in line:
        new_line = line.replace(old_str,new_str)   # new_line = line.replace(find_str,replace_str)
    else:
        new_line = line
    f_new.write(new_line)
f.close()
f_new.close()
os.replace(f_new_name,f_name)
# os.rename(f_new_name,f_name)                 # mac,linux

 

完毕,呵呵呵呵

posted @ 2018-01-03 17:03  天生帅才  阅读(562)  评论(0编辑  收藏  举报
// 百度统计