python 文件操作总结
声明部分:
本文转载自:https://www.cnblogs.com/wj-1314/p/8476315.html
本人仅做显示格式的调整,及逐行验证代码后,若有bug则校正
印子:
文件操作对于编程语言的重要性不言而喻,如果数据不能持久保存,信息技术也就失去了意义。
文件操作的内容包括打开文件,操作文件,关闭文件
关于文件操作的相关模块请参考博客:https://www.cnblogs.com/wj-1314/p/8557077.html
一,打开文件
python中打开文件的函数为open('filename',mode='r',encode='None'),open函数默认返回文件的句柄,我们可以根据句柄来对文件进行增,删,改,查的操作。将句柄赋给我们定义的变量,假设我们定义变量为f,则f=open('filename',mode='r',encode='utf-8') 或者with open('filename') as f。
注意点: 1.python解释器打开文件时,是对硬盘进行操作,需要内核态才可以操作硬盘,故此时python解释器是调用操作系统的文件读取接口。windows中文版本默认使用GBK编码表,linux默认使用utf-8,所有如果操作的文件在windows下,非GBK编码的,需要在open函数中声明编码类型,使操作系统运用相应的编码规则进行解码读取,防止串码,乱码现象。 2.open主要有三种模式,读(r),写(w),追加(a),其中,默认为读模式。各个模式的详解,见下文。
二,关闭文件
关闭文件有两组方式:
1.使用f.close(),f为open返回的句柄赋值的变量名。 2.程序结束后,自动关闭。第一个方法容易造成文件写操作时,数据的丢失。原因是写数据时,数据会先保存在内存中,文件关闭时才会写入硬盘,此时如果文件未关闭,软件因为异常崩溃,导致内存中的数据丢失,且未写入硬盘中。作为第一种关闭方法的优化,是使用:with open('filename') as f 。with会创建一个程序块,将文件操作置于with程序块下,这样with控制块结束,文件也会自动关闭。 ##语法如下: with open('f1.txt') as f1 , open('f2.txt') as f2: ......
三,操作文件
3.1 file的基本方法
3.2 文件的读取、创建、追加、删除、清空
3.3 python逐行读取文件内容的两种方法
3.4 文件定位
3.5 重命名和删除文件
3.6 文件修改
3.6.1文件修改占硬盘
3.6.2文件修改占内存
四,补充内容
4.1 各种系统操作
注意:虽然python中提供了各种拼接目录的函数,但是,函数并不能保证字符编码不出问题,很大可能导致程序错误。所以最好还是自己拼接。
python中对文件、文件夹(文件操作函数)的操作需要涉及到os模块和shutil模块。
得到当前工作目录,即当前Python脚本工作的目录路径: os.getcwd() 返回指定目录下的所有文件和目录名:os.listdir() 函数用来删除一个文件:os.remove() 删除多个目录:os.removedirs(r“c:\python”) 检验给出的路径是否是一个文件:os.path.isfile() 检验给出的路径是否是一个目录:os.path.isdir() 判断是否是绝对路径:os.path.isabs() 检查是否快捷方式os.path.islink ( filename ) 检验给出的路径是否真地存:os.path.exists() 返回一个路径的目录名和文件名:os.path.split() eg os.path.split('/home/swaroop/byte/code/poem.txt') 结果:('/home/swaroop/byte/code', 'poem.txt') 分离扩展名:os.path.splitext() 获取路径名:os.path.dirname() 获取文件名:os.path.basename() 运行shell命令: os.system() 读取和设置环境变量:os.getenv() 与os.putenv() 给出当前平台使用的行终止符:os.linesep Windows使用'\r\n',Linux使用'\n'而Mac使用'\r' 指示你正在使用的平台:os.name 对于Windows,它是'nt',而对于Linux/Unix用户,它是'posix' 重命名:os.rename(old, new) 创建多级目录:os.makedirs(r“c:\python\test”) 创建单个目录:os.mkdir(“test”) 获取文件属性:os.stat(file) 修改文件权限与时间戳:os.chmod(file) 终止当前进程:os.exit() 获取文件大小:os.path.getsize(filename)
4.2 各种目录操作
os.mkdir("file") 创建目录 复制文件: shutil.copyfile("oldfile","newfile") oldfile和newfile都只能是文件 shutil.copy("oldfile","newfile") oldfile只能是文件夹,newfile可以是文件,也可以是目标目录 复制文件夹: shutil.copytree("olddir","newdir") olddir和newdir都只能是目录,且newdir必须不存在 重命名文件(目录) os.rename("oldname","newname") 文件或目录都是使用这条命令 移动文件(目录) shutil.move("oldpos","newpos") 删除文件 os.remove("file") 删除目录 os.rmdir("dir")只能删除空目录 shutil.rmtree("dir") 空目录、有内容的目录都可以删 转换目录 os.chdir("path") 换路径 ps: 文件操作时,常常配合正则表达式: img_dir = img_dir.replace('\\','/')
五,文件处理习题
文件操作分为读,写,修改
5.1 读文件
##举例如下: f = open(file=‘userinfo.txt',mode='r',encoding='utf-8') data = f.read() f.close() ##上述操作语法解释如下: file='userinfo.txt' #表示文件路径 mode='r' #表示只读(可以修改为其他) encoding='utf-8' #表示将硬盘上的 0101010 按照utf-8的规则去“断句”,再将“断句”后的每一段0101010转换成unicode的 01010101,unicode对照表中有01010101和字符的对应关系。 f.read() #表示读取所有内容,内容是已经转换完毕的字符串。 f.close() #表示关闭文件 ##再看一个例子 f = open(file='userinfo.txt',mode='rb') data = f.read() f.close() ##上述操作语法解释: file='userinfo.txt' #表示文件路径 mode='rb' #表示只读(可以修改为其他) f.read() #表示读取所有内容,内容是硬盘上原来以某种编码保存010101010,即:某种编码格式的字节类型 f.close() #表示关闭文件
问:两个例子的区别在哪?
在于示例2打开文件时并未指定encoding,这是为何?是因为直接以rb模式打开了文件 ,rb是指二进制模式,数据读到内存里直接是bytes格式,如果想内容,还需要手动decode,因此在文件打开阶段,不需要指定编码
问:假设你不知道你要处理的文件是什么编码可怎么办?
import chardet f = open('log',mode='rb') data = f.read() f.close() result = chardet.detect(open('log',mode='rb').read()) print(result) ##输出: {'encoding': 'GB2312', 'confidence': 0.99, 'language': 'Chinese'} ##注意:
注意:
文件操作时,以 “r”或“rb” 模式打开,则只能读,无法写入;
硬盘上保存的文件都是某种编码的0101010,打开时需要注意:
rb,直接读取文件保存时原生的0101010,在Python中用字节类型表示
r和encoding,读取硬盘的0101010,并按照encoding指定的编码格式进行断句,再将“断句”后的每一段0101010转换成unicode的 010101010101,在Python中用字符串类型表示
5.2文件操作的其他功能
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 判断文件是否可写
5.3 例题
读文件找到第9个字符,华 ,找到第二行的 实,删除最后一行 写入文件 桃之夭夭,灼灼其华。之子于归,宜其室家。 桃之夭夭,有蕡其实。之子于归,宜其家室。 桃之夭夭,其叶蓁蓁。之子于归,宜其家人。 f = open('poem.txt', 'r+', encoding='utf-8') f.seek(3*8) print(f.read(1)) f.seek(3*28+2) print(f.read(1)) data_list = f.readlines() print(data_list) data_list.pop() print(data_list) f.seek(0) f.truncate() f.write(''.join(data_list))
5.4 例题:读取一个文件下的所有文件
import os def read_image(image_dir): photofile_list = os.listdir(image_dir) for i in range(len(photofile_list)): photo_path = os.path.join(image_dir,photofile_list[i]) print(photo_path)