python读写文件
专栏:ExASIC Oct. 27, 2024, 10:03 a.m. 129 阅读
python读写文件

我们在做验证时常常需要

  • 读verilog filelist,

  • 生成Makefile,

  • 读bmp图片,

  • 生成bmp图片。

今天我们就以这几个需求为背景来看看python是如何读写文件的。

基本概念介绍

我们知道python中一切都是对象,“文件”也不例外。下面的实验可以看出文件是名叫\_io.TextIOWrapper的class。

实验:

>>> f = open ("test.txt", "w")
>>> type(f)
<class '_io.TextIOWrapper'>

常用操作函数

  • open()

  • seek()

  • tell()

  • read()

  • readline()

  • readlines()

  • write()

  • writelines()

  • flush()

  • close()

open(filename, mode)

mode:

  • “r” 只读(文件不存在则报错)

  • “w” 写(文件不存在则新建)

  • “a” 追加(文件不存在则新建)

+表示在原有的基础上增强了操作,都具有了读写属性:

  • “r+” 读(可写)

  • “w+” 写(可读)

  • “a+” 追加(可读)

b表示二进制读写:

  • “rb” 二进制读

  • “wb” 二进制写

  • “ab” 二进制

    +和b可以自由组合:

  • “rb+”

  • “wb+”

  • “ab+”

seek(offset, whence=0)

offset: 整数,正数向后,负数向前,位置是字节
whence:

  • 0:文件开头

  • 1:当前位置

  • 2:文件末尾

tell()

返回当前的位置

read(size=-1)

按字节读取文件
size指定读取的字节数,当size是负数时读到文件最后。

readline()


读取一行,返回字符串

readlines(size=-1)

读取多行,返回字符串的列表
size指定读取总字节数

write(text)

把字符串写到文件

writelines(list)


把字符串列表写到文件

flush()

把缓冲区内容写到硬盘

close()

把缓冲区内容写到硬盘,再关闭文件

示例一:读verilog filelist

假设我们有一个verilog filelist,需求是跳过带//注释的行,完成文件拼接。

# cat filelist
a.v 
b.v
//c.v
d.v

参考代码:

#read filelist
f = open("filelist", "r")
lines = f.readlines();
f.close()

#ignore // comment lines
#  and concat list to string
rtl_filelist = "verdi -2001"
for line in lines:
    if not line.startswith('//'):
        rtl_filelist += ' ' + line.rstrip()
print(rtl_filelist)

结果输出:
verdi -2001 a.v b.v d.v

示例二:生成Makefile

参考代码:

if not os.path.exists(tc_type):
    os.mkdir(tc_type)
    os.chdir(tc_type)
    def gen_makefile():
        fh = open("Makefile", "w")
        fh.write("\n")
        fh.write("dirs := $(shell ls -l | grep \"^d\" | awk '{print $$9}')\n\n")
        fh.write("clean_all:\n")
        fh.write("\t$(foreach dir, $(dirs), make -C $(dir) clean_all;)")
        fh.flush()
        fh.close()
    gen_makefile()
    os.chdir('..')

详见:《python基础模块三剑客:sys、os、shutil》的实例部分。

示例三:读写bmp图片

我们先来看一幅bmp图片是怎样存储数据的。一般来说,bmp图片的前54字节为文件头,接下来每3字节为一个像素。下图中的0x16, 0x5c, 0x30是一个像素点,共3字节,依次为蓝、绿、红,每种颜色各占1字节。

py-18-01.webp

需求:
假设我们已经知道图像的大小为1920x1080(每行1920个点,共1080行),我们的目标是:把红蓝交换。

那么我们的代码思路是:

  • 读bmp

    • 读取54字节,保存为文件头

    • 读取3字节,保存到列表

    • 读取3字节,保存到列表

    • 。。。

    • 一直读到图片末尾

  • 数字处理:红蓝交换

  • 写bmp

    • 写文件头

    • 把处理后的数据写到文件

参考代码:

# set resolution
w = 1920
h = 1080

# read bmp
fin = open("test.bmp", "rb")
bmp_header = fin.read(54)
bmp_data = []
for i in range(w):
    for j in range(h):
        pixel = fin.read(3)
        bmp_data.append(pixel)

# data process
for i in range(w*h):
    pixel = bmp_data[i]
    bmp_data[i] = pixel[::-1]

# write into another bmp
fout = open("out.bmp", "wb")
fout.write(bmp_header)
for pixel in bmp_data:
    fout.write(pixel)

输出结果:

py-18-02.webp

我们可以看到第一个像素0x16, 0x5c, 0x30变成了0x30, 0x5c, 0x16。

总结

本次介绍了python读写文件的基本方法和思路,用具体的例子演示了读写文本文件、读写二进制文件。

对于特定格式的文件,如xml、json、yaml、excel等,python有专用的模块来处理,后续会介绍。

感谢阅读,更多文章点击这里:【专栏:ExASIC】
最新20篇 开设专栏