第七章 文件读写(OS&IO操作)

2021-08-23  本文已影响0人  帅气的Lucky

IO操作

一、读

1、读文件

2、读文件完整过程

try:
    fp = open("file.txt", "r")
    print(fp.read())
finally:
    if fp:
        fp.close()

3、读文件简写方式

with open("file.txt", "r") as fp:
    print(fp.read())

二、写

1、写文件

2、写文件完整过程

try:
    fp = open("file.txt", "w")
    fp.write("cool man")
finally:
    if fp:
        fp.close()

3、文件关闭

你可以反复调用write()来写入文件,但是务必要调用f.close()来关闭文件。当我们写文件时,操作系统往往不会立刻把数据写入磁盘,而是放到内存缓存起来,空闲的时候再慢慢写入。只有调用close()方法时,操作系统才保证把没有写入的数据全部写入磁盘。忘记调用close()的后果是数据可能只写了一部分到磁盘,剩下的丢失了。所以,还是用with语句来得保险

不使用with的情况

file = open("test.txt","r")
for line in file.readlines():
    print(line)
file.close()

这样直接打开文件,如果出现异常,如读取过程中文件不存在或异常,则直接出现错误,close方法无法执行,文件无法关闭

使用with的情况

file= open("test.txt","r")
try:
    for line in file.readlines():
        print line
except:
    print "error"
finally:
    file.close()

with语句作用效果相当于上面的try-except-finally

4、写文件简写方式

with open("file.txt", "w") as fp:
    fp.write("cool man")

三、编码与解码

Unicode:统一码,也叫万国码、单一码(Unicode)是计算机科学领域里的一项业界标准,包括字符集、编码方案等。Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。

如果把各种文字编码形容为各地的方言,那么Unicode就是世界各国合作开发的一种语言。

UTF-8是针对Unicode的一种可变长度字符编码;它可以用来表示Unicode标准中的任何字符,而且其编码中的第一个字节仍与ASCII相容,使得原来处理ASCII字符的软件无须或只进行少部份修改后,便可继续使用。因此,它逐渐成为电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。

1、编码

with open("file.txt", "wb") as fp:
    s = "lucky is a good man"
    s = s.encode("utf-8")
    fp.write(s)

2、解码

with open("file.txt", "rb") as fp:
    s = fp.read()
    s = s.decode("utf-8")
    print(s)

编码与解码 :使用什么编码 就使用什么解码

3、案例

4、chardet模块

四、pickle 序列化的操作

使用说明:可以将序列 序列化到 文件里 也就是 可以做到 原样写入 原样拿出 以二进制写进文件里 并以二进制的形式读取到内存里

1、list、tuple、dict、set的文件操作

2、StringIO

注意:文件使用后关闭文件

3、BytesIO

4、二进制文件

原因大概有三个:

第一是[二进制文件]比较节约空间,这两者储存[字符型数据]时并没有差别。但是在储存数字,特别是实型数字时,二进制更节省空间,比如储存 Real*4 的数据:3.1415927,文本文件需要 9 个字节,分别储存:3 . 1 4 1 5 9 2 7 这 9 个 ASCII 值,而[二进制文件]只需要 4 个字节(DB 0F 49 40)

第二个原因是,内存中参加计算的数据都是用二进制无格式储存起来的,因此,使用二进制储存到文件就更快捷。如果储存为文本文件,则需要一个转换的过程。在数据量很大的时候,两者就会有明显的速度差别了。

第三,就是一些比较精确的数据,使用二进制储存不会造成有效位的丢失。

五、os模块

1、os中常用属性和方法

作用:包含了基本的操作系统功能,提供了非常丰富的方法用来处理文件和目录

2、os.path中常用方法

操作文件和目的函数一部分在os模块中,还有一部分在os.path中

名称 说明
abspath 返回指定路径的绝对路径
join 拼接路径(不论是否存在)
split 拆分路径(不论是否存在)
splitdrive 以路径第一个'/'为分隔,分隔驱动器名与路径
splitext 获取文件的扩展名(不论是否存在)
basename 获取目录或文件名(不论是否存在)
getsize 获取属性
getctime 获取属性
isdir 判断是否是目录
isfile 判断是否是文件
exists 判断目录和文件是否存在
isabs 判断是否是绝对路径(不论是否存在)
import os

# 返回指定路径的绝对路径
print(os.path.abspath("."))

# 拼接路径(不论是否存在)
print(os.path.join(r"C:\Users\sunck\Desktop\file", "a.txt"))

# 拆分路径(不论是否存在)
print(os.path.split(r"C:\Users\sunck\Desktop\file"))
print(os.path.split(r"C:\Users\sunck\Desktop\file\sunck.txt"))
# 以路径第一个'/'为分隔,分隔驱动器名与路径
print(os.path.splitdrive(r"C:\Users\sunck\Desktop\file"))
print(os.path.splitdrive(r"C:\Users\sunck\Desktop\file\sunck.txt"))
# 获取文件的扩展名(不论是否存在)
print(os.path.splitext(r"C:\Users\sunck\Desktop\file"))
print(os.path.splitext(r"C:\Users\sunck\Desktop\file\sunck.txt"))

# 获取目录名(不论是否存在)
print(os.path.basename(r"C:\Users\sunck\Desktop\file"))
# 获取文件名(不论是否存在)
print(os.path.basename(r"C:\Users\sunck\Desktop\file\sunck.txt"))

# 获取属性
print(os.path.getsize(r"C:\Users\sunck\Desktop\code\test.py"))
print(os.path.getctime(r"C:\Users\sunck\Desktop\code\test.py"))

# 判断是否是目录
print(os.path.isdir(r"C:\Users\sunck\Desktop\code"))
print(os.path.isdir(r"C:\Users\sunck\Desktop\file"))
print(os.path.isdir(r"C:\Users\sunck\Desktop\code\test.py"))

# 判断是否是文件
print(os.path.isfile(r"C:\Users\sunck\Desktop\code\test.py"))
print(os.path.isfile(r"C:\Users\sunck\Desktop\code\1.txt"))
print(os.path.isfile(r"C:\Users\sunck\Desktop\code"))

# 判断目录和文件是否存在
print(os.path.exists(r"C:\Users\sunck\Desktop\code\test.py"))
print(os.path.exists(r"C:\Users\sunck\Desktop\code\2.py"))
print(os.path.exists(r"C:\Users\sunck\Desktop\code"))
print(os.path.exists(r"C:\Users\sunck\Desktop\file"))

# 判断是否是绝对路径(不论是否存在)
print(os.path.isabs(r"C:\Users\sunck\Desktop\code"))
print(os.path.isabs(r"C:\Users\sunck\Desktop\file"))
print(os.path.isabs(r".\code"))

python删除一个非空文件夹

import shutil
shutil.rmtree('c:\\test')

六、目录遍历

1、递归遍历目录

# 返回所有文件的绝对路径
def traverseDir(dirPath):
    absPathList = []
    import os

    filesList = os.listdir(dirPath)
    for fileName in filesList:
        absPath = os.path.join(dirPath, fileName)
        if os.path.isdir(absPath):
            # 目录
            absPathList += traverseDir(absPath)
        else:
            # 文件
            # print(absPath)
            absPathList.append(absPath)
    return absPathList

absPathList = traverseDir(r"C:\Users\lucky\Desktop\file")
print(absPathList)
print(len(absPathList))
# for absPath in absPathList:
#     print(absPath)

2、递归遍历 统计大小

import os
# 递归 输出 所有的文件名
path = r'C:\Users\xlg\Desktop\python安装文件'
def myfile(path):
    sum = 0 # 文件大小初始化 为 0
    myfilelist = os.listdir(path) #返回当前文件夹下的所有的文件 和 目录
    for i in myfilelist: #遍历
        newpath = os.path.join(path,i) #将文件和路径拼凑在一起 形成一个新的完整的文件路径
        if os.path.isdir(newpath): #判断是否是 目录
            sum += myfile(newpath)  #如果是目录 就进去 继续统计
        if os.path.isfile(newpath):  #如果是文件 直接统计大小
            sum += os.path.getsize(newpath) #累加文件的大小
    return sum
print(myfile(path))

3、检索指定路径下后缀是 py 的所有文件

获取文件后缀

def getfile_fix(filename):
     return filename[filename.rfind('.')+1:]
print(getfile_fix('lucky.txt'))


方法二
filename[-3:].upper()=='.PY'
方法三
#myList = x.split('.')
#print(myList[len(myList)-1])

完整示例

import os
import os.path

#path = 'D:/UC/'
ls = []

def getAppointFile(path,ls):
    fileList = os.listdir(path)
    try:
        for tmp in fileList:
            pathTmp = os.path.join(path,tmp)
            if os.path.isdir(pathTmp):
                getAppointFile(pathTmp,ls)
            elif pathTmp[pathTmp.rfind('.')+1:].upper()=='PY':
                #相等filename[-3:].upper()=='.PY':   #不是目录,则比较后缀名
                #myList = x.split('.')
                #print(myList[len(myList)-1])
                ls.append(pathTmp)
    except PermissionError:
        pass

def main():

    while True:
        path = input('请输入路径:').strip()
        if os.path.isdir(path) == True:
            break

    getAppointFile(path,ls)
    #print(len(ls))
    print(ls)
    print(len(ls))

main()

进阶操作

import os
import time

def getSuffix(path,suffixList,searchSuffix):
    fileList = os.listdir(path)
    for file in fileList:
        #拼接新的路径
        newPath = os.path.join(path,file)
        #判断是否是目录 是的话递归
        if os.path.isdir(newPath):
            getSuffix(newPath,suffixList,searchSuffix)
            #判断是否是py后缀的文件
        # elif newPath[newPath.rfind('.')+1:].upper() == "PY":
        elif newPath[newPath.rfind('.')+1:].upper() == searchSuffix.upper():
            suffixList.append(file)
def suffixShow(path,searchSuffix='py'):
    myList = []
    #path 当前查找数据的目录
    #myList 存储后缀数据的名字
    getSuffix(path,myList,searchSuffix)
    # print(myList)
    #判断是否有数据
    length = len(myList)
    #有数据进行显示
    if length:
        print("你所查找py后缀文件在{}目录下的个数为{} 这些文件都为...".format(path,length))
        time.sleep(2)
        for file in myList:
            print(file)
    else:
        print("在当前目录下 没有找到你要寻找后缀的文件")

while True:
    searchDir = input("请输入你要查找的目录")
    searchSuffix = input("请输入你要查找的后缀 不输入默认为py")
    #判断目录是否存在
    if os.path.exists(searchDir):
        if searchSuffix:
            suffixShow(searchDir,searchSuffix)
        else:
            suffixShow(searchDir)
    else:
        print(searchDir,"不存在 请重新输入")
        time.sleep(2)

4、递归删除 文件

path = './a'
import os

def d(path):
    List = os.listdir(path)
    for i in List:
        newPath = os.path.join(path,i)
        if os.path.isdir(newPath):
            d(newPath)
        if os.path.isfile(newPath):
            os.remove(newPath)
    os.rmdir(path)
d(path)

七、栈与队列

1、栈结构

2、队列结构

内存.png
栈区:由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈

堆区:一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表

全局区(静态区):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域,程序结束后由系统释放

文字常量区:常量字符串就是放在这里的,程序结束后由系统释放

程序代码区:存放函数体的二进制代码
堆栈效率-8665703.png
  stack:相对较高

  heap:相对较低
上一篇下一篇

猜你喜欢

热点阅读