python之文件操作及字符编码

文件操作的基本流程

我们使用Python或者其他语言编写的应用程序,当我们需要一些数据的时候,可能是数据库中的数据,也可能是计算机本身存储的数据。当我们需要应用到计算机中的数据的时候,那么我们就需要操作计算机中的文件。而Python给我们提供了文件操作的方法。文件操作有三大步流程

#1. 打开文件,得到文件句柄并赋值给一个变量
f=open('a.txt','r',encoding='utf-8') #默认打开模式就为r

#2. 通过句柄对文件进行操作
data=f.read()

#3. 关闭文件
f.close()

一定要记得关闭文件

当我们打开一个文件的时候,是占用了我们的内存资源的,如果我们只打开文件而不关闭,那么将会一直损耗占用我们的内存资源,直至内存资源被消耗完毕,卡死。所以,在操作完一个文件的时候,一定要关闭文件。关闭文件有两种方法:
f.close() #回收操作系统级打开的文件
del f #回收应用程序级的变量
不过, del f 一定要发生在f.close() 之后,否则就会导致操作系统大开的文件并没有关闭,而白白浪费资源。而python自动的垃圾回收机制决定了我们无需考虑del f,这就要求我们,在操作完毕文件后,一定要记住f.close()。当然,每一次打开文件之后都要关闭,也就是都要f.close()。有的时候,我们会忘记关闭,那么还有一种简便的方式。极力推荐:
with open(‘a.txt’,‘w’) as f:
pass

with open('a.txt','r') as read_f,open('b.txt','w') as write_f:
    data=read_f.read()
    write_f.write(data)

文件编码

f=open(…)是由操作系统打开文件,那么如果我们没有为open指定编码,那么打开文件的默认编码就是操作系统说了算了,操作系统会用自己的默认编码去打开文件,在windows下是gbk,在linux下是utf-8,所以,当我们打开文件的时候,一定要记得文件编码。
f=open(‘a.txt’,‘r’,encoding=‘utf-8’)

文件打开的模式

我们知道,在本地计算机中的文件,有一些我们可以打开阅读并修改,但有一些却只能查看,甚至不能查看。只就是我们对文件进行了设置,设置它的打开方式。在Linux中,就显得格外的明显了。那么Python操作文件的时候,也有相对应的打开模式:

  1. 打开文件的模式有(默认为文本模式):
    r ,只读模式【默认模式,文件必须存在,不存在则抛出异常】
    w,只写模式【不可读;不存在则创建;存在则清空内容】
    a, 只追加写模式【不可读;不存在则创建;存在则只追加内容】

  2. 对于非文本文件,我们只能使用b模式,"b"表示以字节的方式操作(而所有文件也都是以字节的形式存储的,使用这种模式无需考虑文本文件的字符编码、图片文件的jgp格式、视频文件的avi格式)
    rb
    wb
    ab
    注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型,不能指定编码

  3. +’模式(就是增加了一个功能)
    r+, 读写【可读,可写】
    w+,写读【可写,可读】
    a+, 写读【可写,可读】

  4. 以bytes类型操作的读写,写读,写读模式
    r+b, 读写【可读,可写】
    w+b,写读【可写,可读】
    a+b, 写读【可写,可读】*

文件操作的具体方法

read(3):

1. 文件打开方式为文本模式时,代表读取3个字符

2. 文件打开方式为b模式时,代表读取3个字节

其余的文件内光标移动都是以字节为单位的如:seek,tell,truncate

注意:

  1. seek有三种移动方式0,1,2,其中1和2必须在b模式下进行,但无论哪种模式,都是以bytes为单位移动的

  2. truncate是截断文件,所以文件的打开方式必须可写,但是不能用w或w+等方式打开,因为那样直接清空文件了,所以truncate要在r+或a或a+等模式下测试效果

   def close(self, *args, **kwargs): # real signature unknown
        关闭文件
        pass

    def fileno(self, *args, **kwargs): # real signature unknown
        文件描述符  
        pass

    def flush(self, *args, **kwargs): # real signature unknown
        刷新文件内部缓冲区
        pass

    def isatty(self, *args, **kwargs): # real signature unknown
        判断文件是否是同意tty设备
        pass

    def read(self, *args, **kwargs): # real signature unknown
        读取指定字节数据
        pass

    def readable(self, *args, **kwargs): # real signature unknown
        是否可读
        pass

    def readline(self, *args, **kwargs): # real signature unknown
        仅读取一行数据
        pass

    def seek(self, *args, **kwargs): # real signature unknown
        指定文件中指针位置
        pass

    def seekable(self, *args, **kwargs): # real signature unknown
        指针是否可操作
        pass

    def tell(self, *args, **kwargs): # real signature unknown
        获取指针位置
        pass

    def truncate(self, *args, **kwargs): # real signature unknown
        截断数据,仅保留指定之前数据
        pass

    def writable(self, *args, **kwargs): # real signature unknown
        是否可写
        pass

    def write(self, *args, **kwargs): # real signature unknown
        写内容
        pass

    def __getstate__(self, *args, **kwargs): # real signature unknown
        pass

    def __init__(self, *args, **kwargs): # real signature unknown
        pass

    @staticmethod # known case of __new__
    def __new__(*args, **kwargs): # real signature unknown
        """ Create and return a new object.  See help(type) for accurate signature. """
        pass

    def __next__(self, *args, **kwargs): # real signature unknown
        """ Implement next(self). """
        pass

    def __repr__(self, *args, **kwargs): # real signature unknown
        """ Return repr(self). """
        pass

文件修改

文件的数据是存放于硬盘上的,因而只存在覆盖、不存在修改这么一说,我们平时看到的修改文件,都是模拟出来的效果,具体的说有两种实现方式:

方式一:将硬盘存放的该文件的内容全部加载到内存,在内存中是可以修改的,修改完毕后,再由内存覆盖到硬盘

import os  # 调用系统模块

with open('a.txt') as read_f,open('.a.txt.swap','w') as write_f:
    data=read_f.read() #全部读入内存,如果文件很大,会很卡
    data=data.replace('www','happy') #在内存中完成修改

    write_f.write(data) #一次性写入新文件

os.remove('a.txt')  #删除原文件
os.rename('.a.txt.swap','a.txt')   #将新建的文件重命名为原文件

方式二:将硬盘存放的该文件的内容一行一行地读入内存,修改完毕就写入新文件,最后用新文件覆盖源文件

import os

with open('a.txt') as read_f,open('.a.txt.swap','w') as write_f:
    for line in read_f:
        line=line.replace('www','happy')
        write_f.write(line)

os.remove('a.txt')
os.rename('.a.txt.swap','a.txt')

关于编码

asiic

包含数字,英文,特殊字符。利用八位表示一个字符
8位 = 1 byte 表示一个字符。

万国码unicode

将所有国家的语言包含在这个密码本。
初期:16位,两个字节,表示一个字符。
A : 00010000 00010010
中: 00010010 00010010
升级:32位,四个字节,表示一个字符。
A : 00010000 00010010 00010000 00010010
资源浪费。

utf-8

最少用8位(一个字节),表示一个字符。
英文:a :00010000 用8位表示一个字符。
欧洲:00010000 00010000 16位两个字节表示一个字符。
亚洲 中 :00010000 00010000 00010000 24位,三个字节表示一个字符。

gbk:国标

只包含:英文中文。
英文:a :00010000 8位,一个字节表示一个字符。
中文:中:00010000 00010000 16位,两个字节表示一个字符。
gb2312…

计算机单位之间的划算
8 bit = 1byte
1024byte=1kb
1024kb = 1MB
1024MB = 1GB
1024GB = 1TB

编码与解码

encode 编码 :str — > bytes

s = 'aAlice'  # str
s1 = s.encode('utf-8')  # bytes

encode 编码。gbk–>utf-8

s = 'hello girl'
s1 = s.encode('gbk')
print(s1)
s = '中国'
s1 = s.encode('utf-8')
print(s1)

unicode —> utf-8 编码 与解码:

s = 'alex'
s1 = s.encode('utf-8')  # unicode ---> utf-8 编码
s3 = s1.decode('utf-8')  # utf-8 ---> unicode 解码
print(s3)

unicode —> gbk 编码与解码:

s = 'alex'
s1 = s.encode('gbk')  # unicode ---> gbk 编码
s3 = s1.decode('gbk')  # gbk ---> unicode 解码
print(s3)

gbk —> utf-8

  s = 'alex'
    s1 = s.encode('gbk')
    print(s1)
    s2 = s1.decode('gbk').encode('utf-8')
    print(s2)

需要说的是:Linux的操作系统默认的编码是utf-8,Windows操作系统是gbk编码,Python中默认的编码是utf-8,所以,需要注意python与Windows操作系统之间的关系。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值