一、文件打开  open(filename,mode,buffering)

  filename 文件名

  mode 打开模式(r\w\a\x\b\t\+)

  buffering 是否缓冲(0:不缓冲,默认值;1:缓冲;>1的int:缓冲区的大小)

  (一) open(filename,'r')

  filename文件存在:文本方式打开,指针在文件头,可读、不可写

  filename文件不存在:报错

''''
'r',文本方式打开,可读、不可写。
文件存在,直接打开,指针在文件头;文件不存在,报错。
'''
# 文件存在时
f = open('user_information.txt','r')  # 文件已存在
print(f.tell())         # 文件指针位置:0
f.read()
print(f.tell())         # 文件指针位置:21
# f.write('hi')           # not writable
f.close()
# 文件不存在时
f = open('readme.txt','r')  # 文件不存在,报错
# FileNotFoundError: [Errno 2] No such file or directory: 'readme.txt'
View Code

  (二) open(filename,'w')

  filename文件存在:文本方式打开,原内容清空,指针在文件头,不可读、可写

  filename文件不存在:创建新文件,不可读、可写。

'''
'w',文本方式打开,不可读、可写,打开时指针在文件头。
文件存在,将原文件内容清空;文件不存在,新建文件。
'''
# 文件已存在时
f = open('user_information.txt','w')
print(f.tell())         # 文件指针位置:0
# f.read()                #  not readable
f.write('dongxuew$liushui816')
print(f.tell())         # 文件指针位置:19
f.write('\n')
print(f.tell())         # 文件指针位置:21
f.close()
# 文件不存在时
f = open('readme_w.txt','w')
print(f.tell())        # 创建新文件
f.close()
View Code

  (三) open(filename,'a')

  filename文件存在:文本方式打开,指针在文件尾,不可读、可写

  filename文件不存在:创建新文件,不可读、可写。

'''
'a',文本方式打开,不可读、可写。
文件存在,将原文件打开,指针在文件尾。文件不存在,新建文件。
'''
# # 文件已存在时
# f = open('user_information.txt','a')
# print(f.tell())         # 文件指针位置:42
# # f.read()                #  not readable
# f.write('dongxuew$liushui816')
# print(f.tell())         # 文件指针位置:61
# f.write('\n')
# print(f.tell())         # 文件指针位置:63
# f.close()
# 文件不存在时
f = open('readme_a.txt','a')  # 创建新文件
print(f.tell())
# f.readline()  # not readable
f.close()
View Code

  (四) open(filename,'x')

  filename文件存在:报错。

  filename文件不存在:创建新文件,不可读、可写。

# 'x',文件已存在时报错,不存在时新建,可写、不可读。
f = open('readme_xx.txt','x')  # 创建新文件
print(f.tell())
f.write('hi')
print(f.tell())
# f.read()
f.close()
View Code

  P.S.:

  'b':二进制方式打开文件。不能单独使用,需要与\r\w\a配合使用。rb\wb\ab的方法同r\w\a方法,只是在操作时,需要注意:字节流文件是以bytes为单位。

  't':文本方式打开文件,默认值。\rt\wt\at==\r\w\a。

  '+':功能扩展,可读、可写。不能单独使用,需要与\r\w\a配合使用

  (五) open(filename,'r+')

  filename文件存在:文本方式打开,指针在文件头,可读、可写。

  filename文件不存在:报错。

''''
'r+',文本方式打开,可读、可写。
文件存在,直接打开,指针在文件头;文件不存在,报错。
'''
# 文件存在时,可读可写,打开时指针在开头
f = open('user_information.txt','r+')  # 文件已存在
print(f.tell())         # 文件指针位置:0
f.read()                # 文件可读
print(f.tell())         # 文件指针位置:21
f.write('hi')           # 文件可写
print(f.tell())         # 文件指针位置:23
f.close()
# 已存在文件打开直接write,添加在文件开头
f = open('user_information.txt','r+')
print(f.tell())         # 文件指针位置:0
f.write('hello')
print(f.tell())         # 文件指针位置:5
f.read()
print(f.tell())         # 文件指针位置:23
f.close()
# 文件不存在时
f = open('readme_r+.txt','r+')  # 文件不存在,报错
f.close()
View Code

  (六) open(filename,'w+')

  filename文件存在:文本方式打开,清空原内容,指针在文件头,可读、可写。

  filename文件不存在:创建新文件,可读、可写

'''
'w+',文本方式打开,可读、可写,打开时指针在文件头。
文件存在,将原文件内容清空;文件不存在,新建文件。
'''
# 文件已存在时
f = open('user_information.txt','w+')
print(f.tell())         # 文件指针位置:0
f.read()                # 文件可读
print(f.tell())         # 文件指针位置:0
f.write('dongxuew$liushui816')
print(f.tell())         # 文件指针位置:19
f.write('\n')
print(f.tell())         # 文件指针位置:21
f.read()                #  文件可读
print(f.tell())         # 文件指针位置:21
f.close()
# 文件不存在时
f = open('readme_w++++.txt','w+')
print(f.tell())        # 创建新文件
f.read()
f.write('hihi')
f.close()
View Code

  (七) open(filename,'a+')

  filename文件存在:文本方式打开,指针在文件尾,可读、可写。

  filename文件不存在:创建新文件,可读、可写

'''
'a+',文本方式打开,可读、可写。
文件存在,将原文件打开,指针在文件尾。文件不存在,新建文件。
'''
# 文件已存在时
f = open('user_information.txt','a+')
print(f.tell())         # 文件指针位置:21
f.read()                # 文件可读
f.write('dongxuew$liushui816')
print(f.tell())         # 文件指针位置:40
f.write('\n')
print(f.tell())         # 文件指针位置:42
f.close()
# 文件不存在时
f = open('readme_a+++.txt','a+')  # 创建新文件
print(f.tell())
f.read()                 # 文件可读
f.write('hihi')         # 文件可写
# f.readline()  # not readable
f.close()
View Code

  P.S.:

  1、文件打开后,需要关闭文件f.close()

  2、通常使用with语句打开文件,不但不需要关闭文件,还可以同时打开两个文件。

# with 语句语法如下
with open('filename1.py','r') as f1:
    with open('filename2.py','r') as f2:
        pass
View Code

  二、文件内部操作

  (一)关于指针

  1、f.tell()  获取当前文件指针位置

  2、f.seek(num,whence=0)  向后移动指针(num表示移动的距离,whence表示从哪里开始移位)

  whence = 0 时,从文件头开始向后移位;whence = 1 时,从文件当前位置向后移位;whence = 2 时,从文件尾开始向后移位。

# 指针位移
f = open('user_information.txt','ab+')
# python3 不允许不以为二进制方式打开文件,如:a+打开文件时seek常会报错
print(f.tell()) # 105
f.seek(10)  # 默认从文件头开始向后移位
print(f.tell()) # 10
f.seek(5,1) # 1,表示从当前位置开始向后移位
print(f.tell()) # 15
f.seek(10,2) # 2,表示从文件尾开始移位
print(f.tell()) # 115
f.close()
View Code

  3、 f.__next__() 文件指针移至下一行,位置到最后时会报错。

f = open('user_information.txt','ab+')
print(f.tell())  # 8
f.write(b'hi\nhello\nno\n')
f.seek(10)
f.__next__()
print(f.tell())     # 11
f.__next__()
print(f.tell())     # 17
f.close()
View Code

  (二) f.truncate(size) 文件截断

  有参数size时:size长度小于文件内容时,从文件头开始,截取size字节的文件内容,截断size后的文件内容删除。

         size长度大于文件内容时,系统不同处理不同。

  无参数size时:默认从文件指针当前位置进行截断,删除其后面的文件内容。

  注意:截断对文件指针位置无影响。

f = open('user_information.txt','ab+')
f.write(b'dongxuewhello')
print(f.tell())  # 18
f.truncate(10)    # 从文件开始截取10bytes
print(f.tell())  # 18  # 截断不影响指针的位置
f.seek(8)       # 指针移位
f.truncate()   # 默认参数表示截断到当前指针位置
f.close()

f = open('user_information.txt','ab+')
print(f.tell())  # 8
f.close()
View Code

   P.S.: python中打开文件中,不能直接进行相关内容的删除,需要新建文件。

  (三)写文件

  1、f.write(str\bytes)  将str\bytes内容写进文件,不会在后面自动添加换行符

  文本方式打开文件时,参数为str;二进制方式打开文件时,参数为bytes。  

# 以二进制方式打开文件,需要参数是bytes
f = open('readme.txt','wb+')
f.write(b'hi')
f.close()
# 以文本方式打开文件,需要参数是str
f = open('readme.txt','w+')
f.write('hi')
f.close()
View Code

  2、f.writelines(seq)  seq必须是列表或元组,将内容逐行写入文件,不会自动添加换行符

with open('user_information.txt','r+') as f:
    with open('readme.txt','w+') as fcopy:
        fcopy.writelines(f.readlines())
with open('readme.txt','r+') as fcopy:
    for line in fcopy:
        print(line)
View Code

  (四) 读文件

  1、 f.read(size)  逐个读取,size控制读取字节\字符的长度

  按文本方式打开文件时,逐个字符读取;按bytes方式打开文件时,逐个字节读取,输出十进制int表示。

with open('readme.txt','a+') as f1:
    # 文本方式打开,输出字符
    f1.seek(0)
    for i in f1.read():print(i,end=' ')
print()
with open('readme.txt','ab+') as f1:
    # bytes方式打开,输出字节的十进制int表示
    f1.seek(0)
    for i in f1.read():print(i,end=' ')
print()
with open('readme.txt','ab+') as f1:
    # 读取指定长度
    f1.seek(0)
    for i in f1.read(6):print(i,end=' ')
View Code

  2、 f.readline(size) 读取一行,size是指定字节\字符的长度

  默认读取一行;也可以用size设置读取长度,但仅限于一行内

  当size大于一行时,取一行;当size小于一行时,取size长度。

# 读取一行,默认读全行
with open('readme.txt','ab+') as f1:
    f1.seek(0)
    content = f1.readline()
    print(content) # b'nihao\n'
    print(f1.tell()) # 6
print()
# 读取一行,设置读取长度小于一行内容时,取指定长度
with open('readme.txt','ab+') as f1:
    f1.seek(0)
    content = f1.readline(4)
    print(content) # b'niha'
    print(f1.tell()) #4
print()
# 读取一行,设置读取长度大于一行内容时,取一行
with open('readme.txt','ab+') as f1:
    # 读取一行,设置读取长度
    f1.seek(0)
    content = f1.readline(20)
    print(content) # b'niha'
    print(f1.tell()) #6
View Code

  3、 f.readlines(size)按行读取,每一行作为list的一个元素,size是指定字节\字符的长度

  默认读取当前指针位置之后的所有行。

  用size指定读取长度时,读取的是包含size长度字符\字节的最少行

# 按行读取,默认从指针位置开始,读取剩余全部
with open('user_information.txt','ab+') as f1:
    f1.seek(11)
    for line in f1.readlines():
        print(line)

# 按行读取,size指定读取字符数,显示内容为:包含size字符数的最少行
with open('user_information.txt','ab+') as f1:
    f1.seek(0)
    for line in f1.readlines(17):
        print(line)
View Code

  三、 f.flush()  把缓冲区的数据刷入硬盘

  四、os模块 文件相关操作

  (一) 文件删除  os.remove(filename)

  删除指定文件,每次只能删除一个,需要提前 import os  

# 删除指定文件,每次删除一个
import os
os.remove('readme_a++.txt')
View Code

  需要批量删除文件时,可在remove基础上,根据删除条件自行组织代码:

# 批量删除当前目录下,所有名字中含有readme字样的文件
for i in os.listdir():# 返回当前目录下的所有文件和目录名
    if 'readme' in i:
        os.remove(i)
for i in os.listdir():print(i)
View Code

  (二) 文件重命名  os.rename(old,new)

  1、rename可以直接重命名一个文件或目录

import os
os.rename('hell_world.py','del_hi.py')
View Code

  2、rename也可以用于文件\目录的移动,同盘移动时效率高

  使用rename进行文件或目录移动时,使用绝对路径。old是文件时,new可以是文件、也可以是目录;old是目录时,new只能是目录。

  注意:new文件\目录不能存在,否则会报错;new的父目录需要存在,否则会报错;同盘移动不需要复制,移动较快,但不同盘仍需要复制

import os
# 移动文件
current_dir = os.getcwd()  # 获取当前目录名
old_file = current_dir + '\\' + 'del_hi.py' # old

sub_dir = 'newfolder'   # 移动的目标目录
new_file = current_dir + '\\' + sub_dir + '\\' + 'del_hi.py'  # new

# 用os.rename()移动文件
os.rename(old_file,new_file)

# 移动目录
current_dir = os.getcwd()  # 获取当前目录名
old_dir = current_dir + '\\' + 'newfolder' # old

# 移动的目标目录
new_dir = current_dir + '\\' +  'new_newfolder'  # new

# 用os.rename()移动文件
os.rename(old_dir,new_dir)
View Code

  3、os.path.join(dir,filename)   重构文件路径:dir\filename

  五、shutil模块 文件相关操作

  shutil模块,是高级的文件、文件夹、压缩包处理模块。其中涉及文件操作的重点,在于文件的复制和异盘移动。

  (一)文件复制

  1、copyfile(src,dst) 复制文件src的 (data数据)到文件dst

  注意:src和dst必须都是文件,且dst文件具有可写权限。若dst已存在,会覆盖。

  2、copy(fsrc,fdst)   复制src的 (data & mode bits权限)到dst

  注意:dst可以是文件,也可以是目录。若dst是目录,将在目录中复制一个同名、同内容文件,包含文件权限。

  3、copy2(fsrc,fdst) 复制src的 (data & info状态信息)到dst

  注意:dst可以是文件,也可以是目录。若dst是目录,将在目录中复制一个同名、同内容文件,包含文件状态信息(如最后访问时间、最后修改时间等)

import shutil
# shutil.copyfile('first_xml.xml','copy_first_test.xml')
shutil.copy('first_xml.xml','copy_file_test')
# shutil.copy2('first_xml.xml','copy_file_test')

import os
os.remove('copy_file_test\\first_xml.xml')
View Code

   4、copymode(src,dst) 复制src的 (mode bits权限)给dst

    5、copystat(src,dst) 复制src的 (info状态信息)给dst 

  (二)文件移动 move(src,dst)

  注意:使用move()移动文件,同盘移动时类似于重命名,不重新复制文件;异盘移动时,需要重新复制文件。

     可以使用绝对路径,也可以使用相对路径。dst可以是文件夹、也可以是文件。

import shutil

# 目标文件夹内如果有同名文件,则报错
# shutil.move('first_xml.xml','copy_file_test')
# # shutil.Error: Destination path 'copy_file_test\first_xml.xml' already exists

# # 可以使用相对路径
# shutil.move('copy_file_test\\copy_fist_xml.xml','.\\')

# 目标可以是文件,文件移动到目标文件目录下,删除目标文件
shutil.move('copy_file_test\\first_xml.xml','copy_fist_xml.xml')
View Code