Python成为专业人士笔记–文件&文件夹的读取/写入

“专业人士笔记”系列目录:

创帆云:Python成为专业人士笔记--强烈建议收藏!每日持续更新!

文件操作介绍

在存储,读取或传输数据时,对操作系统的文件进行读写是经常涉及到的场景。与其他语言不同,Python大大简化了读取/写入和关闭文件的过程,最少2行代码就可完成上述所有操作;本文说明了Python如何与操作系统上的文件进行交互。

文件模式

可以使用mode参数指定的不同模式打开文件,这些包括 :

‘r’ – 只读模式。默认值。它只允许您读取文件,而不允许您修改它。当使用此模式时,文件必须存在。

‘w’ – 写入模式。 如果它不存在 ,将创建一个新文件,否则将覆盖文件,并允许您写入它。

‘a’ – 追加模式。它将把数据写到文件的末尾。它不会擦除文件,并且在这种模式下,文件必须已经存在。

‘rb’ – 二进制读模式。这类似于r,除了读取是在二进制模式下强制执行的。

‘r+’ – 读写模式。这允许您同时读写文件,而不必使用r和w ,但前提是文件必须已存在

‘rb+’ – 二进制读写模式。和r+一样,只是数据是二进制的

‘wb’ – 二进制写入模式。和w一样,只是数据是二进制的。

‘w+’ – 读写模式,功能与r+相同,但如果文件不存在,则创建一个新文件。否则,文件将被覆盖

‘wb+’ – 二进制模式下的读写模式。和w+一样,但是数据是二进制的。

‘ab’ – 以二进制模式附加。类似于a,只是数据是二进制的。

‘a+’ – 附加和读取模式。类似于w+,因为如果文件不存在,它将创建一个新文件 , 如果文件存在,则文件指针位于文件的末尾。

‘ab+’ – 二进制附加和读取模式。与a+相同,只是数据是二进制的。


Python 3添加了一个新的模式来进行独占创建,这样您就不会意外地截断或覆盖现有文件。

‘x’ – 以独占模式打开,如果文件已经存在,将引发FileExistsError

‘xb’ – 同x模式,只是数据是二进制

‘x+’ – 读写模式。类似于w+,因为如果文件不存在,它将创建一个新文件。否则
将产生 FileExistsError.

‘xb+’ – 和x+完全一样,数据是二进制的

符合python风格的文件操作代码结构:

        try:
    with open("fname", "r") as fout:
    # 这里写打开文件后的处理逻辑

except FileExistsError:
   # 文件异常处理代码

      

逐行读取文件

逐行遍历文件的最简单方法 :

        #创建测试文件(当前项目路径下)
with open('myfile.txt', 'w') as fp:
    fp.write('我\n爱\n你')

#逐行读取
with open('myfile.txt', 'r') as fp:

    for line in fp:
        print(line)

#输出:
 我
 爱
 你

      

readline()允许对逐行迭代进行更细粒度的控制。下面的例子等价于上面的例子 :

        #创建测试文件(当前项目路径下)
with open('myfile.txt', 'w') as fp:
    fp.write('我\n爱\n你')

#逐行读取
with open('myfile.txt', 'r') as fp:
    content='';
    while True:
        content=fp.readline();
        print(content)

        if(content==''):
            #如果读到空字符串,证明结束并返回
            break;
 #输出:
 我
 爱
 你 
      

但是,不建议将for循环迭代器和readline()一起使用

如何更精细的控制行读取,更常见的是,用readlines()函数存储文件行的可迭代集合 :

        #创建测试文件(当前项目路径下)
with open('myfile.txt', 'w') as fp:
    fp.write('我\n爱\n你')

#逐行读取
with open("myfile.txt", "r") as fp:
    lines = fp.readlines()

#查询
for i in range(len(lines)):
    print("Line " + str(i) + ": " + lines[i])


#输出:
 Line 0: 我
 Line 1: 爱
 Line 2: 你

      

遍历文件(递归)

要迭代所有文件,包括子目录中的文件,请使用os.walk :

        import os

for root, folders, files in os.walk('.'): #该路径为云环境上项目路径,可以替换成其它路径甚至根路径'/'

    # 获取所有文件夹
    for file in folders:
        print(root,file)

    #获取所有文件
    for filename in files:

        print(root, filename)

#输出:
 . aaa
 . hello.py
 . test.py
 . test2.py
 . test3233
 . main.py
 . shoppinglist.txt
 . myfile.txt
      

在python3中,如果你希望快速获取文件对象,您可以使用更有效的方法os.scandir,像这样:

        import os

for entry in os.scandir('.'):

    if not entry.name.startswith('.') and entry.is_file():

        print(entry)

#输出:
<DirEntry 'hello.py'>
<DirEntry 'test.py'>

#当然,可以直接用print(entry.name)输出它们的文件名
 
 
      

获取文件完整内容

文件I / O的首选方法是使用with关键字;这样可以确保一旦阅读或写作完成后,python能够帮你处理剩余的文件关闭、资源清理等工作

        #创建测试文件(当前项目路径下)
with open('myfile.txt', 'w') as fp:
    fp.write('我\n爱\n你')

#打开读取
with open('myfile.txt') as in_file:
    content = in_file.read()
print(content)

#输出:
 我
 爱
 你
      

或者,要手动关闭文件,您可以放弃使用并直接调用close :

        #创建测试文件(当前项目路径下)
with open('myfile.txt', 'w') as fp:
    fp.write('我\n爱\n你')

#读取
in_file = open('myfile.txt', 'r')
content = in_file.read()
print(content)
in_file.close()

      

写入文件

        with open('myfile.txt', 'w') as f:
 f.write("Line 1")
 f.write("Line 2")
 f.write("Line 3")
 f.write("Line 4")


      

如果在python云环境的项目根目录打开myfile.txt,你会看到它的内容是 :

        Line 1Line 2Line 3Line 4
      

注意不要使用os.linesep作为行结束符;写入时换行请使用\ n

如果要指定编码,只需将编码参数添加到open函数即可

        with open('my_file.txt', 'w', encoding='utf-8') as f:
    f.write('utf-8 text')
      

也可以使用print语句写入文件。在python2和python3中,机制是不同的,但是概念是相同的,你可以把本来会出现在屏幕上的输出结果发送到一个文件中 :

        with open('fred.txt', 'w') as outfile:
     s = "I'm Not Dead Yet!"
     print(s) # 输出到标准控制台
     print(s, file = outfile) # 写入到文件

      

检查文件或路径是否存在

用try/except异常捕获检查:

        import errno

path='/tes21323t'

try:

    with open(path,'r') as f:
        print('文件存在')

except IOError as e:
    print('文件或文件夹不存在')


      

在多线程条件下,如果另一个线程在检查和使用时删除了文件,上面的代码会避免这种情况;但这种情况在下面的代码中有可能会发生:

        import pathlib
path = pathlib.Path('/path/to/some/file.txt')
if path.is_file():
   #业务逻辑代码
      

要检查给定的路径是否存在,可以使用上面的Try,或者显式地检查路径 :

        import os
path = "/home/myFiles/directory1"
if os.path.exists(path):
   #做些什么
      

用 mmap进行文件灵活读取

使用mmap模块,用户可以将文件映射到内存中,从而随机访问文件中的位置。这是使用普通文件操作的另一种选择。

        import mmap
with open('filename.ext', 'r') as fd:
 #0:  映射整个文件 
 mm = mmap.mmap(fd.fileno(), 0)

 #在索引5到10处打印字符 
 print mm[5:10]

 # 从mm的当前位置开始打印行 
 print mm.readline()

 #在第5个索引写一个字符 
 mm[5] = 'a'

 #将mm的当前位置设置为文件的开头 
 mm.seek(0)

 #关闭 mmap 对象
 mm.close()
      

替换文件中的文本

        import fileinput
#定义要替换的字符串的字典,其实有两个处要替换
replacements = {'Search1': 'Replace1','Search2': 'Replace2'}

for line in fileinput.input('filename.txt', inplace=True):
    for search_for in replacements:
        replace_with = replacements[search_for]
        line = line.replace(search_for, replace_with)

 print(line, end='')
      

检查是否为空文件

        import os
#项目文件下的hello.py是否为空
path_to_file='./hello.py'
if os.stat(path_to_file).st_size == 0:
    print('这是空的')
else:
    print('这不是空的')

#或者:
import os
path_to_file='./hello.py'
if os.path.getsize(path_to_file) > 0:
    print('这是空的')
else:
    print('这不是空的')
      

但是,如果文件不存在,两者都会抛出异常。为了避免必须捕捉这样的错误,可以这样做 :

        import os
def is_empty_file(fpath): 
    return os.path.isfile(fpath) and os.path.getsize(fpath) > 0

# 它将返回一个bool值。 
      

多行读取文件

假设您只想在文件的某些特定行之间进行迭代,您可以使用itertools实现这一点 :

        import itertools

with open('myfile.txt','w') as file:
    file.write('第一行\n第二行\n第三行\n')

with open('myfile.txt', 'r') as f:
    for line in itertools.islice(f, 0, 2):
        #从第0行开始,读取2行
        print(line)

#输出:
 第一行
 第二行


      

复制文件夹

        import shutil
source='//192.168.1.2/Daily Reports'
destination='D:\Reports\Today'
shutil.copytree(source, destination)
      

注意:目标目录必须不存在

复制文件:

        #准备好两个文件:
with open(input_file, 'r') as in_file, open(output_file, 'w') as out_file:
     for line in in_file:
         out_file.write(line)

#和上面一样,使用shutil模块:
import shutil
shutil.copyfile(src, dst)
      

好了,今天的分享就到这里,禁止转载,违者必究

猜你喜欢

转载自blog.csdn.net/oSuiYing12/article/details/106211781