其他分享
首页 > 其他分享> > cook book:文件与IO+数据编码和处理

cook book:文件与IO+数据编码和处理

作者:互联网

1:读写文本数据 :读写各种不同编码的文本数据ASCII,UTF-8或UTF-16编码等

# rt模式下,python在读取文本时会自动把\r\n转换成\n,文本文件用二进制读取用‘rt’;
# 使用带有 rt 模式的 open() 函数读取文本文件
with open('aaaa', "rt") as f:
    data = f.read()
    print(data, type(data))

输出aaaa文件读取出来的数据,\r\n都转换成\n,读取出来的数据是字符串str类型

with open('aaaa', "rt") as f:
    for line in f:
        print(line)
# 写入一个文本文件,使用带有 wt 模式的 open() 函数, 如果之前文件内容存在则清除并覆盖掉。
# 编写文本数据块
with open('somefile.txt', 'wt') as f:
    f.write(text1)
    f.write(text2)
    ...

# 重定向打印语句
with open('somefile.txt', 'wt') as f:
    print(line1, file=f)
    print(line2, file=f)
    ...
# 已存在文件中添加内容,使用模式为 at 的 open() 函数。
# 文件的读写操作默认使用系统编码,可以通过调用 sys.getdefaultencoding() 来得到。 
# 在大多数机器上面都是utf-8编码。如果你已经知道你要读写的文本是其他编码方式,
那么可以通过传递一个可选的 encoding 参数给open()函数 with open('somefile.txt', 'rt', encoding='latin-1') as f:
# Python支持非常多的文本编码。几个常见的编码是ascii, latin-1, utf-8和utf-16。 
在web应用程序中通常都使用的是UTF-8。 ascii对应从U+0000到U+007F范围内的7位字符。
latin-1是字节0-255到U+0000至U+00FF范围内Unicode字符的直接映射。
当读取一个未知编码的文本时使用latin-1编码永远不会产生解码错误。
使用latin-1编码读取一个文件的时候也许不能产生完全正确的文本解码数据,
但是它也能从中提取出足够多的有用数据。同时,如果你之后将数据回写回去,原先的数据还是会保留的
# with语句
# with语句给被使用到的文件创建了一个上下文环境, 但 with 控制块结束时,文件会自动关闭。你也可以不使用 with 语句,但是这时候你就必须记得手动关闭文件
f = open('somefile.txt', 'rt')
data = f.read()
f.close()

# 换行符的识别Unix和Windows中是不一样,分别是 \n 和 \r\n 
# 默认情况下,Python会以统一模式处理换行符。 这种模式下,在读取文本的时候,
Python可以识别所有的普通换行符并将其转换为单个 \n 字符。 类似的,在输出时会将换行符 \n 转换为系统默认的换行符。
如果你不希望这种默认的处理方式,可以给 open() 函数传入参数 newline='' ,
with open('somefile.txt', 'rt', newline='') as f:
# 在Unix机器上面读取一个Windows上面的文本文件
    内容是 hello world!\r\n
>>> # 已启用换行转换(默认)
>>> f = open('hello.txt', 'rt')
>>> f.read()
'hello world!\n'

>>> # 新行翻译已禁用
>>> g = open('hello.txt', 'rt', newline='')
>>> g.read()
'hello world!\r\n'
>>>
# 读取文件编码错误问题,读取或者写入一个文本文件时,你可能会遇到一个编码或者解码错误
>>> f = open('sample.txt', 'rt', encoding='ascii')
>>> f.read()
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "/usr/local/lib/python3.3/encodings/ascii.py", line 26, in decode
        return codecs.ascii_decode(input, self.errors)[0]
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position
12: ordinal not in range(128)
>>>

这种错误通常表示你读取文本时指定的编码不正确,

# 仔细阅读说明并确认你的文件编码是正确的(比如使用UTF-8而不是Latin-1编码或其他)。 
如果编码错误还是存在的话,你可以给 open() 函数传递一个可选的 errors 参数来处理这些错误。 下面是一些处理常见错误的方法 >>> # 用Unicode U+fffd替换字符替换坏字符 >>> f = open('sample.txt', 'rt', encoding='ascii', errors='replace') >>> f.read() 'Spicy Jalape?o!' >>> # 完全忽略坏字符 >>> g = open('sample.txt', 'rt', encoding='ascii', errors='ignore') >>> g.read() 'Spicy Jalapeo!' >>> # 对于文本处理的首要原则是确保你总是使用的是正确编码。当模棱两可的时候,就使用默认的设置(通常都是UTF-8)

2:打印输出至文件中    将 print() 函数的输出重定向到一个文件中去 ——>在 print() 函数中指定 file 关键字参数

with open('d:/work/test.txt', 'wt') as f:
    print('Hello World!', file=f)
文件必须是以文本模式打开。 如果文件是二进制模式的话,打印就会出错

3:使用其他分隔符或行终止符打印  使用 print() 函数输出数据,改变默认的分隔符或者行尾符

# print() 函数中使用 sep 和 end 关键字参数,改变输出方式
print('ACME', 50, 91.5)                         # ACME 50 91.5
print('ACME', 50, 91.5, sep=',')                # ACME,50,91.5
print('ACME', 50, 91.5, sep=',', end='!!\n')    # ACME,50,91.5!!

# end 参数可以在输出中禁止换行
for i in range(5):
    print(i, end=' ')

# str.join和sep最后输出一样
print(','.join(('ACME', '50', '91.5')))
print('ACME', 50, 91.5, sep=',')

# str.join() 的问题在于它仅仅适用于字符串
row = ('ACME', 50, 91.5)
print(','.join(row))    #  报错join里面的参数需要每个都是字符串
print(','.join(str(x) for x in row))   # 需要这样写

# 直接使用sep参数也可以
row = ('ACME', 50, 91.5)
print(*row, sep=',')

4:读写字节数据   读写二进制文件,比如图片,声音文件等,  使用rb 或 wb 的 open() 函数来读取或写入二进制数据

# rb 或 wb 的 open() 函数来读取或写入二进制数据
# 以单字节字符串的形式读取整个文件
with open('somefile.bin', 'rb') as f:
    data = f.read()

# 将二进制数据写入文件
with open('somefile.bin', 'wb') as f:
    f.write(b'Hello World')

# 读取二进制数据时,需要指明的是所有返回的数据都是字节字符串格式的,而不是文本字符串。 
# 在写入的时候,必须保证参数是以字节形式对外暴露数据的对象(比如字节字符串,字节数组对象等)
# 读取二进制数据的时候,字节字符串和文本字符串的语义差异可能会导致一个潜在的陷阱,索引和迭代动作返回的是字节的值而不是字节字符串
t = 'Hello World'
print(t[0])         # H

b = b'Hello World'
print(b[0])         # 72   返回的是字节H的十进制的值72,不是返回的b'H'这个字节
        
# 从二进制模式的文件中读取或写入文本数据,必须确保要进行解码和编码操作
with open('somefile.bin', 'rb') as f:
    data = f.read(16)
    text = data.decode('utf-8')

with open('somefile.bin', 'wb') as f:
    text = 'Hello World'
    f.write(text.encode('utf-8'))

decode解码,encode编码
# 二进制I/O还有一个鲜为人知的特性就是数组和C结构体类型能直接被写入,而不需要中间转换为自己对象
import array
nums = array.array('i', [1, 2, 3, 4])
with open('data.bin','wb') as f:
    f.write(nums)
# 这个把数组对象写入文本,可以直接写入这个数组对象,并不是写入一个字符串 # 这个适用于任何实现了被称之为”缓冲接口”的对象,这种对象会直接暴露其底层的内存缓冲区给能处理它的操作。 二进制数据的写入就是这类操作之一 # 很多对象还允许通过使用文件对象的 readinto() 方法直接读取二进制数据到其底层的内存中去 >>> import array                      # array是数组,这个数组里面只能放数字 >>> a = array.array('i', [0, 0, 0, 0, 0, 0, 0, 0]) >>> with open('data.bin', 'rb') as f: ... f.readinto(a) # 从f文件句柄中读取数据后放到a这个容器中,所以返回[1, 2, 3, 4, 0, 0, 0, 0] ... 16 >>> a array('i', [1, 2, 3, 4, 0, 0, 0, 0]) >>>
# mmap,内存映射文件,文件data.bin可以放字符串
import mmap

a = mmap.mmap(-1, 20)

with open('data.bin', 'rb') as f:
    f.readinto(a)
    print(a.read())

 

标签:rt,数据编码,读取,编码,book,文件,IO,print,open
来源: https://www.cnblogs.com/yuanwt93/p/15109405.html