Python Day09

文件

文件分为两种类型:文本文件和二进制文件。
文件操作的顺序:打开文件、操作文件(读或写)、关闭文件。

打开文件 open()函数
file_object = open(file_name [,access_mode])
access_mode是访问模式,指定了打开文件的方式
在这里插入图片描述
'w’模式打开文件会比较危险,容易导致此前的内容遗失。
在这里插入图片描述
open()文件之后,一定要close()关闭。
Python拥有垃圾收集机制,会在文件对象的引用计数降至零的时候自动关闭文件,所以在Python编程里,如果忘记关闭文件并不会造成内存泄漏那么危险。
但并不是说就可以不要关闭文件,如果你对文件进行了写入操作,那么你应该在完成写入之后进行关闭文件。因为Python可能会缓存你写入的数据,如果这中间断电了,那些缓存的数据根本就不会写入到文件中。

注意:
Windows在路径名中既可以接受斜线(/)也可以接受反斜线(\),不过如果使用反斜线作为路径名的分隔符的话,要注意使用双反斜线(\)进行转义。

>>> f = open("D:\\Python\\readme.txt")    #默认模式是r
>>> f
<_io.TextIOWrapper name='D:\\Python\\readme.txt' mode='r' encoding='cp936'>
>>> f.read()   #参数如果不做设置,则全部读取
'我什么时候才能成为大佬?\n我什么时候才能出任CEO?\n我什么时候才能赢取白富美?\n我什么时候才能走向人生巅峰?'
>>> f.read()   #再读取一次,则读取为空,因为文件指针指向了文件末尾
''
>>> f = open("D:\\Python\\readme.txt")
>>> f.read(5)   #从文件开头读取5个字符
'我什么时候'
>>> f.tell()    #返回当前在文件中的位置
10              #因为一个中文字符占两个字节
>>> 
>>>> #seek()可以修改文件指针
>>> f.seek(30,0)   #从0开始偏移30个字节
30
>>> f.readline()   #读取一行
'么时候才能出任CEO?\n'
>>> list(f)       #将文件转变成列表
['我什么时候才能赢取白富美?\n', '我什么时候才能走向人生巅峰?']
>>> f.seek(0,0)    #将文件指针定位到开头
0
>>> for eachline in f:
	print(eachline)
我什么时候才能成为大佬?
我什么时候才能出任CEO?
我什么时候才能赢取白富美?
我什么时候才能走向人生巅峰?
>>> 
>>> f = open('D:\\Python\\test.txt','w')
>>> f.write("肖战哥哥你最棒!!!")
10			    #返回的是写入字符个数
>>> f.close()   #没关闭之前,写入的内容会存放在缓冲区。关闭文件后才能被写入文件。
>>> 

将 f2 写入 f1 中。如果打开方式使用 ‘r+’ ,文件指针在文件起始处,f2的内容会覆盖掉一部分内容。

>>> f1 = open("D:\\Python\\readme.txt",'a') #在f1追加
>>> f2 = open("D:\\Python\\test.txt")
>>> f1.write(f2.read())
10
>>> f1.close()
>>> f2.close()
>>> 

一个任务:

#任务描述:
#将three dialogue文本中的三段对话(三段话用====已经隔开),分别保存为六个文件
#去掉 A: 和 B:
#A的对话单独保存为A_*.txt    B的对话单独保存为B_*.txt  *=1,2,3

def save_file(A,B,count):

    file_name_A = 'A_' + str(count) + '.txt'
    file_name_B = 'B_' + str(count) + '.txt'

    A_file = open(file_name_A,'w')
    B_file = open(file_name_B,'w')

    A_file.writelines(A)
    B_file.writelines(B)

    A_file.close()
    B_file.close()
    
def split_file(file_name):
    f = open("D:\\Python\\three dialogue.txt")

    A = []
    B = []
    count = 1    #方便文件的命名

    for each_line in f:
        if each_line[:6] != "======":
        #进行字符串的分割操作
            (role,line_spoken) = each_line.split(':',1)   #num是分割次数,num=1,意思是分成两个字符串
            if role == 'A':
                A.append(line_spoken)
            if role == 'B':
                B.append(line_spoken)

        else:
        #进行文件保存操作
            save_file(A,B,count)

            A = []
            B = []
            count += 1

    save_file(A,B,count)

    f.close()

split_file("D:\\Python\\three dialogue.txt")
  1. 编写一个程序,接受用户的输入并保存为新的文件。
def write_save(file_name):
    print("请输入内容,单独输入\':w\'保存退出")
    f = open(file_name,'w')
    
    while True:
        write_some = input()
        if write_some != ':w':
            f.write('%s\n' % write_some)
        else:
            break

    f.close()

file_name = input("请输入文件名:")
write_save(file_name)
  1. 编写一个程序,比较用户输入的两个文件,如果不同,显示出所有不同处的行号与第一个不同字符的位置。
def compare_file(file_1,file_2):
    f_1 = open(file_1)
    f_2 = open(file_2)

    count = 0
    differ = []

    for eachline in f_1:
        count += 1

        if eachline != f_2.readline():
            differ.append(count)

    f_1.close()
    f_2.close()

    return differ

file_1 = input("请输入需要比较的第一个文件名:")
file_2 = input("请输入需要比较的第二个文件名:")

differ = compare_file(file_1,file_2)

if len(differ) == 0:
    print("两个文件完全一样")
else:  
    print("两个文件共有%d处不同" % len(differ))
    for each in differ:
        print("第%d行不同" % each)

运行结果如下:
在这里插入图片描述
2. 编写一个程序,当用户输入文件名和行数(N)后,将该文件的前N行内容打印到屏幕上。

def Print_N_Line(file_name,N):
    print("\n文件%s的前%d行的内容如下:\n" % (file_name,N))
    f = open(file_name)
    while N:
        print(f.readline())
        N = N - 1

    f.close()

file_name = input("请输入要打开的文件及路径(C:\\test.txt):")
N = int(input("请输入要打印的行数:"))
Print_N_Line(file_name,N)

运行结果:
在这里插入图片描述
3. 要求在上一题的基础上扩展,用户可以随意输入需要显示的行数。(如输入13:21打印第13行到第21行,输入:21打印前21行,输入21:则打印从第21行开始到文件结尾所有内容)

def file_view(file_name,line_num):
    if line_num.strip() == ':':    #去除首尾的空格,只剩:,要打印全文
        begin = '1'
        end = '-1'

    (begin,end) = line_num.split(':')

    if begin == '':
        begin = '1'#从头开始
    if end == '':
        end = '-1' #直到结尾

    if begin == '1' and end == '-1':
        prompt = '的全文'
    elif begin == '1':
        prompt = '从开始到%s' % end
    elif end == '-1':
        prompt = '从%s到结束' %begin
    else:
        prompt = '从第%s行到第%行' %(begin,end)

    print("\n文件%s%s的内容如下:\n" % (file_name,prompt))

    begin = int(begin) - 1
    end = int(end)
    lines = end - begin

    f = open(file_name)

    for i in range(begin):
        f.readline()

    if lines < 0:
        print(f.read())
    else:
        for j in range(lines):
            print(f.readline(),end = '')

    f.close()
    
file_name = input("请输入要打开的文件(C:\\test.txt)")
line_num = input("请输入需要显示的行数( 13:21 or :21 or 21: )")
file_view(file_name,line_num)
  1. 编写一个程序,实现“全部替换”功能。
def file_replace(file_name,rep_word,new_word):
    #读
    f_read = open(file_name)

    content = []
    count = 0

    for eachline in f_read:
        if rep_word in eachline:
            count = count + eachline.count(rep_word)
            #count() 方法用于统计字符串里某个字符出现的次数
            eachline = eachline.replace(rep_word,new_word)
        content.append(eachline)

    print("\n文件%s中共有%s个【%s】" %(file_name,count,rep_word))
    decide = input("\n您确定要把所有的【%s】替换为【%s】吗?[yes or no]\n" %(rep_word,new_word))

    #写
    if decide in ['YES','Yes','yes']:
        f_write = open(file_name,'w')
        f_write.writelines(content)
        f_write.close()

    f_read.close()

file_name = input("请输入文件名:")
rep_word = input("请输入需要替换的单词或字符:\n")
new_word = input("请输入新的单词或字符:\n")
file_replace(file_name,rep_word,new_word)

在这里插入图片描述
在这里插入图片描述
os.path模块中关于路径常用的函数使用方法
在这里插入图片描述
0. 编写一个程序,统计当前目录下每个文件类型的文件数,程序实现如图

import os

all_files = os.listdir(os.curdir)# 使用os.curdir表示当前目录更标准
type_dict = dict()

for each_file in all_files:
    if os.path.isdir(each_file):
        type_dict.setdefault('文件夹',0)
        type_dict['文件夹'] += 1

    else:
        ext = os.path.splitext(each_file)[1] #分离文件名和扩展名,将扩展名赋值给ext
        type_dict.setdefault(ext,0)
        type_dict[ext] += 1

for each_type in type_dict.keys():
    print('该文件夹下共有【%s】的文件%d个' % (each_type,type_dict[each_type])
  1. 编写一个程序,计算当前文件夹下所有文件的大小。
import os

all_files = os.listdir(os.curdir)
file_dict = dict()

for each_file in all_files:
    if os.path.isfile(each_file):
        file_size = os.path.getsize(each_file)
        file_dict[each_file] = file_size

for each in file_dict.items():
    print('%s[%d Byte]' % (each[0],each[1]))
  1. 编写一个程序,用户输入文件名以及开始搜索的路径,搜索该文件是否存在。如遇到文件夹,则进入文件夹继续搜索
import os

def search_file(start_dir,target):
    os.chdir(start_dir)

    for each_file in os.listdir(os.curdir):
        if each_file == target:
            print(os.getcwd() + os.sep + each_file)#os.sep根据你所处的平台,自动采用相应的分隔符号
        if os.path.isdir(each_file):
            search_file(each_file,target) #递归调用
            os.chdir(os.pardir) #递归调用后要返回上一层目录

start_dir = input('请输入待查找的初始目录:')
target = input('请输入需要查找的目标文件:')
search_file(start_dir,target)

#[运行结果]
========================= RESTART: D:\Python\搜索文件.py =========================
请输入待查找的初始目录:D:\\Python
请输入需要查找的目标文件:恭喜你找到我了.txt
D:\Python\你可以找到我吗1\你能否找到我\恭喜你找到我了.txt
D:\Python\你可以找到我吗2\恭喜你找到我了.txt
>>> 
  1. 编写一个程序,用户输入开始搜索的路径,查找该路径下(包含子文件夹内)所有的视频格式文件(要求查找mp4 rmvb, avi的格式即可),并把创建一个文件(vedioList.txt)存放所有找到的文件的路径
import os

def search_file(start_dir,target):
    os.chdir(start_dir)

    for each_file in os.listdir(os.curdir):
        ext = os.path.splitext(each_file)[1]
        if ext in target:
            vedio_list.append(os.getcwd() + os.sep + each_file + os.linesep)#os.linesep字符串给出当前平台使用的行终止符
        if os.path.isdir(each_file):
            search_file(each_file,target)
            os.chdir(os.pardir)

start_dir = input("请输入待查找的初始目录:")
program_dir = os.getcwd()

target = ['.mp4','.avi','.rmvb']
vedio_list = []

search_file(start_dir,target)

f = open(program_dir + os.sep + 'vedioList.txt','w')
f.writelines(vedio_list)
f.close()

【运行结果】
在这里插入图片描述
4. 编写一个程序,用户输入关键字,查找当前文件夹内(如果当前文件夹内包含文件夹,则进入文件夹继续搜索)所有含有该关键字的文本文件(.txt后缀),要求显示该文件所在的位置以及关键字在文件中的具体位置(第几行第几个字符)。

import os

def print_pos(key_dict):
    keys = key_dict.keys()
    keys = sorted(keys)
    for each_key in keys:
        print('关键字出现在第%s行,第%s个位置.'% (each_key,str(key_dict[each_key])))
        

def pos_in_line(line,key):
    pos = []
    begin = line.find(key)
    while begin != -1:
        pos.append(begin + 1)
        begin = line.find(key,begin+1) #从下一个位置继续查找

    return pos

def search_in_file(file_name,key):
    f = open(file_name)
    count = 0
    key_dict = dict()#字典,用户存放key所在具体行数对应具体位置

    for each_line in f:
        count += 1

        if key in each_line:
            pos = pos_in_line(each_line,key)
            key_dict[count] = pos

    f.close()
    return key_dict


def search_files(key,detail):
    all_files = os.walk(os.getcwd())
    #os.walk方法,主要用来遍历一个目录内各个子目录和子文件
    #可以得到一个三元tupple(dirpath, dirnames, filenames),
    #第一个为起始路径,第二个为起始路径下的文件夹,第三个是起始路径下的文件。
    #dirpath 是一个string,代表目录的路径,
    #dirnames 是一个list,包含了dirpath下所有子目录的名字。
    #filenames 是一个list,包含了非目录文件的名字。
    #这些名字不包含路径信息,如果需要得到全路径,需要使用os.path.join(dirpath, name).
    txt_files = []

    for i in all_files:
        for each_file in i[2]:#非目录文件的名字
            if os.path.splitext(each_file)[1] == '.txt':
                each_file = os.path.join(i[0],each_file)
                txt_files.append(each_file)
    for each_txt_file in txt_files:
        key_dict = search_in_file(each_txt_file,key)
        if key_dict:
            print('=============================')
            print('在文件【%s】中找到关键字【%s】' % (each_txt_file,key))
            if detail in ['YES','Yes','yes']:
                print_pos(key_dict)

key = input("请将该脚本放于待查找的文件内,请输入关键字:")
detail = input("请问是否需要打印关键字【%s】在文件中的具体位置(YES/NO):" % key)
search_files(key,detail)

【运行结果】
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值