zoukankan      html  css  js  c++  java
  • 文件操作

    Date: 2019-05-28

    Author: Sun

    文件的处理包括读文件和写文件,读写文件就是请求操作系统打开一个文件对象,然后,通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个文件对象(写文件)

    1 文件读取

    文件读取可分为以下步骤:

    • 打开文件
    • 读取文件内容
    • 关闭文件

    打开文件要使用open内建函数:

    open(file [, mode='r', encoding=None, errors=None])

    参数说明:

    ​ file:文件路径,可以是相对路径和绝对路径

    ​ mode:文件打开模式

    	  encodeing: 文件编码方式,不用于二进制文件,一般是utf-8,gbk
    

    ​ errors:指定如何处理编码和解码错误 ,适用于文本文件

    返回值:一个可迭代的文件对象

    mode 解释
    r 只读
    w 写之前会清空文件的内容
    a 追加的方式,在原本内容中继续写
    r+ 可读可写
    w+ 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
    a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
    b rb、wb、ab、rb+、wb+、ab+意义和上面一样,用于二进制文件操作

    注意:二进制文件一般用于视频、音频、图片

    读取文件常用函数:

    函数 解释
    read([size]) 读取文件(读取size字节,默认读取全部)
    readline([size]) 读取一行,如果指定size,将读入指定的字符数
    readlines() 把文件内容按行全部读入,返回一个包含所有行的列表
     #打开文件
    fp = open('qfile.txt','r',encoding='utf-8')
    
    #读取文件全部内容
    #content = fp.read()  
    #print(content)
    
    #读取指定字符数,包括行尾的换行符\n
    # print(fp.read(20))
    
    #读取一行
    # print(fp.readline(5))  #读取指定字符数
    # print(fp.readline())  #读取一整行,直到碰到一个\n
    
    #读取所有行,返回列表
    # print(fp.readlines())  
    
     #关闭文件
    fp.close() 
    
    #由于文件读写时都有可能产生IOError,一旦出错,后面的f.close()就不会调用。
    # 所以,为了保证无论是否出错都能正确地关闭文件,我们可以使用try ... finally来实现:
    # try:
    #     fp = open('qfile.txt','r',encoding='utf-8')
    #     print(fp.readlines())
    # finally:
    #     fp.close()
    #可以简写为:
    #with语句会自动调用close方法关闭文件
    with open('qfile.txt','r',encoding='utf-8')  as fp:
        print(fp.readline())
    
    #fread()和freadlines()会一次读入文件全部内容,如果文件太大,会直接耗尽内存的,因为文件对象可迭代,所以可以用for循环遍历文件读取
    with open('qfile.txt','r',encoding='utf-8')  as fp:
        for line in fp:
            print(line.strip())   #注意无论是read、readline、readlines都会读入行末的\n,所以需要手动剔除\n
    

    读取大文件

    比如给你一个10G大文件,如何读取?

    python文件对象提供了三个“读”方法: .read().readline().readlines()

    .read() 每次读取整个文件,它通常用于将文件内容放到一个字符串变量中。然而.read() 生成文件内容最直接的字符串表示,但对于连续的面向行的处理,它却是不必要的,并且如果文件大于可用内存,则不可能实现这种处理。

    处理大文件是很容易想到的就是将大文件分割成若干小文件处理,处理完每个小文件后释放该部分内存。这里用了iter 和 yield(关于yield和iter是属于生成器的,后续章节会讲到)

    # -*- coding: utf-8 -*-
    __author__ = 'sun'
    __date__ = '2019/5/28 18:26'
    
    
    def read_in_chunks(filePath, chunk_size=1024*1024):
        """
        Lazy function (generator) to read a file piece by piece.
        Default chunk size: 1M
        You can set your own chunk size
        """
        file_object = open(filePath)
        while True:
            chunk_data = file_object.read(chunk_size)
            if not chunk_data:
                break
            yield chunk_data
    
    def process(chunk):
        '''
        do some data with chunk.
        :param chunk:
        :return:
        '''
        pass
    
    if __name__ == "__main__":
        filePath = './path/filename'
        for chunk in read_in_chunks(filePath):
            process(chunk)
    

    关于读取大文件,经常在面试过程中被问到,其实采用map-reduce原理来解决此类问题是最佳方案。

    将大块文件数据分块读取,然后分发到不同的线程或者进程中处理,也就是map思想,采用分而治之的思想处理每块数据,然后进行reduce结果合并最终结果数据。

    2 写文件

    path = "file11.txt"
    
    #IO流
    
    #1.打开文件
    f = open(path,"w",encoding="utf-8")
    
    #2.写入内容,将内容写入到缓冲区
    #不会自动换行,需要换行的话,需要在字符串末尾添加换行符
    f.write("Whatever is worth doing is worth doing well该行很骄傲很关键\n")
    
    #3.刷新缓冲区【加速数据的流动,保证缓冲区的流畅】
    f.flush()
    
    #4.关闭文件  关闭文件也会刷新缓冲区
    f.close()
    
    #简写方式:可以不用手动调用close
    with open(path,"w",encoding="utf-8") as f1:
        f.write("Whatever is worth doing is worth doing well该行很骄傲很关键")
    

    3 移动文件指针

    文件是顺序向后读写的,如果想要移动文件指针,可以使用seek方法:

    file_obj.seek(offset,whence=0)

    功能:移动文件指针

    参数:offset 是偏移量,正数表示从文件开头向文件末尾移动,负数相反。

    ​ whence : 文件指针的位置,可选参数,值可以是

    ​ SEEK_SET or 0 表示文件开头位置,是默认值

    ​ SEEK_CUR or 1 表示当前位置

    ​ SEEK_END or 2 文件末尾位置

    返回值:新的位置

    #1.txt内容:hello world
    with open('1.txt','r',encoding='utf-8') as fp:
        fp.seek(5)  #移动到hello后的空格位置
        print(fp.read(3))  #wo
        fp.seek(0)   #移动到开头
        print(fp.read(5))  #hello
        print(fp.tell())   #tell()显示当前指针位置
    

    4. 编码和解码

    字符串类型和字节类型转换过程

    ​ 字符串类型转换为字节类型:编码,encode

    ​ 字节类型转换为字符串类型:解码,decode

    str = "今天是个好日子 today is a good day"
    path = "file22.txt"
    
    with open(path,"wb") as f:
        result = str.encode("utf-8")
        print(result)
        f.write(result)
    
    with open(path,"rb") as f1:
        data = f1.read()
        print(data)
        print(type(data))
    
        newData = data.decode("utf-8")
        print(newData)
        print(type(newData))
    

    5. os模块

    需要引入os模块

    函数名 函数值
    os.name 获取当前的操作系统的类型nt->windows posix->unix 后者Linux
    os.environ[ɪn'vaɪərən] 获取操作系统中的环境变量
    os.environ.get("path")[ɪn'vaɪərən] 获取path的环境变量
    os.curdir 获取当前的目录
    os.getcwd() 获取当前的工作目录
    os.listdir() 以列表的形式 返回当前目录的文件
    os.mkdir() 创建目录
    os.rmdir() 删除目录
    os.rename(old,new) 修改文件后者文件夹的名字
    os.remove() 删除文件
    os.system(command) 执行系统命令
    os.path.join(path1,path2) 将path1和path2拼接成一个正常的路径
    os.path.splitext() 获取文件扩展名
    os.path.isdir() 判断是否是目录
    os.path.isfile() 判断是否是文件
    os.path.exists() 判断文件或者目录是否存在
    os.path.getsize() 获取文件的大小(字节)
    os.path.dirname() 获取路径的目录名
    os.path.basename() 获取路径的文件名
    os.path.abspath() 返回文件的绝对路径
    os.path.split() 拆分路径
  • 相关阅读:
    Hierarchy Query (Connect by) and ORA600 ([kkqcbydrv:1])
    The Steps to Create a New Oracle Database
    Change Schema Name (II)
    [转]The differences between V$UNDOSTAT and V$ROLLSTAT
    【Oracle Mgmt】Oracle Character Semantics (NLS_LENGTH_SEMANTICS) and etc...
    [Oracle Mgmt]About Oracle Password File
    Show parameter & Table Not exists
    RMAN Recovery Window and Redundancy Concept
    [PLSQL]Are you sure it will be definitely random? (DBMS_RANDOM.SEED)
    IOT, Secondary Index and Mapping Table
  • 原文地址:https://www.cnblogs.com/sunBinary/p/10940902.html
Copyright © 2011-2022 走看看