Python入门教程[5]-文件处理

王 茂南 2018年3月3日06:32:58
评论
1 5477字阅读18分15秒
摘要这一篇文章会介绍在python中如何实现文件的打开,关闭,写入等操作,对于之后的应用是很有帮助的。

打开关闭文件

我们使用open函数打开文件夹,open需要两个参数,第一个参数是文件路径或者文件名,第二个是文件打开的模式。模式有如下的选项:

  • "r",以只读模式打开,你只能读取文件但不能编辑/删除文件的任何内容
  • "w",以写入模式打开,如果文件存在将会删除里面的所有内容,然后打开这个文件进行写入
  • "a",以追加模式代开,写入到文件中的任何数据将自动添加到末尾
  • "b",以二进制的方式打开
  • "w+", 上面所有的模式加一个加号(+), 此时若文件不存在, 则会自动新建一个文件夹.

默认为只读模式。

我们下面看一个例子:

  1. file = open('byr.py','r') #打开文件
  2. file.readlinereadline() #读取文件的一行
  3. >> #这里会输出文件第一行的内容
  4. file.close()#记得文件打开后要关闭

在实际情况中,我们会采取with语句处理文件对象,他会在文件用完之后自动关闭。下面我们来看一个例子。

  1. with open('byr.py') as file:
  2.     count=0
  3.     for line in file:
  4.         print(line) #每一行打印文件内容
  5.         count = count+1
  6.     print(count) #输出文件总行数

我们在上面这个程序中没有使用close,但是程序在执行到with代码块之外的时候,文件会被自动关闭。

读取文件内容

在上面其实已经讲到了一些关于文件内容读取的内容,即 readline,这里在把文件内容读取讲得详细一点。

下面介绍三个常用的函数

  • read() 读取整个文件,要谨慎使用,可能文件过大
  • readline 每次读取文件的一行
  • readlines 读取文件的所有行,返回一个列表,列表中每个元素对应文本中的一行字符串

其实,在使用with的时候,返回的file已经可以直接进行文件每一行的读取了.

  1. with open('byr.py') as file:
  2.     print(file)
  3.     print(list(file)) #可以显示每一行的内容
  4.     for line in file:
  5.         print(line) #这样就可以输入文件的每一行

读取文件并进行编码转化

有的时候我们是按照二进制的方式来读取的文件,可能需要进行转换。例如转换为十进制。我们来看一个例子,我们需要将 pcap 文件转换为十进制,之后可以当成图片来进行处理。

首先我们使用二进制的方式打开 pcap 文件,并进行读取。

  1. with open('./data/preprocess_data/test.pcap', 'rb') as f:
  2.         content = f.read()

此时的 content 为二进制文件。content 打印出来如下所示:

Python入门教程[5]-文件处理

接着我们将其转换为 16 进制。这里我们使用 binascii.hexlify 来进行转换,他的输出结果为,返回二进制数据 data 的十六进制表示形式。 data 的每个字节都被转换为相应的 2 位十六进制表示形式

  1. import binascii
  2. hexst = binascii.hexlify(content)
Python入门教程[5]-文件处理

因为每一个字节转换为相应的 2 位十六进制进行表示,所以我们转换为十进制的时候,就是 2 个 2 个来进行转换,如下所示:

  1. fh = np.array([int(hexst[i:i+2],16) for i in range(0, len(hexst), 2)])

最终转换的结果如下图所示:

Python入门教程[5]-文件处理

写入文件

写入文件最常用的方法是write(),下面看一个例子

  1. with open('byr.txt','w') as file:
  2.     file.write('byr test')#这样默认是不换行的
  3.     file.write('byr test \n') #这样就是换行的
  4.     file.write('byr test')

上面这个程序我们使用w模式打开,如果文件不存在就会新建,如果文件存在就会把原来的内容覆盖掉。

那么要是我们想要向文件里增加内容应该怎么办呢?我们可以使用a追加模式打开文件:

  1. with open('byr.txt','a') as file:
  2.     file.write('byr test')#这样默认是不换行的
  3.     file.write('byr test \n') #这样就是换行的
  4.     file.write('byr test \n')

打开的编码

有的时候, 我们需要写入中文, 这个时候需要指定打开文件的编码. 下面是一个简单的例子.

  1. with open(file='temp_config', mode='a', encoding="UTF-8") as file:
  2.     file.write('你好!')

 

os.path文件与文件夹操作

下面介绍os.p这个常用的标准库,这个库主要是用于处理文件和文件夹,下面举一些常用的用法.

  • os.path.abspath(path) 返回文件的绝对路径
  • os.path.basename(path) 返回文件名
  • os.path.dirname(path) 返回文件路径
  • os.path.isfile(path) 判断路径是否为文件
  • os.path.isdir(path) 判断路径是否为目录
  • os.path.exists(path) 判断路径是否存在
  • os.path.join(path1[, path2[, ...]]) 把目录和文件名合成一个路径
  1. import os
  2. filename = '/home/wmn/byr.py'
  3. print(os.path.abspath(filename))#返回文件的绝对路径
  4. >> '/home/wmn/byr.py'
  5. print(os.path.basename(filename))#返回文件名
  6. >> 'byr.py'
  7. print(os.path.dirname(filename))#返回文件的路径
  8. >> '/home/wmn'
  9. print(os.path.isfile(filename))#判断是否是文件
  10. >> True
  11. print(os.path.isdir(filename))#判断是否是目录
  12. >> False
  13. print(os.path.exists(filename))#判断路径是否存在
  14. >> True
  15. print(os.path.join('/home/wmn','byr.txt'))#把目录和文件名合在一起
  16. >> '/home/wmn/byr.txt'

我们可以结合一下, 先判断文件夹是否存在, 如果文件夹不存在, 那么我们就创建文件夹, 具体的代码如下所示:

  1. os.makedirs(os.path.dirname(file_name), exist_ok=True# 没有就创建文件夹

这个还是很常用的,更多的内容可以查看文档,也可以查看另一个介绍os模块的文章,Python入门教程[7]-常用模块

 

删除文件与图像写入

有的时候, 我们会使用到文件的删除, 使用remove即可.

  1. os.remove(img_path) # 删除文件

对于图像的写入, 我们使用cv2.imwrite来进行写入.

  1. import cv2
  2. # jpg图像保存
  3. cv2.imwrite("D:\\cat2.jpg", img,[int(cv2.IMWRITE_JPEG_QUALITY), 5])
  4. # png图像控制压缩等级
  5. cv2.imwrite("./cat.png", img, [int(cv2.IMWRITE_PNG_COMPRESSION), 0])
  6. cv2.imwrite("./cat2.png", img, [int(cv2.IMWRITE_PNG_COMPRESSION), 9])

下面是一个完整的, 关于文件夹内图像处理的代码, 这段代码的主要作用是将图像保存为统一的大小.

  1. def image_preprocess(dir_path='./dogs_cats/cat/'):
  2.     """图片预处理
  3.     """
  4.     i = 0
  5.     for img in tqdm(os.listdir(dir_path)): # 调用 tqdm 可视化循环处理过程
  6.         img_path = os.path.join(dir_path, img) # 图像的完整路径
  7.         img_data = cv2.imread(img_path) # 使用 opencv读取图像
  8.         img_data = cv2.resize(img_data, (64, 64)) # 图片处理成统一大小
  9.         os.remove(img_path) # 删除原始图像
  10.         cv2.imwrite(img_path, img_data)# 保存新的图像
  11.         i = i + 1
  12.         if i%5000 == 0:
  13.             print('i:',i,'img_name:',img,image_label(img))

 

文件的填充和裁剪

有的时候会对文件进行填充和裁剪. 比如都裁剪为相同的大小. 这里就说明以下如何进行文件的裁剪和填充.

文件填充

  1. with open('my_file', 'ab') as f:
  2.     f.write(bytes([0]*1000))

上面的代码时向文件中填充0, 填充1000bytes, 最终的效果如下所示.

Python入门教程[5]-文件处理

文件裁剪

我们希望直接对文件进行末尾截断. 比如100bytes的文件, 我们只保留前50bytes的内容. 我们可以使用f.seek()来定位到文件的某个byte, 再使用f.truncate()来删除该比特后面的所有内容.

如我们生成一个101byte的文件, 文件内容如下.

Python入门教程[5]-文件处理

我们希望保留前50bytes, 也就是到十六进制的31, 我们可以执行下面的操作.

  1. with open('my_file', 'ab') as f:
  2.     f.seek(50)
  3.     f.truncate()

这样就是保留前50bytes. 最终的结果如下图所示.

Python入门教程[5]-文件处理

 

同时打开多个文件

我们可以使用with来打开多个文件,下面介绍两种写法:

方法一:

  1. with open('file1') as f1, open('file2') as f2, open('file3') as f3:
  2.     for i in f1:
  3.         j = f2.readlinereadline()
  4.         k = f3.readlinereadline()
  5.         print(i,j,k)

 方法二:

  1. from contextlib import nested
  2. with nested(open('file1'), open('file2'), open('file3')) as (f1,f2,f3):
  3.     for i in f1:
  4.         j = f2.readlinereadline()
  5.         k = f3.readlinereadline()
  6.         print(i,j,k)

一次读取文件N行

有的时候我们会遇到文件比较大,不能一次性全部读取,需要N行读一次,下面介绍一下方法:

  1. with open(...) as f:
  2.     while True:
  3.         next_n_lines = list(islice(f, n))
  4.         if not next_n_lines:
  5.             break
  6.         else:
  7.             # process next_n_lines

一个详细的例子可以参考:Python多进程用法中的文件处理的例子。

文件内容修改

有的时候我们需要对源文件进行一些修改,可以使用如下的方式进行修改。

  1. def alter(file,old_str,new_str):
  2.     """
  3.     替换文件中的字符串
  4.     :param file:文件名
  5.     :param old_str:就字符串
  6.     :param new_str:新字符串
  7.     :return:
  8.     """
  9.     file_data = ""
  10.     with open(file, "r", encoding="utf-8") as f:
  11.         for line in f:
  12.             if old_str in line:
  13.                 line = line.replace(old_str,new_str)
  14.             file_data += line
  15.     with open(file,"w",encoding="utf-8") as f:
  16.         f.write(file_data)
  17. alter("./20190301.csv", "\,", ",")

获取文件夹内所有文件

这一部分可以查看,Python入门教程[7]-常用模块中的os模块的使用。

 

更多入门教程链接

关于更多入门教程, 可以通过下面的链接查看.

  • 微信公众号
  • 关注微信公众号
  • weinxin
  • QQ群
  • 我们的QQ群号
  • weinxin
王 茂南
  • 本文由 发表于 2018年3月3日06:32:58
  • 转载请务必保留本文链接:https://mathpretty.com/8954.html
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: