伍佰目录 短网址
  当前位置:海洋目录网 » 站长资讯 » 站长资讯 » 文章详细 订阅RssFeed

Python_学习之文件读写

来源:本站原创 浏览:127次 时间:2022-03-08

Python_学习之文件操作
一、初识⽂文件操作
二、读写操作
三、文件的操作顺序
四、模式介绍
五、示例

  1. 文件修改
  2. 大文件进行摘要md5验证
  3. 批量生成n行数数据的多个文件
  4. 批量读取文件n行数据
  5. 同时打开多个文件写法

一、初识⽂文件操作
  python来读写文件是用open()函数来打开一个⽂文件, 获取到⽂文件句句柄. 然后通过文件句柄就可以进行各种各样的操作了. 根据打开方式的不同能够执行的操 作也会有相应的差异.

  打开文件的方式: r, w, a, r+, w+, a+, rb, wb, ab, r+b, w+b, a+b默认使⽤用的是r(只读)模式

    绝对路劲:从根目录到当前位置如:c:\install\file.txt

  相对路劲:同一个文件夹的文件相对于当前程序所在的文件夹而言 ..\表示当前位置的上级目录 (常用)

print(__file__) 获取当前文件的路径

二、读写操作
  默认读模式只能读文件,不能做写操作,写模式只能写文件,不能读文件,除非使用(+)加模式

三、文件的操作顺序
  1、找到文件,打开作业,指定模式,根据文件保存时的编码来指定编码格式 :open(“path\file” , moth = “r/w/r+等”, encoding = “以什么编码格式显示文件内容”)

  2、根据对应模式所拥有的方法操作文件: f.read()等其它操作

  3、关闭文件 :f.close()

四、模式介绍
1、只读(r,rb)

r 表示以字符来读取

rb 表示以字节bytes来读取 ,如中文gbk 读取出来的格式为:b'\xd6\xd0',在读取图片,声音,视频文件时以此格式。

无论rb还是wb,ab模式都不用指定encoding,因为文件存储最后都是字节的形式存起来的,如果指定将报错:# ValueError: binary mode doesn't take an encoding argument# 找到文件,指向一个变量即句柄  f = open("path\file.txt", mode = "r", encoding = "UTF-8")    content = f.read()    print(content)  f.close()注:文件都有一个指针,读模式是从开头即指针为0时,进行读取的,当读取完毕后,指针停在文件的末尾,如果后面没有内容,不关闭文件的情况下,继续读取将读取的时空白。f.read()      一次性读取文件的全部内容,如果文件过大,将导致内存崩溃,系统宕机f.read(n)      可以指定读取文件的范围,如果模式为r ,n表示几个字符,如果模式时rb,n表示几个字节(此处涉及到编码级,utf-8 中文表示3个字节,gbk 中文表示2个字节)f.readline()   一次读取一行数据,readline() 默认末尾都加了\n 换行,如果想文件好看,需要在后面加上strip() 去掉换行符f.readlines()  把每一行一次读取出来放到一个列表中,然后需要对文件操作可以for循环,但同样文件过大时,会导致内存溢出,慎用。f.readable()   判断当前模式是否可读f.writeable()  判断当前模式是否可写如果需要对文件操作,可直接循环句柄f,它是一行一行拿出来进行操作的。for line in f:   print(f"读取每一行字符串:{line}")

2、只写(w, wb)

写模式,如果文件存在,则清空文件内容,如果文件不存在,则创建新文件,都是从开头写,写完指针停留在最后,直到关闭文件。f.write("内容")  内容只能是字符串,如果想将列表的元素写入只能通过for循环列表,直接填入列表,将报错。f.flush()        写完内容记得要及时将内容从缓存写入磁盘,不然可能导致内容没有写入文件f.close()

3、在读写的基础上附加功能

r +  读写,指针从零开始先读后写,如果先写的话,因打开文件指针在0处,写入的内容将从头覆盖相应长度的原文件内容(最常用)w+  写读,先清空,后从头写入文件,因指针在文件尾部,读取文件为空白a     追加模式,不能读,只能写,不会清空文件,会在尾部追加内容a+    追加读,不会清空文件,在尾部追加内容,因指针在尾部,读取文件时同样空白总结:在不改变指针位置的情况下,a、w+、a+ 都无法读到内容,因为加完内容后指针都在文件尾部

4、获取文件的位置即指针,及改变文件的指针

f.tell()    获取当前文件的位置,也是以字节为单位f.seek(n)   指定指针的位置,n是以字节为单位,如果是gbk,n 需要为2的倍数,utf-8 ,n 需要为3的倍数移动到开头:f.seek(0)移动到结尾:f.seek(0,2)        0表示偏移量,2表示结尾,1表示当前位置在r+模式下. 如果读取了了内容. 不论读取内容多少. 光标显⽰示的是多少. 再写入 或者操作⽂文件的时候都是在结尾进⾏的操作.

5、截断

截断truncate(),只有在有写的模式下才能截断想截断:方法1、通过seek(n)移动指针到截断位置,truncate()方法2、通过truncate(n)n没有指定是删除截断位置后的所有内容,n指定了就从头开始到n个字节

6、通过with……as 操作文件

因为通过f = open("path\file.txt", mode = "r", encoding = "UTF-8")很容易忘记关闭文件导致错位,故一般用with方式[上下文],它无需我们手动关闭,在我们操作完毕后with  open("path\file_name", moth = "w" , encoding= "utf-8")  as f:   f.write("name")   f.flush()

五、示例

1. 文件修改

import oswith open("myPwd.txt", "r", encoding="utf-8") as f1, \       open("myPwd_new.txt", "w", encoding="utf-8") as f2:   for line in f1:       new_data = line.replace("sun", "xiu")  # 逐行修改文件内容       f2.write(new_data)  # 将修改后的文件写入到新文件中os.remove("myPwd.txt.txt")os.rename("myPwd.txt_new.txt", "myPwd.txt.txt")
  1. 大文件进行摘要md5验证

import hashlib

def check_md5(file_path):   with open(file_path, 'rb') as f:       md5_obj = hashlib.md5()       while 1:           b_data = f.read(4096)           if b_data:               md5_obj.update(b_data)           else:               return md5_obj.hexdigest()
  1. 批量生成n行数数据的多个文件
import osimport timeimport datetimeimport threadingdef writ_file(path, file_name):    """    写入文件    :param path:    :param file_name:    :return:    """    st = "%s,00128980,00248980,00128980,%s"    with open(os.path.join(path, f'{file_name}.txt'), 'a', encoding='utf-8') as fp:        for i in range(1, 1651):            line_text = st % ((str(i).ljust(11, '0')), datetime.datetime.today().replace(microsecond=0))            fp.write(f'{line_text}\n')            print(f"线程{threading.get_ident()},写入数据:{line_text}完成")if __name__ == '__main__':    """    # 批量生产2个1650行的文件    """    now = time.time()    threads = []    x = 0    base_dir = os.path.dirname(os.path.abspath(__file__))    for i in range(0, 2):        t = threading.Thread(target=writ_file, args=(base_dir, x))        t.start()        threads.append(t)        x += 1    for j in threads:        j.join()    print(time.time() - now)
  1. 批量读取文件n行数据
# TODO:优化为一次夺取500行import tracebackfrom itertools import zip_longestdef grouper(iterable, n, fill_value=None):   """  分组读取文件  :param iterable:  :param n: 行数  :param fill_value: 当最后数据不够组数时的默认值  :return:  """   args = [iter(iterable)] * n   return zip_longest(*args, fillvalue=fill_value)def get_data(file_path):   """  读取文件,一次读取n行,返回生成器  :param file_path: 文件路径  :return: 返回的是一组数据  """   try:       with open(file_path, 'r', encoding='utf-8') as f:           for lines in grouper(f, 500, None):               print(f"一次数据{len(lines)}条,数据为:{lines}")               lines_data = []               for line in lines:                   # 当行数不够分组时,补充为None ('xxx',None,)                   if line:                       line = line.strip('\n')                       data = line.split(',')                       """此处省略从每行数据中获取需要的数据,仅仅是对字符串的处理了"""                       lines_data.append(tuple(data))               # 清除掉分组为None的元素               yield list(filter(None, lines_data))   except Exception as ex:       print(f'解析文件[file_path]={file_path}发生异常,异常原因为:{ex},位置为:{tr���,�տ�aceback.format_exc()}')       yield 500def save_data(generator_data):   """批量保存数据:如保存数据库或文件"""   count = 1   for line in generator_data:       for db in line:           string = "&".join(db)           with open("test.txt", mode="a", encoding="utf-8") as f:               f.write(f"{string}\n")               print(f"第{count}笔数据{line}保存成功")               count += 1def _main(file_path: list):   for path in file_path:       file_data = get_data(path)       save_data(file_data)if __name__ == '__main__':   _main(["0.txt", ])
  1. 同时打开多个文件写法
"""考虑如下的案例:同时打开三个文件,文件行数一样,要求实现每个文件依次读取一行,然后输出,我们先来看比较容易想到的写法:"""def open_more_file(filename1, filename2, filename3):   with open(filename1, 'rb') as fp1:       with open(filename2, 'rb') as fp2:           with open(filename3, 'rb') as fp3:               for i in fp1:                   j = fp2.readline()                   k = fp3.readline()                   print(i, j, k)def open_more_file_for_with(filename1, filename2, filename3):   with open(filename1, 'rb') as fp1, open(filename2, 'rb') as fp2, open(filename3, 'rb') as fp3:       for i in fp1:           j = fp2.readline()           k = fp3.readline()           print(i, j, k)def open_more_file_for_zip(filename1, filename2, filename3):   with open(filename1, 'rb') as fp1:       with open(filename2, 'rb') as fp2:           with open(filename3, 'rb') as fp3:               for i, j, k in zip(fp1, fp2, fp3):                   print(i, j, k)def open_more_file_for_contextlib(filename1, filename2, filename3):   """  语法糖ExitStack的用法https://docs.python.org/3/library/contextlib.html  :param filename1:  :param filename2:  :param filename3:  :return:  """   from contextlib import ExitStack   with ExitStack() as stack:       files = [stack.enter_context(open(fname)) for fname in (filename1, filename2, filename3)]       for i, j, k in zip(files[0], files[1], files[2]):           print(i, j, k)

  推荐站点

  • At-lib分类目录At-lib分类目录

    At-lib网站分类目录汇集全国所有高质量网站,是中国权威的中文网站分类目录,给站长提供免费网址目录提交收录和推荐最新最全的优秀网站大全是名站导航之家

    www.at-lib.cn
  • 中国链接目录中国链接目录

    中国链接目录简称链接目录,是收录优秀网站和淘宝网店的网站分类目录,为您提供优质的网址导航服务,也是网店进行收录推广,站长免费推广网站、加快百度收录、增加友情链接和网站外链的平台。

    www.cnlink.org
  • 35目录网35目录网

    35目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向35目录推荐、提交优秀网站。

    www.35mulu.com
  • 就要爱网站目录就要爱网站目录

    就要爱网站目录,按主题和类别列出网站。所有提交的网站都经过人工审查,确保质量和无垃圾邮件的结果。

    www.912219.com
  • 伍佰目录伍佰目录

    伍佰网站目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向伍佰目录推荐、提交优秀网站。

    www.wbwb.net