Python文件的使用

来自CloudWiki
跳转至: 导航搜索

文件的使用

文件的打开和关闭

open函数的格式

open(file, mode='r', buffering=-1, encoding=None, errors=None,newline=None, closefd=True, opener=None)

  • file参数指定了被打开的文件路径。
  • mode参数指定了打开文件后的处理方式。
  • buffering参数指定了读写文件的缓存模式。0表示不缓存,1表示缓存,如大于1则表示缓冲区的大小。默认值是缓存模式。
  • encoding参数指定对文本进行编码和解码的方式,只适用于文本模式,可以使用Python支持的任何格式,如GBK、utf8、CP936等等。

文件打开模式

文件打开模式:

  • Python7-1.png

python文件打开模式:

  • b模式:以二进制模式打开文件
  • t模式:以文本模式打开文件
  • r模式:以读模式打开文件,如文件不存在则抛出异常
  • w模式:以写模式打开文件,如果文件已存在,则清空原有内容
  • x模式:以写模式打开文件,如果文件已存在,则抛出异常
  • a模式:以追加写模式打开文件,不覆盖文件原有内容
  • +模式:以读、写模式打开文件,既能读,又能写。


  • 文件写模式:w 代表清空文件原有内容,a 代表在文件原有内容上追加,x 代表创建新文件,如果文件已存在,则抛出异常

使用方法

  • 如果执行正常,open()函数返回1个文件对象,通过该文件对象可以对文件进行读写操作。如果指定文件不存在、访问权限不够、磁盘空间不足或其他原因导致创建文件对象失败则抛出异常。
f1 = open( 'file1.txt', 'r' )     # 以读模式打开文件
f2 = open( 'file2.txt', 'w')      # 以写模式打开文件
  • 当对文件内容操作完以后,一定要关闭文件对象,这样才能保证所做的任何修改都确实被保存到文件中。
f1.close()

例题:

s = "队伍名\n队长:XXX\n队员:XXX XXX XXX\n"
fw = open(r"d:\sample123.txt","w")
fw.write(s)
fw.close()

fr = open(r"d:\sample123.txt","r")
print(fr.read())
fr.close()
 

注:写路径时,前面要加上字母r ,表示按照字符的原义去理解路径中的字符

文件操作属于I/O操作,I/O操作中可能因为I/O设备的原因有时操作不正确,因此I/O操作一般建议使用try语句捕获有可能发生的错误。

try:
     f=open(“c:\\xyz.txt”,“rt”)
     f.close()
except:
     print("文件打开失败")

练习

输入若干个学生的姓名Name、性别Gender、年龄Age,把它存储到文件students.txt中,每个数据项占一行。

def write(info):#定义函数,写文件
    try:#加入异常处理语句
        fw = open(r"d:/test.txt","wt")#以文本写的方式打开文件
        fw.write(info[0]+"\n")#写入内容
        fw.write(info[1]+"\n")
        fw.write(info[2]+"\n")
        fw.close()
    except Exception as e:
        print(e)

def myinput( ):#接受用户输入
    s =input("请输入姓名,性别 年龄,以空格隔开")
    info = [ ]
    info = s.split( )#分割字符串
    return info

def read():#定义函数,读文件
    try:
        fr = open(r"d:/test.txt","rt")#以文本读的方式打开文件
        result = fr.read()
        return result
    except Exception as e:
        print(e)
        return "error:",+str(e)
if __name__=="__main__":
    info = myinput()
    print(info)
    write(info)
    r = read( )
    print(r)

文件的类型

文件包括文本文件和二进制文件两种类型。

文本文件一般由单一特定编码的字符串组成,如如一个txt格式的文本文件。

二进制文件直接由比特0和皮特一组成,没有统一的字符编码。二进制文件由于没有统一的字符编码,只能当做字节流,而不能看作是字符串。

当用二进制方法写文件时,必须将字符串用encode函数编一下码

例题:

#以文本形式写文件
s = '新年都未有芳华,二月初惊见草芽。\n白雪却嫌春色晚。故穿庭树作飞花。\n'
fw = open('sample.txt',"wt")
fw.write(s)
fw.close()

#以文本形式读文件
fr =open('sample.txt',"rt")
print(fr.read())
fr.close()

#以二进制形式写文件
fw = open('sample.txt',"wb")
fw.write(s.encode("gbk"))
fw.close()
#以二进制形式读文件
fr =open('sample.txt',"rb")
print(fr.read())
fr.close()
#以文本形式读文件
fr =open('sample.txt',"rt")
print(fr.read())
fr.close()


文件读写结束时,一定要加入fr.close() 来关闭输入输出流。

文件的遍历

文本文件可以看作是由行组成的组合类型,因此也可以使用遍历循环逐行的遍历文件。

s = '新年都未有芳华,\n二月初惊见草芽。\n白雪却嫌春色晚。\n故穿庭树作飞花。'
fw = open('sample.txt',"wt")
fw.write(s)
fw.close()

fp =open('sample.txt',"rt")      #假设文件采用CP936编码
for line in fp:                 #文件对象可以直接迭代
    print(line)
fp.close()

可以用for循环来逐行读入文件数据

文件的编码

GBK编码

是指中国的中文字符,其它它包含了简体中文与繁体中文字符,另外还有一种字符“gb2312”,这种字符仅能存储简体中文字符。

GBK中一个英文字符占一个字节(ASCII),一个汉字两字节

UTF-8编码

它是一种全国家通过的一种编码,如果你的网站涉及到多个国家的语言,那么建议你选择UTF-8编码。

UTF-8中一个英文字符占一个字节(ASCII),一个汉字通常占3字节

保存包括中文在内的多语言文件,一般用UTF-8编码较多

在中文Windows系统中如果我们不指定文本文件的编码,那么它采用系统默认的GBK编码

如果我们想改变默认编码方式,在open函数中添加参数:encoding="utf-8

如:   fobj=open("c:\\abc.txt","wt",encoding="utf-8")

用utf-8编码写文件,稍后读的时候也需用utf-8编码来读,否则会报错。

例6-3-1: GBK编码

fobj=open("c:\\abc.txt","wt")
fobj.write("abc我们")
fobj.close()

执行后abc.txt文件是7个字节,分别是:

0x61 0x62 0x63 0xce 0xd2 0xc3 0xc7

其中前3个是abc字符,0xce,0xd2这2个字节是汉字"我"的内码,0xc3,0xc7这2个字节是汉字"们"的内码。

指定文件编码

如果我们不使用默认的编码,可以在open函数中用encoding参数指定编码。

  fobj=open("c:\\abc.txt","wt",encoding="utf-8")
  fobj.write("abc我们")
  fobj.close()


执行后abc.txt文件是9个字节,分别是:

 0x61 0x62 0x63 0xe6 0x88 0x91 0xe4 0xbb 0xac

其中前3个是abc字符,0xe6, 0x88, 0x91这3个字节是汉字"我"的UTF-8编码,0xe4,0xbb ,0xac这3个字节是汉字"们"的UTF-8编码。

练习

用UTF-8编码存储文本文件,再用相同编码读取文件。

思考:如果用其他的编码方式读取,会出现什么结果?

s="队名:精神小伙 队员:张三 李四 王五\n  \t"

fw = open(r"C:\Users\maxin\Documents\teaching\2023Python程序设计\1.txt",'wb')#以二进制模式写
fw.write(s.encode("utf-8"))
fw.close()#这句不能忽略

fr = open(r"C:\Users\maxin\Documents\teaching\2023Python程序设计\1.txt",'rb')#以二进制模式读
print(fr.read( ))
fr.close()#这句不能忽略

fw = open(r"C:\Users\maxin\Documents\teaching\2023Python程序设计\1.txt",'wt',)#以文本模式写
fw.write(s)
fw.close()#这句不能忽略

fr = open(r"C:\Users\maxin\Documents\teaching\2023Python程序设计\1.txt",'rt')#以文本模式读
print(fr.read( ))
fr.close()#这句不能忽略

fw = open(r"C:\Users\maxin\Documents\teaching\2023Python程序设计\1.txt",'at')#以文本模式追加写
fw.write(s)
fw.close()#这句不能忽略

fw = open(r"C:\Users\maxin\Documents\teaching\2023Python程序设计\1.txt",'a')#省略t字母
fw.write(s)
fw.close()#这句不能忽略

fr = open(r"C:\Users\maxin\Documents\teaching\2023Python程序设计\1.txt",'r+')#既能读,又能写
print(fr.read( ))
fr.close()#这句不能忽略



上下文管理语句with

在实际开发中,读写文件应优先考虑使用上下文管理语句with,关键字with可以自动管理资源,不论因为什么原因(哪怕是代码引发了异常)跳出with块,总能保证文件被正确关闭,并且可以在代码块执行完毕后自动还原进入该代码块时的上下文,常用于文件操作、数据库连接、网络连接、多线程与多进程同步时的锁对象管理等场合。

 with open(filename, mode, encoding) as fp:
    #这里写通过文件对象fp读写文件内容的语句

  • 上下文管理语句with还支持下面的用法:
with open('test.txt', 'r') as src, open('test_new.txt', 'w') as dst:
	dst.write(src.read())

所以,上面那个例子用上下文语句可以这么写:

s = 'Hello world\n文本文件的读取方法\n文本文件的写入方法\n'
with open('sample.txt',"w") as fw:
    fw.write(s)

with open('sample.txt',"r") as fr:
    print(fr.read())

可以用上下文管理语句with 来简写文件输入输出

文件的读写函数

f.read()

如果文件不大,可以一次性将文件内容读入,保存到程序内部变量当中,f.read()是最常用的一次性读文件的函数。

函数调用的形式为:

文件对象.read()
文件对象.read(n)
  • 如果不指定要读取的字符数n,使用read()读,则读到整个文件的内容;
  • 如果使用read(n)指定要读取的字符数,那么就按要求读取n个字符;
  • 如果要读n个字符,而文件没有那么多字符,那么就读取所有文件内容。
  • 如果文件指针已经到了文件的尾部,再读就返回一个空串。


#写文件
s = '新年都未有芳华,二月初惊见草芽。白雪却嫌春色晚。故穿庭树作飞花。'
fw = open('D:/sample.txt',"wt")
fw.write(s)
fw.close()

#以文本形式读文件
fr =open('D:/sample.txt',"rt")
print(fr.read())
fr.close()

练习

例6-4-3:保存文件c:\abc.txt,打开文件一次读一个字符,读取全部

readline()

如果要从文件中读取一行,那么可以使用readline()

规则:

它返回一行字符串。readline()的规则是在文件中连续读取字符组成字符串,一直读到'\n'字符或者读到文件尾部为止。

注意如果读到'\n',那么返回的字符串包含'\n'。

如果到了文件尾部,再次读就读到一个空字符串。

练习

保存文件c:\abc.txt,打开文件一次读一行字符,读取全部

def writeFile():
    fobj=open("c:\\abc.txt","wt")
    fobj.write("abc\nxyz")
    fobj.close()
 
def readFile():
    fobj=open("c:\\abc.txt","rt")
    goon=1
    st=""
    while goon==1:
         s=fobj.readline()
         if s!="":
              st=st+s
         else:
              goon=0
    fobj.close()
    print(st)
    
try:
    writeFile()
    readFile()
except Exception as err:
       print(err)


f.readlines()

如果要从文件中读取所有行,那么:

 文件对象.readlines()

规则:

  • 它返回所有的行字符串,每行是用"\n"分开的,而且一行的结尾如果是"\n"则包含"\n"。
  • 一般再次使用for循环从readlines()中提取每一行。

f.readlines()也是一次性读入文件的函数,其结果是一个列表,每个元素是文件的一行。

fr =open('D:/sample.txt',"rt")
print(fr.readlines())
fr.close()

练习

读出students.txt文件学生信息的关键代码如下:

   f=open("student.txt","rt")
    while True:
        name=f.readline().strip("\n")
        if name=="":
            break
        gender= f.readline().strip("\n")
        age=float(f.readline().strip("\n"))


f.write()

f.write()向文件写入字符串,每次写入后,将会记录一个写入指针。

f = open("D:/test.txt","w")
f.write("新年都未有芳华。\n")
f.write("2月初惊见草芽。\n")
f.write("白雪却嫌春色晚。\n")
f.write("故穿庭树作飞花。\n")
f.close()

fp =open('D:/test.txt',"rt")      
for line in fp:                 #文件对象可以直接迭代
    print(line)
fp.close()

f.writelines()

f.writelines()直接将列表类型的各个元素连接起来,写入文件。

f = open("D:/test.txt","w")
#f.write("新年都未有芳华。\n")
#f.write("2月初惊见草芽。\n")
#f.write("白雪却嫌春色晚。\n")
#f.write("故穿庭树作飞花。\n")
ls = ['新年都未有芳华,\n二月初惊见草芽。\n白雪却嫌春色晚。\n故穿庭树作飞花。\n']
f.writelines(ls)
f.close()

fp =open('D:/test.txt',"rt")      
for line in fp:                 #文件对象可以直接迭代
    print(line)
fp.close()

f.tell()

使用tell函数获取当前文件指针的位置,方法是:

文件对象.tell()

它返回一个整数。

在程序看来,文件就是由一连串的字节组成的字节流,文件的每个字节都有一个位置编号,一个有n个字节的文件字节编号依次为0、1、2、……、n-1号,在第n字节的后面有一个文件结束标志EOF (End Of File),如图为文件的模型,其中标明了文件字节值,文件位置编号以及文件指针的关系,该文件有6个字节,它们是0x41、0x42、0x43、0x41、0x42、0x61,指针目前指向第2字节,EOF是文件尾。

Python2022122901.png

如字节流有n个字节,p是指针的位置(0<=p<=n-1),那么读写的规则如下:

  • 0<=p<=n-1时,指针指向一个文件字节,可以读出该字节,读完后指针会自动指向下一个字节,既p会自动加1;若p指向EOF的位置,则不能读出任何文件字节,EOF通常是循环读文件的循环结束条件。
  • 0<=p<=n-1时,指针指向一个文件字节,可以写入一个新的字节,新的字节将覆盖旧的字节,之后指针会自动指向下一个字节,既p会自动加1;若p指向EOF的位置,则新写入的字节会变成第n+1个字节,EOF向后移动一个位置,在字节流的末尾写入会加长文件字节流。
s = '新年都未有芳华,二月初惊见草芽。\n白雪却嫌春色晚。故穿庭树作飞花。\n'
fw = open('D:/sample.txt',"wt",encoding="utf-8")
fw.write(s)
print(fw.tell())
fw.close()


#以文本形式读文件
fr =open('D:/sample.txt',"rt",encoding="utf-8")
print(fr.tell())
print(fr.readline())
print(fr.tell())
print(fr.readline())
print(fr.tell())
fr.close()

f.seek()

当从文件中读取内容后,读取指针将向前进,可以用seek()方法将读取指针移动到文件开头

Python中使用feek函数来移动文件指针,方法是:

文件对象.seek(offset[,whence])
  • offset -- 开始的偏移量,也就是代表需要移动偏移的字节数
  • whence:可选,默认值为 0。给offset参数一个定义,表示要从哪个位置开始偏移;0代表从文件开头开始算起,1代表从当前位置开始算起,2代表从文件末尾算起。

注“”文件如果按"wt+"或者"rt+"的模式打开,那么文件指针可以随意调整,可以随意对文件进行读写。

#写文件
s = '新年都未有芳华,二月初惊见草芽。白雪却嫌春色晚。故穿庭树作飞花。'
fw = open('D:/sample.txt',"wt")
fw.write(s)
fw.close()

#以文本形式读文件
fr =open('D:/sample.txt',"rt")
s=fr.read()

print(s)

fr.seek(0)

s=fr.read()
print(s)
fr.close()

综合案例:文件读写

以下案例将以上所有函数都用上了:

def myinput( ):#接受用户输入
    s =input("请输入姓名,性别 年龄,以空格隔开")#例:张三 男 20
    info = [ ]
    info = s.split( )#分割字符串
    return info

def write(info):#定义函数,写文件
    try:#加入异常处理语句
        with open(r"d:/test.txt","wt",encoding="utf-8") as fw:#用上下文管理语句with 读写文件
            fw.write(info[0]+"\n")#写入内容
            fw.write(info[1]+"\n")
            fw.write(info[2]+"\n")
            #print(fw.tell())#告诉文件当前指针的位置
            #fw.writelines(info)#直接将列表类型的各个元素连接起来,写入文件。
            #print(fw.tell())#告诉文件当前指针的位置
        
    except Exception as e:
        print(e)
def read():#定义函数,读文件
    try:
        with open(r"d:/test.txt","rt",encoding="utf-8") as fr:#以文本读的方式打开文件
            #result = fr.read(7)#一次性地读取内容,
            #result = fr.readline()#读取一行内容
            result = fr.readlines()#读取多行内容
            print("第1次读取文件内容:")
            print(result)
            print("文件指针重新寻址后,第2次读取文件内容:")
            fr.seek(0)#这里的0 代表文件指针距离文件开始位置的偏移,可以设成其他数值
            result = fr.readlines()#读取多行内容
            print(result)
            '''
            #逐行的遍历文件
            result = [ ]
            for line in fr:
                result.append(line.strip())
            '''

        return result
    except Exception as e:
        print(e)
        return "error:",+str(e)



if __name__=="__main__":
    info = myinput()#用户输入
    print("打印用户输入的数据:")
    print(info)#打印用户输入的数据
    print("将用户输入的内容写入文件:")
    write(info)#将用户输入的内容写入文件
    print("从文件中读取内容:")
    read( )#从文件中读取内容