Python文件操作
一、文件操作:
1. 文件写入模式:
os.mknod("test.txt") 创建空文件
f1 = open("test.txt",w) 直接打开一个文件,如果文件不存在则创建文件
关于open 模式:
w 以写方式打开,
a 以追加模式打开
r+ 以读写模式打开
w+ 以读写模式打开
a+ 以读写模式打开
rb 以二进制读模式打开
wb 以二进制写模式打开
ab 以二进制追加模式打开
rb+ 以二进制读写模式打开
wb+ 以二进制读写模式打开
ab+ 以二进制读写模式打开
对于对于以上文件操作的模式,区别如下图所示:
除以上文件操作模式中,还会用到rb,rb+,wb,wb+,ab,ab+,既然上述的操作模式已经能满足大部分需要,二进制的写入有什么必要呢?
(1)二进制读文件
进行读文件操作时,直到读到文档结束符(EOF)才算读取到文件最后,Python会认为字节\x1A(26)转换成的字符为文档结束符(EOF),故使用'r'进行读取二进制文件时,可能会出现文档读取不全的现象。
举例如下:
二进制文件中存在如下从低位向高位排列的数据:7F 32 1A 2F 3D 2C 12 2E 76
如果使用'r'进行读取,则读到第三个字节,即认为文件结束。
如果使用'rb'按照二进制位进行读取的,不会将读取的字节转换成字符,从而避免了上面的错误。
解决方案:
二进制文件就用二进制方法读取'rb'
小结:
使用'r'的时候,如果碰到'0x1A',就视为文件结束,就是EOF。使用'rb'则不存在这个问题,即:如果你用二进制写入再用文件读出的话,如果其中存在'0x1A',就只会读出文件的一部分,使用'rb'会一直读取文件末尾。
(2)二进制写文件
对于字符串x='abc\ndef',我们可用len(x)得到它的长度为7,\n我们称之为换行符,实际上是0x0A。当我们用'w'即文本方式写的时候,在windows平台上会自动将'0x0A'变成两个字符'0x0D','0x0A',即文件长度实际上变成8。当用'r'文本方式读取时,又自动的转换成原来的换行符。
如果换成'wb'二进制方式来写的话,则会保持一个字符不变,读取的时候也是原样读取。
所以如果用文本方式写入,用二进制方式读取的话,就要考虑这多出的一个字节了。'0x0D'也称回车符。
Linux下不会变,因为linux只使用'0X0A'来表示换行。
2. 常用操作文件方法:
f1.read([size]) #size为读取的长度,以byte为单位 f1.readline([size]) #读一行,如果定义了size,有可能返回的只是一行的一部分 f1.readlines([size]) #把文件每一行作为一个list的一个成员,并返回这个list。其实它的内部是通过循环调用readline()来实现的。如果提供size参数,size是表示读取内容的总长,也就是说可能只读到文件的一部分。 f1.write(str) #把str写到文件中,write()并不会在str后加上一个换行符 f1.writelines(seq) #把seq的内容全部写到文件中(多行一次性写入)。这个函数也只是忠实地写入,不会在每行后面加上任何东西。 f1.close() #关闭文件。python会在一个文件不用后自动关闭文件,不过这一功能没有保证,最好还是养成自己关闭的习惯。 如果一个文件在关闭后还对其进行操作会产生ValueError f1.flush() #把缓冲区的内容写入硬盘 f1.fileno() #返回一个长整型的”文件标签“ f1.isatty() #文件是否是一个终端设备文件(unix系统中的) f1.tell() #返回文件操作标记的当前位置,以文件的开头为原点 f1.next() #返回下一行,并将文件操作标记位移到下一行。把一个file用于for … in file这样的语句时,就是调用next()函数来实现遍历的。 f1.seek(offset[,whence]) #将文件打操作标记移到offset的位置。这个offset一般是相对于文件的开头来计算的,一般为正数。但如果提供了whence参数就不一定了,whence可以为0表示从头开始计算,1表示以当前位置为原点计算。2表示以文件末尾为原点进行计算。需要注意,如果文件以a或a+的模式打开,每次进行写操作时,文件操作标记会自动返回到文件末尾。 f1.truncate([size]) #把文件裁成规定的大小,默认的是裁到当前文件操作标记的位置。如果size比文件的大小还要大,依据系统的不同可能是不改变文件,也可能是用0把文件补到相应的大小,也可能是以一些随机的内容加上去。
二、目录操作:
1. 常用操作目录方法:
os.getcwd() #得到当前工作目录,即当前Python脚本工作的目录路径 os.listdir() #返回指定目录下的所有文件和目录名 os.remove() #函数用来删除一个文件 os.removedirs(r“c:\python”) #删除多个目录 os.path.isfile() #检验给出的路径是否是一个文件 os.path.isdir() #检验给出的路径是否是一个目录 os.path.isabs() #判断是否是绝对路径 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() #获取文件名 os.system() #运行shell命令 os.getenv() 与os.putenv() #读取和设置环境变量 os.linesep #给出当前平台使用的行终止符,Windows使用'\r\n',Linux使用'\n'而Mac使用'\r' os.name #指示你正在使用的平台:对于Windows,它是'nt',而对于Linux/Unix用户,它是'posix' os.rename("oldname","newname") 文件或目录都是使用这条命令 os.makedirs(r“c:\python\test”) #创建多级目录 os.mkdir(“test”) #创建单个目录 os.stat(file) #获取文件属性 os.chmod(file) #修改文件权限与时间戳 os.exit() #终止当前进程 os.path.getsize(filename) #获取文件大小 os.chdir() #切换工作目录 os.chroot() #设定当前进程的根目录 os.rmdir("dir") #只能删除空目录 os.removedirs() #删除多级目录
关于shutil模块的使用方法,查看这里。
三、Path操作:
1. 分隔:
basename() #去掉目录路径,返回文件名 dirname() #去掉文件名,返回目录路径 join() #将分离的各部分组合成一个路径名 split() #返回(dirname(),basename())元组 splitdrive() #返回(drivename,pathname)元组 splitext #返回(filename,extension)元组
2. 信息:
getatime() #返回最近访问时间 getctime() #返回文件创建时间 getmtime() #返回最近文件修改时间 getsize() #返回文件大小(以字节为单位)
3. 查询:
exists() #指定路径(文件或目录)是否存在 isabs() #指定路径是否为绝对路径 isdir() #指定路径是否存在且为一个目录 isfile() #指定路径是否存在且为一个文件 islink() #指定路径是否存在且为一个符号链接 ismount() #指定路径是否存在且为一个挂载点 samefile() #两个路径名是否指向同一个文件
四、示例:
(1)判断文件是否存在,存在则打开,让用户通过键盘反复输入多行数据,追加保存至此文件中:
#!/usr/bin/python import os import os.path filename=raw_input('plz a file name:') if os.path.isfile(filename): openname= open(filename,'a+') while True: newline=raw_input('plz a line:') if newline == 'q' or newline =='quit': break else: openname.write(newline+'\n') openname.close()
(2)将文件夹下所有图片名称加上'_fc':
# -*- coding:utf-8 -*- import re import os import time #str.split(string)分割字符串 #'连接符'.join(list) 将列表组成字符串 def change_name(path): global i if not os.path.isdir(path) and not os.path.isfile(path): return False if os.path.isfile(path): file_path = os.path.split(path) #分割出目录与文件 lists = file_path[1].split('.') #分割出文件与文件扩展名 file_ext = lists[-1] #取出后缀名(列表切片操作) img_ext = ['bmp','jpeg','gif','psd','png','jpg'] if file_ext in img_ext: os.rename(path,file_path[0]+'/'+lists[0]+'_fc.'+file_ext) i+=1 #注意这里的i是一个陷阱 #或者 #img_ext = 'bmp|jpeg|gif|psd|png|jpg' #if file_ext in img_ext: # print('ok---'+file_ext) elif os.path.isdir(path): for x in os.listdir(path): change_name(os.path.join(path,x)) #os.path.join()在路径处理上很有用 img_dir = 'D:\\xx\\xx\\images' img_dir = img_dir.replace('\\','/') start = time.time() i = 0 change_name(img_dir) c = time.time() - start print('程序运行耗时:%0.2f'%(c)) print('总共处理了 %s 张图片'%(i)) 输出结果: 程序运行耗时:0.11 总共处理了 109 张图片