Python从入门到进阶(十四)——数据文件读写

一 数据文件读写

  1. python文件读写的方式

文件读写就是一种常见的IO操作。python封装了操作系统的底层接口,直接提供了文件读写相关的操作方法;文件读写不需要额外引入第三方库;

一个文件读写的步骤:
1、从硬盘中读取一个文件路径
2、加载文件到内存中,获取文件对象(也叫文件句柄)
3、通过文件对象对对接进行读写操作
4、最后需要关闭文件;
  1. 打开一个文件:
# 一般写法
f=open(file,mode,encoding='utf-8')

主要是三个参数,文件路径,打开模式,文件编码
关于打开模式的描述如下图:

文件打开模式描述
r以只读模式打开,并将文件指针指向文件头,不存在报错
w只写打开文件,文件存在清空,不存在创建
a以只追加可写模式打开文件,并将文件指针指向文件尾部,不存在创建
r+在r的基础上增加了可写功能
w+在w的基础上增加了可读功能
a+在a的基础上增加了可读功能
b读写二进制文件(默认是t,表示文本),需要与上面几种模式搭配使用,如ab,wb,ab,ab+(POSIX系统,包含Linux都会忽略该字符)
关于可写可读的三个模式的区别:
  • r+覆盖当前文件指针所在位置的字符;
  • w+在打开文件时就会先将文件内容清空,适合重写
  • a+只能写到文件末尾,适合追加
  1. 文件读取:
file = '1.txt'
file_obj = open(file,‘r’,encoding='utf-8')
content = file_obj.read()
print(content)
file_obj.close()

以只读模式打开一个文件,读取内容,关闭文件;
使用with 方式,可以写文件关闭代码;

file = '1.txt'
with open(file,‘r’,encoding='utf-8') as file_obj:
    	content = file_obj.read()
print(content)

按行读取:

file = '1.txt'
with open(file,‘r’,encoding='utf-8') as file_obj:		    					content = file_obj.readline() #读取一行
print(content)
for line in file_obj.readlines(): #读取多行
   print(line) 	
  1. 文件的写入
  • 写文件和读文件是一样的,唯一区别是调用open()函数时,传入标识符’w’,'w+'或者’wb’表示写文本文件或写二进制文件;
  • python提供了两个“写”方法: write() 和 writelines()。
f1=open('1.txt','w')
f1.write('123')
f1.close()
------------------
f1=open('1.txt','w')
f1.writelines(["1\n","2\n","3\n"])
f1.close()
  1. 创建文件夹
    使用os递归创建文件夹,已存在就覆盖
def testCrdir(self,name):
        os.makedirs(name,exist_ok=True)
  1. 文件夹拷贝
    实现文件夹拷贝,要求如下:
  • 使用 shutil 拷贝 “copy.py” 文件到 “/tmp/copy.py”
  • 拷贝 “copy.py” 文件到 “/tmp/copy2.py”, 保留元数据
  • 递归拷贝目录 “./” 到 “/tmp/file_test/”,如果已存在就覆盖
import shutil
shutil.copy(
    "copy.py", 
    "/tmp/copy.py"
)

# 拷贝文件,保持元数据
shutil.copy2(
    "copy.py", 
    "/tmp/copy2.py"
)

# 递归拷贝目录
shutil.copytree(
    "./", 
    "/tmp/file_test/", 
    dirs_exist_ok=True
)
  1. Python文件遍历
  • 稳定排序地遍历一个文件下的文件
def testFileForeach(self,dir):
        import os
        entries=os.listdir(dir)
        entries.sort()
        return entries

    def testff(self,dir):
        entries=self.testFileForeach(dir)
        for entry in entries:
            print(entry)
  • 遍历一个文件夹下的所有子文件夹,并返回所有’config.json’文件的绝对路径列表
def retrieve_file_paths(self,dir_name):
        file_paths=[]
        abs_dir_name=os.path.abspath(dir_name)
        cfg_file=os.path.join(abs_dir_name,'config.json')
        if os.path.exists(cfg_file):
            file_paths.append(cfg_file)
        
        for base,dirs,files in os.walk(abs_dir_name):
            for dir in dirs:
                cfg_file=os.path.join(base,dir,'config.json')
                if os.path.exists(cfg_file):
                    file_paths.append(cfg_file)
        print(file_paths)
        return file_paths

    def retrieve_file_paths(self,dir_name):
        file_paths=[]
        abs_dir_name=os.path.abspath(dir_name)
        for base,dirs,files in os.walk(abs_dir_name):
            for file_name in files:
                if file_name=='config.json':
                    file_path=os.path.join(base,file_name)
                    file_paths.append(file_path)
        print(file_paths)
        return file_paths

    def retrieve_file_paths(self,dir_name):
        file_paths=[]
        abs_dir_name=os.path.abspath(dir_name)
        for base,dirs,files in os.walk(abs_dir_name):
            cfg_file=os.path.join(base,'config.json')
            if os.path.exists(cfg_file):
                file_paths.append(cfg_file)
        print(file_paths)
        return file_paths
  1. 文件统计
    统计文件中行数,非空行数,以及空格间隔的token数
# -*- coding: UTF-8 -*-
import json
 
def count_file(file):
    line_count = 0
    non_empty_line_count = 0
    token_count = 0
 
    with open(file, 'r') as f:
        while True:
            # 读取每行
            line = f.readline()
            if not line:
                break
 
            line_count += 1
            line_len = len(line)
            line_token_count = 0
 
            # TODO(You): 请在此实现统计单行token数
 
            token_count += line_token_count
            if line_token_count > 0:
                non_empty_line_count += 1
 
    return {
        'file': file,
        'line_count': line_count,
        'line_token_count': token_count,
        'non_empty_line_count': non_empty_line_count
    }
 
if __name__ == '__main__':
    ret = count_file('count_file.py')
    print('行数:', ret['line_count'])
    print('非空行:', ret['non_empty_line_count'])
    print('非空词数:', ret['line_token_count'])
    with open('/tmp/count.json', 'w') as f:
        f.write(json.dumps(ret, indent=2, ensure_ascii=False))
请选出下列能正确实现这一功能的选项。
# A.
				blank=True
                for char in line:
                    if char in [' ','\t','\b','\n']:
                        if not blank:
                            line_token_count+=1
                        blank=True
                    else:
                        blank=False
# B.
                blank=False
                for char in line:
                    if char in [' ','\t','\b']:
                        blank=True
                    else:
                        if blank:
                            line_token_count+=1
                        blank=False
# C.
                blank=True
                i=0
                while i<line_len:
                    char=line[i]
                    if char in [' ','\t','\b','\n']:
                        if not blank:
                            line_token_count+=1
                        blank=True
                    else:
                        blank=False
                    i+=1
# D.
                blank=True
                i=0
                while i<line_len:
                    char=line[i]
                    if char in [' ','\t','\b']:
                        blank=True
                    else:
                        if blank:
                            line_token_count+=1
                        blank=False
                    i+=1
# B正确
  1. 文件夹压缩
    使用 shutil 对文件夹进行zip压缩,压缩过程显示进度条
使用 shutil 对文件夹进行zip压缩,压缩过程显示进度条

# -*- coding: UTF-8 -*-
import os
import shutil
import logging
from progress.bar import IncrementalBar
logger = logging.getLogger(__name__)

def count_files_in_dir(dir):
    totalFiles = 0
    for base, dirs, files in os.walk(dir):
        totalFiles += len(files)
    return totalFiles

def zip_with_progress(dir_path, zip_file):
    bar = None
    total_files = count_files_in_dir(dir_path)

    def progress(*args, **kwargs):
        # TODO(You): 进度条显示
    
    # 调用shutil.make_archive时,临时替换其 logger 参数,用来显示进度条
    old_info = logger.info
    logger.info = lambda *args, **kwargs: progress(*args, **kwargs)
    shutil.make_archive(dir_path, 'zip', dir_path, logger=logger)
    logger.info = old_info

    if bar is not None:
        bar.finish()

if __name__ == '__main__':
    zip_with_progress('./', '/tmp/test_file_zip.zip')
    print()

请选出下列能正确实现这一功能的选项。
# A.
def progress(*args, **kwargs):
    if not args[0].startswith('adding'):
        return

    nonlocal bar, total_files
    print('@开始压缩:{}'.format(zip_file))
    bar = IncrementalBar('正在压缩:', max=total_files)
    bar.next(1)
# B.
def progress(*args, **kwargs):
    if not args[0].startswith('adding'):
        return

    if bar is None:
        print('@开始压缩:{}'.format(zip_file))
        bar = IncrementalBar('正在压缩:', max=total_files)
    bar.next(1)
# C.
def progress(*args, **kwargs):
    if not args[0].startswith('adding'):
        return

    nonlocal bar, total_files
    if bar is None:
        print('@开始压缩:{}'.format(zip_file))
        bar = IncrementalBar('正在压缩:', max=total_files)
    bar.next(1)
# D.
def progress(*args, **kwargs):
    if not args[0].startswith('adding'):
        return

    nonlocal bar, total_files
    if bar is None:
        print('@开始压缩:{}'.format(zip_file))
        bar = IncrementalBar('正在压缩:', max=total_files)
    bar.next(1)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值