文件和IO

Python 2020-07-02 979

1.读取数据

默认情况下文件的读取和写入都采用系统默认的文本编码方式,可以使用sys.getdefaultencoding()查看默认编码,大部分机器的默认编码都是‘utf-8’。
在UNIX和windows系统上换行符是不同的(\n和\r\n),在使用‘rt’或者‘wt’时,\r\n统一被设置为\n,如果不想要这种行为,你可以在open()中设置newline=''.
关于文本读取和写入时会出现编码或者解码错误,open()中errors默认为‘strict’,表示遇到非法字符时抛出异常。设置ignore时则会忽略非法字符,设置replace时,非法字符将由?取代。

2.将输出重定向到文件中

print可以写文件

with open('file.txt', 'rt') as f:  
    print('Hello world', file=f)  

3.对于不存在的文件执行写入操作

当文件不存在时,才进行写入操作,可以使用‘x’模式替代常见的‘w’模式,当文件存在时,会抛出FileExistsError:

with open('file.txt', 'xt') as f:  
    f.write('test')  
FileExistsError: [Errno 17] File exists: 'file.txt'  

4.在字符串上执行I/O操作

我们想将一段文本或者二进制字符串写入类似文件的对象上
使用io.StringIO()和io.BytesIO()类来创建类似于文件的对象。这些对象可操作字符串数据。

>>> import io  
>>> s = io.StringIO()  
>>> s.write('Hello world\n')  
12  
>>> print('this is a test', file=s)  
>>> s.getvalue()  
'Hello world\nthis is a test\n'  
>>> s1 = io.StringIO('Hello\nworld\n')  
>>> s1.read(4)  
'Hell'  
>>> s1.read()  
'o\nworld\n'  
>>> s1  
<_io.StringIO object at 0x000001BF0F3AE678>  
>>> s1.getvalue()  
'Hello\nworld\n'  

当需要操作二进制时,可以使用io.BytesIO.

s = io.BytesIO()  
s.write(b'binary data')  
s.getvalue()  
b'binary data'  

当需要模拟出一个普通文件时,StringIO和BytesIO类是最适用的。
请注意,StringIO和BytesIO实例没有真正的文件描述符来对应。因此,它们没法工作在一个真正的系统级文件,如文件、管道、或套接字中。

5.读写压缩的数据文件

读取gzip或者bz2的格式压缩文件。使用python提供的gzip和bz2模块处理很简单。

import gzip  
with gzip.open('ys.gzip', 'rt') as f:  # 写入 wt  
    text = f.read()

import bz2  
with bz2.open('ys.bz2', 'rt') as f: # 写入 wt  
    text = f.read()  

当写入压缩数据时,压缩级别可以通过compresslevel关键字参数来指定。级别的默认值为9,代表最高的压缩等级。低压缩等级可以带来更好的性能表现,但压缩比不大。

6.对二进制文件做内存映射

通过内存映射的方式将一个二进制文件加载到可变的字节数组中,这样可以随机访问其内容,或者实现就地修改。

使用mmap模块实现对文件的内存映射

def memory_map(filename, access=mmap.ACCESS_WRITE):  
    size = os.path.getsize(filename)  
    fd = os.open(filename, os.O_RDWR)  # 以读写方式打开  
    return mmap.mmap(fd, size, access=access)

m = memory_map('a.txt')  
print(len(m)) # 59959  
print(m[:10]) # b'<GET https'  
m.close()  

由mmap()返回的mmap对象也可以当做上下文管理器使用

with memory_map('a.txt') as m:  
    print(len(m))

m.closed() #True  

默认情况下,mmap()打开的文件具有可读可写权限。对数据任何修改都会回到原始文件中。如果只读的话,使用mmap.ACCESS_READ(),如果想修改文件,但是修改的数据不写回原始文件,可以使用mmap.ACCESS_COPY().

7.处理路径名

使用os.path模块

>>> path = r'C:\Users\xx\Desktop\开发\2020_6\2020__6\a.txt'  
>>> os.path.basename(path) # 返回文件名  
'a.txt'  
>>> os.path.dirname(path) # 返回文件路径  
'C:\\Users\\xx\\Desktop\\开发\\2020_6\\2020__6'  
>>> os.path.join('home', 'data', os.path.basename(path)) # 把目录和文件名合成一个路径  
'home\\data\\a.txt'  
>>> path = r'~/Data/data.csv'  
>>> os.path.expanduser(path) # 把path中包含的"~"和"~user"转换成用户目录  
'C:\\Users\\xx/Data/data.csv'  
>>> os.path.splitext(path) # 分割路径,返回路径名和文件扩展名的元组  
('~/Data/data', '.csv')  

更多方法,点击链接

8.检测文件是否存在

检测某个文件或目录是否存在

>>> os.path.exists(r'C:\\a.txt')  
False  
>>> os.path.exists(r'C:\\Vue')  
True  

检测文件是否存在,并检测文件的类型是目录还是文件。

>>> os.path.isfile(r'C:\windows-version.txt')  
True  
>>> os.path.isdir(r'C:\windows-version.txt')  
False  
>>> os.path.islink(r'C:\windows-version.txt') # 判断路径是否为链接  
False  
>>> os.path.realpath(r'C:\windows-version.txt') # 返回path的真实路径  
'C:\\windows-version.txt'  

os.path需要注意权限问题

9.打印无法解码的文件名

当程序打印出文件名时,会出现UnicodeEncodeError异常,并伴随一条信息,‘surrogates not allowed’
当打印未知文件名时,可以使用以下方式来避免错误,

def bad_filename(filename):  
    return repr(filename)[1:-1]

try:  
    print(filename)  
except UnicodeEncodeError:  
    print(bad_filename(filename))  

函数bad_filename()的实现需要结合实际。

def bad_filename(filename):  
    temp = filename.encode(sys.getfilesystemencoding(), errors='surrogatescape')  
    return temp.decode('latin-1')  

10.串口通信

对于串口通信,使用pySerial包

import serial  
ser = serial.Serial('/dev/tty.usbmodem641', baudrate=9600, bytesize=8,parity='N', stopbits=1)  

设备名称可能会根据操作系统而有所不同,在Windows上,可以使用0,1的数字代表设备打开通信端口,如“COM0”,'COM1'。一旦打开,就可以通过read(),readline()和write()来调用数据。

ser.write(b'G1 X50')  
resp = ser.readline()  

11.序列化Python对象

python提供了一个特殊的存储数据的模块,pickle模块,但是个人在实际使用中很少用到。

标签:Python

文章评论

评论列表

已有0条评论