文件处理

Python处理文件

文件操作分为读、写、修改。

读文件

实例1:

f = open(file="nginx.conf", mode="r", encoding="utf-8")
data = f.read()
f.close()

上述操作语法解释

file="nginx.conf"        # 表示文件路径 
mode="r"            # 表示只读(可以修改为其它)
encoding="utf-8"        # 表示将硬盘上的二进制按照utf-8的规则去“断句”,再将“断句”后的每一段二进制转换成unicode的 二进制,unicode对照表中有二进制和字符的对应关系。
data = f.read()        # 表示读取所有内容,内容是已经转换完毕的字符串。
f.close()            # 表示关闭文件

实例2:

f = open(file="nginx.conf", mode="rb")
data = f.read()
f.close()

上述操作语法解释

file="nginx.conf"        # 表示文件路径 
mode="rb"            # 表示只读(可以修改为其它)
data = f.read()        #  表示读取所有内容,内容是硬盘上原来以某种编码保存的 010101010,即:某种编码格式的字节类型。
f.close()            # 表示关闭文件

示例2与示例1的区别:

在于示例2打开文件时并未指定encoding,这是为何?是因为直接以rb模式打开了文件 ,rb是指二进制模式,数据读到内存里直接是bytes格式,如果想内容,还需要手动decode,因此在文件打开阶段,不需要指定编码

假如你不知道你要处理的文件是什么编码可怎么办呢?

import chardet
f = open('nginx.conf', mode="rb")
data = f.read()
f.close()

# result = chardet.detect(open('nginx.conf', mode="rb").read())
result = chardet.detect(data)

print(result)

输出:

{'encoding': 'utf-8', 'confidence': 0.99, 'language': ''}

注意:

  • 文件操作时,以 “r”或“rb” 模式打开,则只能读,无法写入;
  • 硬盘上保存的文件都是某种编码的0101010,打开时需要注意:
    • rb,直接读取文件保存时原生的0101010,在Python中用字节类型表示
    • r和encoding,读取硬盘的0101010,并按照encoding指定的编码格式进行断句,再将“断句”后的每一段0101010转换成unicode的 010101010101,在Python中用字符串类型表示

循环文件

f = open("nginx.conf", mode="r", encoding="utf-8")    # 打开文件

for line in f:                # 循环每行
    print(line)

f.close()

 

写文件

f = open(file="nginx.conf", mode="w", encoding="utf-8")

f.write("Nginx是一款高性能的 Web和 反向代理 服务器")

f.close()

上述操作语法解释:

file="nginx.conf"        #  表示文件路径
mode="w"            #  表示只写
encoding="utf-8"        #  将要写入的unicode字符串编码成utf-8格式

f.write(...)            # 表示写入内容,写入的内容是unicode字符串类型,内部会根据encoding转换为制定编码的 01101010101,即:字节类型

f.close()

二进制写

f = open(file="nginx.conf", mode="wb")

f.write("Nginx是一款高性能的 Web和 反向代理 服务器")

f.close()

上述操作语法解释:

file="nginx.conf"       #  表示文件路径
mode="wb"                #  表示只以2进制模式写

f.write(...)                # 表示写入内容,写入的内容必须字节类型,即:是某种编码格式的0101010

f.close()

注意:

文件操作时,以 “w”或“wb” 模式打开,则只能写,并且在打开的同时会先将内容清空。

写入到硬盘上时,必须是某种编码的0101010,打开时需要注意:

  • wb,写入时需要直接传入以某种编码的0100101,即:字节类型
  • w 和 encoding,写入时需要传入unicode字符串,内部会根据encoding制定的编码将unicode字符串转换为该编码的 010101010

追加

把内容追加到文件尾部

f = open(file="nginx.conf", mode="a", encoding="utf-8")

f.write("在高连接并发的情况下,Nginx是Apache服务器不错的替代品。\n")

f.close()

运行结果

# 运行三次效果
在高连接并发的情况下,Nginx是Apache服务器不错的替代品。
在高连接并发的情况下,Nginx是Apache服务器不错的替代品。
在高连接并发的情况下,Nginx是Apache服务器不错的替代品。

注意:

文件操作时,以 “a”或“ab” 模式打开,则只能追加,即:在原来内容的尾部追加内容

写入到硬盘上时,必须是某种编码的0101010,打开时需要注意:

  • ab,写入时需要直接传入以某种编码的0100101,即:字节类型
  • a 和 encoding,写入时需要传入unicode字符串,内部会根据encoding制定的编码将unicode字符串转换为该编码的 010101010

读写模式(混合模式)

打开模式只有只读、只写、只追加,难道没有可以读写的操作吗?当然有

f = open(file="nginx.conf", mode="r+", encoding="utf-8")
data = f.read()                    # 可以读
print(data)
f.write("--------------------->\n")                # 可以写
f.close()

写读模式

f = open(file="nginx.conf", mode="w+", encoding="utf-8")
data = f.read()
print(data)
f.write("\nnewline 1哈哈")
f.write("\nnewline 2哈哈")
f.write("\nnewline 3哈哈")
f.write("\nnewline 4哈哈")
print("content", f.read())
f.close()

文件操作的其它功能

def fileno(self, *args, **kwargs): # real signature unknown
        返回文件句柄在内核中的索引值,以后做IO多路复用时可以用到

    def flush(self, *args, **kwargs): # real signature unknown
        把文件从内存buffer里强制刷新到硬盘

    def readable(self, *args, **kwargs): # real signature unknown
        判断是否可读

    def readline(self, *args, **kwargs): # real signature unknown
        只读一行,遇到\r or \n为止

    def seek(self, *args, **kwargs): # real signature unknown
        把操作文件的光标移到指定位置
        *注意seek的长度是按字节算的, 字符编码存每个字符所占的字节长度不一样。
        如“路飞学城” 用gbk存是2个字节一个字,用utf-8就是3个字节,因此以gbk打开时,seek(4) 就把光标切换到了“飞”和“学”两个字中间。
        但如果是utf8,seek(4)会导致,拿到了飞这个字的一部分字节,打印的话会报错,因为处理剩下的文本时发现用utf8处理不了了,因为编码对不上了。少了一个字节

    def seekable(self, *args, **kwargs): # real signature unknown
        判断文件是否可进行seek操作

    def tell(self, *args, **kwargs): # real signature unknown
        返回当前文件操作光标位置 

    def truncate(self, *args, **kwargs): # real signature unknown
        按指定长度截断文件
        *指定长度的话,就从文件开头开始截断指定长度,不指定长度的话,就从当前位置到文件尾部的内容全去掉。

    def writable(self, *args, **kwargs): # real signature unknown
        判断文件是否可写

修改文件

占硬盘方式的文件修改代码示例

f_name = "兼职白领学生空姐模特护士联系方式utf8.txt"
f_new_name = "%s.new" % f_name

old_str = "乔亦菲"
new_str = "[乔亦菲 Yifei Qiao]"

f = open(f_name,'r',encoding="utf-8")
f_new = open(f_new_name,'w',encoding="utf-8")

for line in f:

    if old_str in line:
        new_line = line.replace(old_str,new_str)
    else:
        new_line = line

    f_new.write(new_line)

f.close()
f_new.close()

上面的代码,会生成一个修改后的新文件 ,原文件不动,若想覆盖原文件

import os

f_name = "兼职白领学生空姐模特护士联系方式utf8.txt"
f_new_name = "%s.new" % f_name

old_str = "乔亦菲"
new_str = "[乔亦菲 Yifei Qiao]"

f = open(f_name,'r',encoding="utf-8")
f_new = open(f_new_name,'w',encoding="utf-8")

for line in f:

    if old_str in line:
        new_line = line.replace(old_str,new_str)
    else:
        new_line = line

    f_new.write(new_line)

f.close()
f_new.close()

os.rename(f_new_name,f_name) #把新文件名字改成原文件 的名字,就把之前的覆盖掉了,windows使用os.replace # 帮助文档说明replace会覆盖原文件

 

文件打开方式明细:

文件打开方式

posted @ 2018-06-25 22:27  以后、  阅读(94)  评论(0)    收藏  举报