python 文件处理

一、概述

数据的存储可以使用数据库,也可以使用文件。

数据库保持了数据的完整性和关联性,且使用数据更安全、可靠。使用文件存储数据则非常简单、易用,不必安装数据库管理系统等运行环境。

文件通常用于存储应用软件的参数或临时性数据,是一个命名的比特集合,存储在硬盘、U盘、闪存条等辅助存储设备中。

文件分为两类:文本文件和二进制文件。 Python提供了os、os.path、shutil等模块处理文件。

文本文件的特点:

基本是字符串。Python源代码文件和HTML文件等都属于文本文件。

可使用任何文本编辑器进行编辑,对人来说相对容易阅读和修改。

对程序来说,无法直接阅读文本文件。通常,每种文本文件都需要使用相应的分析程序来阅读,例如,Python使用专用分析程序来帮助阅读.py文件,而要阅读HTML文件,需要使用专用于HTML的分析程序。

通常比等价的二进制文件大。需要通过网络发送大型文本文件时,一般要进行压缩(如压缩成zip格式),以提高传输速度和节省磁盘空间。

二进制文件的特点:

通常是人无法直接阅读的,且使用常规的文本编辑器无法查看。在文本编辑器中打开二进制文件时,显示的是一堆乱码。有些类型的二进制文件(如JPEG图像)需要使用特殊查看器显示其内容。

占据的空间通常比等价的文本文件小。

对程序来说,可以直接阅读二进制文件。虽然二进制文件各不相同,但通常无需编写复杂的分析程序来读取它们。

二、文件的常见操作

  • 打开文件: 建立磁盘上的文件与程序中的对象相关联 ;通过相关的文件对象获得
  • 文件操作: 读取、写入 复制、删除 ;定位; 其他:追加、计算等  
  • 关闭文件 :切断文件与程序的联系; 写入磁盘,并释放文件缓冲区 

1、文件的创建

文件的打开或创建可以使用open函数。该函数可以指定处理模式,设置打开的文件为只读、只写或可读写状态。

格式1: open(file, [mode[,  buffering]])—>file object

格式2:with open(file, [mode[,  buffering]]) as file object name

  • 参数file是被打开的文件名。若文件file不存在,open()将创建该文件,然后再打开该文件。
  • 参数mode是指文件的打开模式(默认r)。打开模式如表8-1。
  • 参数buffering设置缓存模式。0表示无缓冲;1表示行缓冲;如果大于1则表示缓冲区的大小,,-1(或者任何负数,默认为-1)代表使用默认的缓冲区大小。以字节为单位。
  • open()返回1个file对象,file对象可以对文件进行各种操作。

参数

描述

r

只读模式,如果文件不存在,返回异常FileNotFoundError,默认值

w

覆盖写模式,文件不存在则创建,存在则完全覆盖

x

创建写模式,文件不存在则创建,存在则返回异常FileExistsError

a

追加写模式,文件不存在则创建,存在则在文件最后追加内容

t

文本文件模式,默认值

b

二进制文件模式,可与r/w/x/a/+结合使用

+

与r/w/x/a一同使用,在原功能基础上增加同时读写功能

U

支持所有的换行符号。如:’\r’、’\n’、’\r\n’

file类用于文件管理,可以对文件进行创建、打开、读写、关闭等操作。

文件的处理一般分为三个步骤:

  • 创建并打开文件,使用open()函数返回1个file对象。
  • 调用file对象的read()、write()等方法处理文件。
  • 调用close()关闭文件,释放file对象占用的资源(若使用格式2,可省略此步骤)。

 file类的常用属性和方法

属性和方法

描述

closed

判断文件是否关闭,如果文件关闭,返回True

encoding

显示文件的编码类型

mode

显示文件的打开模式

name

显示文件的名称

newlines

文件使用的换行模式

flush()

将缓冲区的内容写入磁盘

close()

关闭文件

read([size])

从文件中读取size个字节的内容,作为字符串返回;默认返回包含整个文件内容的一个字符串 

readline([size])

从文件中读取1行,作为字符串返回。若指定size,表示每行每次读取的字节数,依然要读完整行的内容

readlines([size])

返回值为整个文件内容的列表,每项是以换行符为结尾的一行字符串。若指定size,表示每次读取的字节数

属性和方法

描述

closed

判断文件是否关闭,如果文件关闭,返回True

encoding

显示文件的编码类型

mode

显示文件的打开模式

name

显示文件的名称

newlines

文件使用的换行模式

flush()

将缓冲区的内容写入磁盘

close()

关闭文件

read([size])

从文件中读取size个字节的内容,作为字符串返回;默认返回包含整个文件内容的一个字符串 

readline([size])

从文件中读取1行,作为字符串返回。若指定size,表示每行每次读取的字节数,依然要读完整行的内容

readlines([size])

返回值为整个文件内容的列表,每项是以换行符为结尾的一行字符串。若指定size,表示每次读取的字节数

 2、文件的读取

文件的读取有多种方法,包括: readline() readlines() read()

(1)按行读取方式readline()

readline()每次读取文件中的一行,需要使用永真表达式循环读取文件。但当文件指针移动到文件的末尾时,依然使用readline()读取文件将出现错误。因此程序中需要添加1个判断语句,判断文件指针是否移动到文件的尾部,并且通过该语句中止循环。

(2)多行读取方式

函数readlines()可一次性读取文件中多行数据。例如:readlines(2),可读入两行数据。 使用readlines()读取文件,需要通过循环访问readlines()返回的内容。

(3)一次性读取方式

读取文件最简单的方法是使用read(),read()将从文件中一次性读出所有的内容,并赋值给1个字符串变量。 但这种方式占内存最大。 若read()带有参数,则读入指定字节数。例如,read(5),读入5个字节的数据。

3、文件的写入

从计算机内存向文件写入数据。 文件的写入同样有多种方法,可以使用write()、writelines()方法写入文件。

将字符串写入文件开头:

相比在文件末尾添加字符串,将字符串写入文件开头不那么容易,因为操作系统没有提供这样的支持。 解决的方法是:将文件读取到一个字符串中,将新文本插入到该字符串,再将这个字符串写入原来的文件。

4、文件的删除

删除文件需要使用os模块和os.path模块。

os模块提供了对系统环境、文件、目录等操作系统级的接口函数。

下表列出了os模块常用的文件处理函数。

注意:os模块的open()函数与内置的open()函数的用法不同。

函数

描述

access(path,mode)

按照mode指定的权限访问文件

chmod(path,mode)

改变文件的访问权限

open*filename,flag[,mode=0o777])

按照mode指定的权限打开文件。默认情况下,给所有用户读、写、执行的权限

remove(path)

删除path指定的文件

rename(old,new)

重命名文件或目录。old表示原文件或目录,new表示新文件或目录

stat(path)

返回path指定文件的所有属性

fstat(path)

返回打开的文件的所有属性

lseek(fd,pos,how)

设置文件的当前位置,返回当前位置的字节数

startfile(filepath[,operation])

起动关联程序打开文件。例如:打开的是一个html文件,将启动IE浏览器

tmpfile()

创建一个临时文件,文件创建在操作系统的临时目录中

函数

描述

函数

描述

abspath(path)

返回path所在的绝对路径

isabs(s)

测试路径是否绝对路径

dirname(p)

返回目录的路径

isdir(path)

判断path指定的是否是目录

exists(path)

判断文件是否存在

isfile(path)

判断path指定的是否是文件

getatime(filename)

返回文件的最后访问时间 

split(p)

对路径进行分隔,并以列表方式返回

getctime(filename)

返回文件的创建时间

splitext(p)

从路径中分割文件的扩展名

getmtime(filename)

返回文件的最后修改时间

splitdrive(p)

从路径中分割驱动器的名称

getsize(filename)

返回文件的大小

walk(top,func,arg)

遍历目录数,与os.walk()功能相同

5、文件的复制

file类并没有提供直接复制文件的方法,但可以使用read()、write()方法来实现复制文件的功能。

复制文件的其他方法:

shutil模块是另一个文件、目录的管理接口,提供了一些用于复制文件、目录的函数。

其中,copyfile()函数可以实现文件的复制,move()函数可以实现文件的移动。

 copyfile(src, dst)  

 move(src, dst)

其中,参数src表示源文件的路径,dst表示目标文件的路径,均为字符串类型。

6、文件的重命名

os模块的函数rename()可以对文件或目录进行重命名。 在实际应用中,经常需要将某一类文件修改为另一种类型,即修改文件的后缀名。可以通过函数rename()和字符串查找函数来实现。

7、文件内容的搜索和替换

文件内容的搜索和替换可以使用字符串查找和替换来实现。

8、处理二进制文件

Python中,通常使用pickle模块处理二进制文件。 可以使用pickle.dump将数据结构存储到磁盘,之后再用pickle.load从磁盘获取数据结构。

pickle不能用于读写特殊格式的二进制文件,如各种格式的图像文件。对这种格式的文件,要用专用模块处理(如:PIL库)

 三、目录的常见操作

Python的os模块和os.path模块还提供了一些针对目录操作的函数。

1、创建目录和删除目录 os模块提供的常用目录处理函数见表

函数

描述

mkdir(path[,mode=0o777])

创建path指定的一个目录

makedirs(name[,mode=0o777])

创建多级目录,name表示为“path1\path2\…”

rmdir(path)

删除path指定的目录

removedirs(path)

删除path指定的多级目录

listdir(path)

返回path指定目录下的所有文件名,返回值为列表

getcwd()

返回当前工作目录

chdir(path)

改变当前目录为path指定的目录

walk(op,topdown=True,οnerrοr=None)

遍历目录树

path.isfile(path)

当path指定的是一个文件的名称时,返回True,否则返回False

path.isdir(path)

当path指定的是一个文件夹的名称时,返回True,否则返回False

stat(fname)

返回有关fname的信息,如大小(单位为字节)和最后一次修改时间。详细功能参见在线文档

2、目录的遍历

os.walk()返回的是一个三元组:tupple(dirpath, dirnames, filenames), 其中第一个为起始路径,第二个为起始路径下的文件夹,第三个是起始路径下的文件。 dirpath是一个string,代表目录的路径; dirnames是一个list,包含了dirpath下所有子目录的名字; filenames是一个list,包含了非目录文件的名字。这些名字不包含路径信息,如果需要得到全路径,需要使用 os.path.join(dirpath, name)。

3、其他目录相关操作

返回当前目录中的文件和文件夹; 返回当前目录中的指定类型文件; 返回当前目录中所有文件的大小总和等。

以下为以上内容的部分示例

def make_story():
    f=open('story.txt','w')   
    f.write('Marry had a little lamb,\n')
    f.write('and then she had some more.\n')
    f.close()
    
make_story()
 
 
    
#在文件尾添加内容
def add_to_story(line,fname='story.txt'):
    f=open(fname,'a')
    f.write(line)
    f.close()
    
add_to_story('haha!\n')
 
# 使用readline()读文件
 
f=open('story.txt')
while True:
    line=f.readline()
    if line:
        print(line[:-1]) #去掉每行的换行符
    else:
        break
    
f.close()
print()
 
#多行读取方式,使用readlines()
 
f=open('story.txt')
lines=f.readlines()
for line in lines:
    print(line[:-1])
f.close()
print()
#使用read()读文件
f=open('story.txt')
context=f.read()
print(context)
f.close()
print()
#使用read()返回指定字节的内容
f=open('story.txt')
context=f.read(5) #读取文件前五个字节内容
print(context)
print(f.tell())#返回文件对象当前指针位置
context=f.read(5)#继续读取5个字节内容
print(context)
 
print(f.tell())#输出文件当前指针位置
f.close()
 
 
#使用writelines()写文件
f=open('hello.txt','w+')
context=['hello world!\n','hello China!\n']
f.writelines(context)
f.close()
 
 
#将字符串插入到文件开头
def insert_tilte(title,fname='story.txt'):
    f=open(fname,'r+')
    temp=f.read()
    temp=title+'\n'+temp
    f.seek(0)
    f.write(temp)
    f.close()
 
insert_tilte('long long ago,')
 
 
f=open('companies.txt','w')   
f.write('GOOGLE Inc.\n')
f.write('Microsoft Corporation\n')
f.write('Apple Inc.\n')
f.write('Facebook,Inc\n')
f.close()
 
f1=open('companies.txt','r')
cNames=f1.readlines()
for i in range(0,len(cNames)):
    cNames[i]=str(i+1)+' '+cNames[i]
f1.close()
f2=open(r'scompanies.txt','w')
f2.writelines(cNames)
f2.close()
 
 
#文件的删除
import os
 
open('hello.txt','w')
 
 
if os.path.exists('hello.txt'):
    os.remove('hello.txt')
 
 
 
#用read()、write() 实现文件 复制
 
 
 
#创建文件hello.txt
src=open('hello.txt','w')
context=['hello world\n','hello China\n']
src.writelines(context)
src.close()
 
#将hello.txt 复制到hello2.txt
src=open('hello.txt','r')
dst=open('hello2.txt','w')
dst.write(src.read())
src.close()
dst.close()
 
 
 
 
#使用shutil模块实现文件的复制和移动
import shutil
 
#将hello.txt 的内容复制给hello2.txt
shutil.copyfile('hello.txt','hello2.txt')
 
 #修改文件名
import os
 
ls=os.listdir('.')#返回当前目录的文件列表
if 'hello.txt1' in ls:
    os.rename('hello1.txt','hello.txt')
 
 
 
# 7 从hello.txt 文件中统计字符串‘hello’出现的次数
print()
import re
 
f1=open('hello2.txt','r')
count=0
for s in f1.readlines():
    ls=re.findall('hello',s)
    if len(ls)>0:
        count+=ls.count('hello')
print('查找到'+str(count)+'个hello')
f1.close()
 
 
#将hello.txt 中字符串'hello'全部替换为'hi',并将结果存为hello2.txt中
f1=open('hello.txt','r')
f2=open('hello2.txt','w')
for s in f1.readlines():
    f2.write(s.replace('hello','hi'))
f1.close()
f2.close()
 
 
 
#二进制文件存取
print()
import pickle
 
def make_picked_file():
    grades={'tom':[84,88,90,90],
           'jack':[77,87,97,88],
           'marry':[85,None,90,90],
           'alan':[100,88,90,95]
           }
    outfile=open('grades.dat','wb')
    pickle.dump(grades,outfile)
 
def get_pickle_data():
    infile=open('grades.dat','rb')
    grades=pickle.load(infile)
    return grades
 
make_picked_file()
print(get_pickle_data())
 
 
 
#目录的创建和删除
import os
os.mkdir('hello6') #创建path指定的一个目录
os.rmdir ('hello6')#删除path 指定目录
os.makedirs('1hello\world')
os.removedirs('1hello\world')
 
 
#用递归函数遍历目录
import os
 
def VisitDir(path):
    ls=os.listdir(path) #返回path 指定目录下的所有文件名和目录名
    for p in ls:
        pathname=os.path.join(path,p) #连接两个或多个路径
        if not os.path.isfile(pathname):
            VisitDir(pathname)
        else:
            print(pathname)
 
 
if __name__=="__main__":
    path=r'C:\Users\Administrator\Desktop'
    
    VisitDir(path)
 
 
#使用os.walk
import os
 
 
def VisitDir(path):
    for root,dirs,files in os.walk(path):
        for filepath in files:
            print(os.path.join(root,filepath))
 
if __name__=="__main__":
    path=r'C:\Users\Administrator\Desktop'
    
    VisitDir(path)
 
 
#返回当前目录中的所有文件的大小总和
 
import os
 
 
def list_cwd():
    return os.listdir(os.getcwd()) #返回当前目录中的所有文件名和子目录名
 
def size_in_bytes(fname):
    return os.stat(fname).st_size
 
def cwd_size_in_bytes():
    total=0
    for name in list_cwd():
        total+=size_in_bytes(name)
    return total
 
 
print(cwd_size_in_bytes())
    
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值