文章目录

  • 1.打开文件
  • 2.文件对象的方法
  • 3.OS模块
  • 4.os.path模块
  • 5.应用:使用shutil拷贝文件

1.打开文件

  • 利用help(open)可以看到open()函数的定义:open(file,mode=‘r’,buffering=1,encoding=None,errors=None,newline=None,closefd=True,opener=None)
    默认打开模式是’rt’,也就是只读和文本模式。

打开模式

执行操作

‘r’

以只读方式打开文件(默认)

‘w’

以写入的方式打开文件,会覆盖已存在的文件(有风险**)

‘x’

如果文件已经存在,使用此模式打开将引发异常

‘a’

以写入模式打开,如果文件存在,则在末尾追加写入

‘b’

以二进制模式打开文件

‘t’

以文本模式打开(默认)

‘+’

可读写模式(可添加到其他模式中使用)

‘U’

通用换行符支持



2.文件对象的方法

  • 文件对象的方法

文件对象的方法

执行操作

close()

关闭文件

read(size=-1)

从文件读取size个字符(单位是字节,中文算2个字节),当未给定size或给定负值的时候,读取剩余的所有字符,然后作为字符串返回(注意这里的读取是从文件指针开始读取,而不是从初始位置)

readline()

从文件中读取一整行字符串(包括末尾的换行’\n’)

write(str)

将字符串str写入文件

writelines(seq)

向文件写入字符串序列seq(列表就是一个序列),seq应该是一个返回字符串的可迭代对象

seek(offset, from)

在文件中移动文件指针,从from(0代表文件起始位置,1代表当前位置,2代表文件末尾)偏移offset个字节

tell()

返回当前文件指针在文件中的位置



  • eg:

    可以直接将文件对象转换为list

    迭代去读文本中的每一行,下面的方法没效率

    更好的方式如下:
  • 测试:
>>> f = open("D:\\python3.3.2\Hello.txt",'w')#w模式写入会覆盖已存在的文件(即原文件内容全部被删除),a模式则在末尾追加写入
>>> f.write('who are you')          #返回的是写入的字符数
11
>>> f.close()
  • eg:将文件(record.txt)中的数据进行分割并按照以下规律保存起来:
    小甲鱼的对话单独保存为boy_.txt的文件(去掉“小甲鱼:”);
    小客服的对话单独保存为girl_
    .txt的文件(去掉“小客服:”);
    文件中总共有三段对话,分别保存为boy_1.txt, girl_1.txt,boy_2.txt, girl_2.txt, boy_3.txt, gril_3.txt共6个文件(提示:文件中不同的对话间已经使用“==========”分割);
(1)方法1
f = open("record.txt")

boy = []
girl = []
count = 1

for each_line in f:
    if each_line[:6] != '======':#判断是否连续读到六个=
        (role,line_spoken) = each_line.split(':',1)#split以:进行字符切割,
        #将切得到的两部分内容依次存放在role与line_spoken中
        if role == '小甲鱼':
            boy.append(line_spoken)#将小甲鱼说的内容添加到列表boy中
        if role == '小客服':
            girl.append(line_spoken)#将小客服说的内容添加到列表girl中
    else:
        file_name_boy = 'boy_' + str(count) + '.txt'
        file_name_girl = 'girl_' + str(count) + '.txt'

        boy_file = open(file_name_boy,'w')#以w模式新建一个以file_name_boy命名的txt文件
        girl_file = open(file_name_girl,'w')#并贴上boy_file的标签

        boy_file.writelines(boy)#将列表boy中的内容写入到boy_file文件中
        girl_file.writelines(girl)

        boy_file.close()#关闭boy_file文件
        girl_file.close()

        boy = []#清空列表boy
        girl = []
        count += 1

file_name_boy = 'boy_' + str(count) + '.txt'
file_name_girl = 'girl_' + str(count) + '.txt'

boy_file = open(file_name_boy,'w')
girl_file = open(file_name_girl,'w')

boy_file.writelines(boy)
girl_file.writelines(girl)

boy_file.close()
girl_file.close()#记得关闭文件

(2)方法2,封装
def save_file(boy,girl,count):
    file_name_boy = 'boy_' + str(count) + '.txt'
    file_name_girl = 'girl_' + str(count) + '.txt'

    boy_file = open(file_name_boy,'w')
    girl_file = open(file_name_girl,'w')

    boy_file.writelines(boy)
    girl_file.writelines(girl)

    boy_file.close()
    girl_file.close()

def split_file(file_name):
    f = open(file_name)

    boy = []
    girl = []
    count = 1

    for each_line in f:
        if each_line[:6] != '======':
            (role,line_spoken) = each_line.split(':',1)#split以:进行字符切割,
            #将切得到的两部分内容依次存放在role与line_spoken中
            if role == '小甲鱼':
                boy.append(line_spoken)
            if role == '小客服':
                girl.append(line_spoken)
        else:
            save_file(boy,girl,count)

            boy = []
            girl = []
            count += 1


    save_file(boy,girl,count)
    f.close()

split_file('record.txt')
  • 测试:

3.OS模块

  • 模块是包含你所定义的所有的函数和变量的文件,其后缀名是.py。模块可以被别的程序引入,以使用该模块中的函数等功能。
  • OS:Operating System操作系统
  • OS模块中关于文件/目录常用的函数使用方法

函数名

使用方法

getcwd()

返回当前工作目录

chdir()

改变工作目录

listdir(path=‘.’)

列举指定目录中的文件名('.‘表示当前目录,’…'表示上一级目录)

mkdir(path)

创建单层目录,如果目录已存在抛出异常

makedirs(path)

递归创建多层目录,如果该目录已存在则抛出异常,注意:'E:\a\b’和’E:\a\c’并不会冲突)

remove(path)

删除文件

rmdir(path)

删除单层目录,如果该目录非空则抛出异常

removedirs(path)

递归删除目录,从子目录到父目录逐层尝试删除,遇到目录非空则抛出异常

rename(old,new)

将文件old重命名为new

system(command)

运行系统的shell命令

walk(top)

遍历top参数指定路径下的所有子目录,并将结果返回一个三元组(路径,[目录],[文件])

-

-

  • 测试:

4.os.path模块

  • os.path模块中关于路径常用的函数使用办法

函数名

使用方法

basename(path)

去掉目录路径,单独返回文件名

dirname(path)

去掉文件名,单独返回目录路径

join(path1[,path2[,…]])

将path1和path2各部分组合成一个路径名

split(path)

分割文件名和路径,返回(f_path, f_name)元组。如果完全使用目录,它也会将最后一个目录作为文件名分离,且不会判断文件或者目录是否存在

splitext(path)

分离文件名和扩展名,返回(f_name, f_extension)元组。

getsize(file)

返回指定文件的尺寸,单位是字节

getatime(file)

返回指定文件最近的访问时间(浮点型秒数,可用time模块的gmtime()或localtime()函数换算)

getctime(file)

返回指定文件的创建时间(浮点型秒数,可用time模块的gmtime()或localtime()函数换算)

getmtime(file)

返回指定文件最新的修改时间(浮点型秒数,可用time模块的gmtime()或localtime()函数换算)

-

-

  • 以下为函数返回True或False

函数名

使用方法

exists(path)

判断指定路径(目录或文件)是否存在

isabs(path)

判断指定路径是否为绝对路径

isdir(path)

判断指定路径是否存在且是一个目录

isfile(path)

判断指定路径是否存在且是一个文件

islink(path)

判断指定路径是否存在且是一个符号链接

ismount(path)

判断指定路径是否存在且是一个挂载点

samefile(path1,path2)

判断path1和path2两个路径是否指向同一个文件

-

-

  • 测试:

5.应用:使用shutil拷贝文件

使用shutil.copy拷贝文件时,若目标文件存在则存在shutile异常。所以可以结合os.path模块进行一层包装

  • 参考代码如下: 在这里,一个 ‘_number’在扩展名之前插入以在重复的情况下生成唯一的目标名称。点赞’foo_1.txt’ .
def safe_copy(file_path, out_dir, dst = None):
    """Safely copy a file to the specified directory. If a file with the same name already 
    exists, the copied file name is altered to preserve both.

    :param str file_path: Path to the file to copy.
    :param str out_dir: Directory to copy the file into.
    :param str dst: New name for the copied file. If None, use the name of the original
        file.
    """
    name = dst or os.path.basename(file_path)
    if not os.path.exists(os.path.join(out_dir, name)):
        shutil.copy(file_path, os.path.join(out_dir, name))
    else:
        base, extension = os.path.splitext(name)
        i = 1
        while os.path.exists(os.path.join(out_dir, '{}_{}{}'.format(base, i, extension))):
            i += 1
        shutil.copy(file_path, os.path.join(out_dir, '{}_{}{}'.format(base, i, extension)))