今天一个购买我课程的小伙伴,问我一个问题,他的问题描述如下:
“需要读取指定arc.data文件,指定某一个关键字符串为起始位置读取(假设指定字符串为“Wxl”),一直读取到指定的关键字符串为结尾(假设为“3Q8”),截取其间内容,并将内容重定向到另外一个文件。”
文件arc.data内容,部分内容如下:
PHRhYmxlIHN0eWxlPSIgY29sb3I6IzNjM2IzYjtmb250LXNpemU6MTRweDsgYm9yZGVyOnNvbGlk
dGQ+PHRkIHN0eWxlPSJiYWNrZ3JvdW5kOiNmZmY7dGV4dC1hbGlnbjpsZWZ0OyI+RndkOnRlc3Q8
L3RkPiAgPC90cj48dHI+PHRkIHN0eWxlPSJ3aWR0aDoxMDBweDsgb3ZlcmZsb3c6aGlkZGVuOyB0
ZXh0LWFsaWduOmNlbnRlcjsgZm9udC1zaXplOjEycHg7Zm9udC13ZWlnaHQ6NjAwO2JhY2tncm91
bmQ6I2Y1ZjVmNTsiPuaUtuS7tuS6uu+8mjwvdGQ+PHRkIHN0eWxlPSJiYWNrZ3JvdW5kOiNmZmY7
dGV4dC1hbGlnbjpsZWZ0OyI+PGEgaHJlZj0iIyI+cG9zdG1hc3RAcm9vdDwvYT48L3RkPjwvdHI+
ICA8dHI+ICAgIDx0ZCBzdHlsZT0id2lkdGg6MTUwcHg7IG92ZXJmbG93OmhpZGRlbjsgZm9udC13
对于这个问题,Jeson觉得同学们需要重点掌握内容有如下两部分。
第一,需要了解open() 函数对于文件的处理,
file 对象方法方法如下:
file.read([size]) size未指定则返回整个文件,如果文件大小>2倍内存则有问题.f.read()读到文件尾时返回""(空字串)
file.readline() 返回一行
file.readlines([size]) 返回包含size行的列表,size 未指定则返回全部行
for line in f: print line #通过迭代器访问
f.write("hello\n") #如果要写入字符串以外的数据,先将他转换为字符串.
f.tell() 返回一个整数,表示当前文件指针的位置(就是到文件头的比特数).
f.seek(偏移量,[起始位置]) 用来移动文件指针.
偏移量:单位:比特,可正可负
起始位置:0-文件头,默认值;1-当前位置;2-文件尾
f.close() 关闭文件
第二,对于文件的读取思路类比
Jeson老师觉得,我们可以想象成对于一串字符串的读取,假设字符串“abcdefg”,我们要读取c到f中间位置的数据,改如何读取?
abcdefg
答:
(1)我们分别把f的位置读取到,再把c的位置读取到。
f所在的文件指针位置为5,c所在的文件指针位置为2,那么如下:
f所在的文件指针位置-c琐杂的文件指针=5-2=共需要读取的长度。
(2)然后调用seek()定位到c所在的文件指针位置,read()所需要的长度。
所以,综上所属,略写了一个函数如下:
In [35]: def readfiles_pos(start_key_chr,start_key_w,start_key_len):
...: f = open('./arc.data','r')
...: while True:
...: r_cnt = f.read(1)
...: if r_cnt == start_key_chr:
...: r2_cnt = f.read(int(start_key_len)-1)
...: if r2_cnt == start_key_w[1:]:
...: return f.tell()
...: break
新定义的函数readfiles_pos(),作用用于读取指定关键字,所在文件中的指针位置,并返回值。
需要传入的参数,定义如下:start_key_w为需要查找的关键字内容,start_key_chr为需要查找的关键字内容的首字母,start_key_len为关键字内容的长度。
接下来,演示下执行调用过程:
// 查找起始字符串“Wxl”读取完后的位置,调用如下:
In [35]: readfiles('W','Wxl',3)
Out[35]: 16
// 查找结束字符串“3Q8”的位置,调用如下:
In [27]: readfiles('3','3Q8',3)
Out[27]: 1480
// 结束字符串“3Q8”的位置 - 起始字符串“Wxl”的位置 - 结束字符串“3Q8”的长度
In [32]: 1480-16-3
Out[32]: 1461
// 调用seek(),将文件读取指针定位到起始字符串“Wxl”读取完后的位置,如下:
In [33]: f.seek(16)
// 读取指定长度,结果如下:
In [34]: f.read(1461)
Out[34]: 'PSIgY29sb3I6IzNjM2IzYjtmb250LXNpemU6MTRweDsgYm9yZGVyOnNvbGlk\r\nIDFwe...
最后,谢谢这位同学,给予我的课程好评,当然也谢谢一直支持Jeson老师的朋友及同学们!
领取专属 10元无门槛券
私享最新 技术干货