python文件操作

文件处理流程

  1.     打开文件,得到文件句柄并赋值给一个变量
  2.  通过句柄对文件进行操作
  3.  关闭文件
1 f = open(file='D:/工作日常/text.txt',mode='r',encoding='utf-8')

打开模式:

文件的打开模式 mode
r 只读模式,文件不存在时会报错。
w 写入模式,文件存在会清空之前的内容,文件不存在则会新建文件。
x 写入模式,文件存在会报错,文件不存在则会新建文件。
a 追加写入模式,不清空之前的文件,直接将写入的内容添加到后面。
b 以二进制模式读写文件,wb,rb,ab。
+ 可读写模式,r+,w+,x+,a+,这几种模式还遵循了r,w,x,a的基本原则。

文件的encoding

根据文件的encoding格式打开文件,windows默认GBK,MAC和linux默认UTF-8

当使用wb,rb,ab模式读取文件时,不用填写encoding

# 以二进制形式打开文件不需要编码
f = open(r"text.txt", "wb")
f.write("路飞\n".encode())  # 写入utf-8二进制字节码
f.write("路飞 Yifei Qiao]".encode())
f.close()

 

如果文件encoding格式为utf-8,打开encoding格式为GBK则读取文件会报错

检查文件编码

import chardet
"""
安装模块pip install chardet
"""
# 检测文件编码 要以二进制形式读取
result = chardet.detect(open(r"text.txt", "rb").read())
print(result)
# {'encoding': 'utf-8', 'confidence': 0.938125, 'language': ''}

 

基本操作

基本使用方法

#文件的读取
f.read(size)  #读取文件的内容,将文件的内容以字符串形式返回。
'''
size是可选的数值,指定字符串长度,如果没有指定size或者指定为负数,就会读取并返回整个文件。
当文件大小为当前机器内存两倍时就会产生问题,反之就尽可能大的size读取和返回数据,如果到了文件末尾,会返回空字符串。
'''

f.readline() #从文件中读取单独一行。
'''
字符串结尾会自动加上一个换行符\n,只有当文件最后没有以换行符结尾时,
这一操作才会被忽略,这样返回值就不会有混淆。如果返回空字符串,表示到达率文件末尾,如果是空行,就会描述为\n,一个只有换行符的字符串。
'''

f.readlines() #一次读取所有,返回一个列表,列表的元素为文件行的内容。
'''可以通过列表索引的方式将文件的每一行的内容输出。
可以通过for循环迭代输出每一行的信息。
'''

f.flush()
#把文件从内存buffer里强制刷新到硬盘

#文件的写入
f.write()         #将要写入的内容以字符串的形式通过write方法写入文件中。
f.writelines()  #括号里必须是由字符串元素组成的序列。

f.close() 
#关闭文件。对一个已经关闭的文件进行操作会报错。

#光标位置
f.tell()             #返回光标在文件中的位置。
f.seek(offset,from)
#在文件中移动文件指针,从from(0代表起始位置,1代表当前位置,2代表文件末尾)偏移offset个字节。

#查看文件信息
closed         #查看文件是否已经关闭,返回布尔值。
mode         #返回文件打开模式。
name         #返回文件名。


#with 形式打开文件,里面的语句执行完后会自动关闭文件
with open('文件名','r') as f:
    f.read() 
    

#读大文件(大于10M以上)
f = open("联系方式.txt",'r',encoding="utf-8")

for line in f:
    print(line)

f.close()

 

代码举例

# #只读模式
f=open(r'new.txt',encoding='utf-8')
print('====>1',f.read())
print('====>2',f.read())
print(f.read())
print(f.readlines())
f.close()

#写模式:文件不存在则创建,文件存在则覆盖原有的
f=open("new.txt",'w',encoding='utf-8')
f.write('111\n')
f.writelines(['2\n','3\n'])
f.close()

# 追加模式:文件不存在则创建,文件存在不会覆盖,写内容是追加的方式写
f=open('new.txt','a',encoding='utf-8')
f.write('123\n')
f.writelines(['aa\n','bb\n'])
f.close()

# 以二进制形式打开文件不需要编码
f = open(r"text.txt", "wb")
f.write("路飞\n".encode())  # 写入utf-8二进制字节码
f.write("路飞 Yifei Qiao]".encode())
f.close()

# 追加方式进行修改
f = open(r"兼职护士联系方式.txt",'ab')
f.write("\n肛娘    北京  167  55  13523230322".encode("gbk"))
f.close()

#读写方式修改
f = open(r"兼职白领学生空姐模特护士联系方式.txt",'r+')
f.seek(10)
print(f.tell())
f.write("[路飞学城 luffycity]")
f.close()

 

文件内光标移动

一: read(3):

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

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

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

注意:

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

      seek控制光标的移动,是以文件开头作为参照的。

   tell当前光标的位置

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

    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
        按指定长度截断文件
        *指定长度的话,就从文件开头开始截断指定长度,不指定长度的话,就从当前位置到文件尾部的内容全去掉。

 

文件操作案例

拷贝文件

#利用b模式,编写一个cp工具
# b模式
f=open('1.jpg','rb')
data=f.read()
# print(data)
f=open('2.jpg','wb')
f.write(data)
print(data)

文件修改替换(硬盘上修改)

#_*_coding:utf-8_*_
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) # 把新文件名字改成原文件的名字,就把之前的覆盖掉了

文件修改替换(内存中修改)

举例1:

f = open(r"斗罗大陆.txt", "r+")
l = f.readlines()
f.seek(0)  # 指针指向文件开头
old_str = "唐三"
new_str = ""
for line in l[0::2]:  # 只取部分字符
     if old_str in line:
         line = line.replace(old_str,new_str)
     f.write(line+"\n")
f.truncate()
# 对文件进行截取,如果文件之前为100M,
# 修改后文件只覆盖了50M,如果不使用truncate不会整体覆盖,只会部分覆盖,后面剩余的50M内容会追加新文件中,修改后的文件大小不变
# 使用truncate后,文件就只有50M,他会把剩余的50M内容从当前write的指针后面进行截取
f.close()

 举例2:

"""
reform.txt
大胆点,伟大无比的力量自会来帮助你。——比锡耳王

大胆是取得进步所付出的代价。——雨果

不怕的人前面才有路。——有岛武信

世界是属于勇敢者的。——哥伦布

走自己的路,叫别人去说吧。——但丁

死是每个人都能做到的,拿出勇气活下去才是勇敢。——罗教·柯迪

人的一生中可能犯的错误,就是经常担心犯错误。——哈伯德

没有比害怕本身更害怕的了。——培根

你怕狼,就别到树林里去。——列宁

人生自古谁无死,留取丹心照汗青。——文天祥

未完待续……
"""

"""
把文件reform.txt中的名人名言,改成“某某说:......”的形式,
把文件读入到内存中修改
"""
f = open(r"reform.txt", "r+")
l = f.readlines()
f.seek(0)  # 指针指向文件开头
for line in l[::2]:  # 去掉空行"\n"字符
    # ['大胆点,伟大无比的力量自会来帮助你。', '比锡耳王']
    print(line)
    if "——" in line:
        old_str_li = line[:-1].split("——")  # 去掉每行"\n"字符,按"——"进行分割
        new_str = old_str_li[-1]+"说:"+old_str_li[0]
        f.write(new_str+"\n\n")  # 写入修改内容
    else:
        f.write(line + "\n\n")  # 写入以前内容
f.truncate()  # 对文件进行截取,进行整体覆盖
f.close()

 Linux文件中字符替换

#!/usr/bin/env python3 
# -*- coding: utf-8 -*-
# @Time    : 2018/3/14 10:05
# @Author  : hyang
# @File    : fileStrReplace.py
# @Software: PyCharm

import sys
import os


def print_arg(arg):
    """
    打印参数
    :param arg:
    :return:
    """

    for ind, val in enumerate(arg):
        if ind == 0:
            print(r"------执行%s输入参数为--------"% val)
        else:
            print(val, end=",")
    print()


# 获得系统参数
v_arg = sys.argv


if len(v_arg) != 4:
    print_arg(v_arg)
    print("---参数输入错误--")
    print("fileStrReplace.py 文件名 旧字符串 新字符串")
else:
    f_name = v_arg[1].strip()
    old_str = v_arg[2].strip()  # 旧字符
    new_str = v_arg[3].strip()  # 替换的新字符
    f_new_name = "%s.new" % f_name
    replace_count = 0  # 字符替换次数
    if not os.path.exists(f_name):
        print("%s文件不存在" % f_name)
    else:
        f_new = open(f_new_name, 'w')
        f = open(f_name, "r",)
        for line in f:  # 读取大文件
            if old_str in line:
                new_line = line.replace(old_str, new_str)  # 字符替换
                replace_count += 1
            else:
                new_line = line

            f_new.write(new_line)  # 内容写新文件

        f.close()
        f_new.close()
        os.remove(f_name)  # 删除原始文件
        os.rename(f_new_name, f_name) # 把新文件名字改成原文件的名字,就把之前的覆盖掉了
        if replace_count == 0:
            print("字符%s不存在" % (old_str))
        else:
            print("文件替换成功,字符%s替换了%s次" % (old_str, replace_count))

执行结果

 

 

删除某一目录下所有文件或文件夹

def del_file(filepath):
    """
    删除某一目录下所有文件或文件夹
    """
    if os.path.exists(filepath):
        # 判断文件夹是否存在
        del_list = os.listdir(filepath)
        for f in del_list:
            f_path = os.path.join(filepath,f)
            if os.path.isfile(f_path):
                os.remove(f_path)
            elif os.path.isdir(f_path):
              shutil.rmtree(f_path)

 


 

posted @ 2018-03-14 02:48  一只小小的寄居蟹  阅读(1004)  评论(0编辑  收藏  举报