文章目录(Table of Contents)
打开关闭文件
我们使用open
函数打开文件夹,open
需要两个参数,第一个参数是文件路径或者文件名,第二个是文件打开的模式。模式有如下的选项:
- "r",以只读模式打开,你只能读取文件但不能编辑/删除文件的任何内容
- "w",以写入模式打开,如果文件存在将会删除里面的所有内容,然后打开这个文件进行写入
- "a",以追加模式代开,写入到文件中的任何数据将自动添加到末尾
- "b",以二进制的方式打开
- "w+", 上面所有的模式加一个加号(+), 此时若文件不存在, 则会自动新建一个文件夹.
默认为只读模式。
我们下面看一个例子:
- file = open('byr.py','r') #打开文件
- file.readlinereadline() #读取文件的一行
- >> #这里会输出文件第一行的内容
- file.close()#记得文件打开后要关闭
在实际情况中,我们会采取with
语句处理文件对象,他会在文件用完之后自动关闭。下面我们来看一个例子。
- with open('byr.py') as file:
- count=0
- for line in file:
- print(line) #每一行打印文件内容
- count = count+1
- print(count) #输出文件总行数
我们在上面这个程序中没有使用close
,但是程序在执行到with
代码块之外的时候,文件会被自动关闭。
读取文件内容
在上面其实已经讲到了一些关于文件内容读取的内容,即 readline
,这里在把文件内容读取讲得详细一点。
下面介绍三个常用的函数
read()
读取整个文件,要谨慎使用,可能文件过大readline
每次读取文件的一行readlines
读取文件的所有行,返回一个列表,列表中每个元素对应文本中的一行字符串
其实,在使用with
的时候,返回的file已经可以直接进行文件每一行的读取了.
- with open('byr.py') as file:
- print(file)
- print(list(file)) #可以显示每一行的内容
- for line in file:
- print(line) #这样就可以输入文件的每一行
读取文件并进行编码转化
有的时候我们是按照二进制的方式来读取的文件,可能需要进行转换。例如转换为十进制。我们来看一个例子,我们需要将 pcap 文件转换为十进制,之后可以当成图片来进行处理。
首先我们使用二进制的方式打开 pcap 文件,并进行读取。
- with open('./data/preprocess_data/test.pcap', 'rb') as f:
- content = f.read()
此时的 content 为二进制文件。content 打印出来如下所示:
接着我们将其转换为 16 进制。这里我们使用 binascii.hexlify 来进行转换,他的输出结果为,返回二进制数据 data 的十六进制表示形式。 data 的每个字节都被转换为相应的 2 位十六进制表示形式。
- import binascii
- hexst = binascii.hexlify(content)
因为每一个字节转换为相应的 2 位十六进制进行表示,所以我们转换为十进制的时候,就是 2 个 2 个来进行转换,如下所示:
- fh = np.array([int(hexst[i:i+2],16) for i in range(0, len(hexst), 2)])
最终转换的结果如下图所示:
写入文件
写入文件最常用的方法是write()
,下面看一个例子
- with open('byr.txt','w') as file:
- file.write('byr test')#这样默认是不换行的
- file.write('byr test \n') #这样就是换行的
- file.write('byr test')
上面这个程序我们使用w
模式打开,如果文件不存在就会新建,如果文件存在就会把原来的内容覆盖掉。
那么要是我们想要向文件里增加内容应该怎么办呢?我们可以使用a
追加模式打开文件:
- with open('byr.txt','a') as file:
- file.write('byr test')#这样默认是不换行的
- file.write('byr test \n') #这样就是换行的
- file.write('byr test \n')
打开的编码
有的时候, 我们需要写入中文, 这个时候需要指定打开文件的编码. 下面是一个简单的例子.
- with open(file='temp_config', mode='a', encoding="UTF-8") as file:
- 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[, ...]]) 把目录和文件名合成一个路径
- import os
- filename = '/home/wmn/byr.py'
- print(os.path.abspath(filename))#返回文件的绝对路径
- >> '/home/wmn/byr.py'
- print(os.path.basename(filename))#返回文件名
- >> 'byr.py'
- print(os.path.dirname(filename))#返回文件的路径
- >> '/home/wmn'
- print(os.path.isfile(filename))#判断是否是文件
- >> True
- print(os.path.isdir(filename))#判断是否是目录
- >> False
- print(os.path.exists(filename))#判断路径是否存在
- >> True
- print(os.path.join('/home/wmn','byr.txt'))#把目录和文件名合在一起
- >> '/home/wmn/byr.txt'
我们可以结合一下, 先判断文件夹是否存在, 如果文件夹不存在, 那么我们就创建文件夹, 具体的代码如下所示:
- os.makedirs(os.path.dirname(file_name), exist_ok=True) # 没有就创建文件夹
这个还是很常用的,更多的内容可以查看文档,也可以查看另一个介绍os模块的文章,Python入门教程[7]-常用模块。
删除文件与图像写入
有的时候, 我们会使用到文件的删除, 使用remove即可.
- os.remove(img_path) # 删除文件
对于图像的写入, 我们使用cv2.imwrite来进行写入.
- import cv2
- # jpg图像保存
- cv2.imwrite("D:\\cat2.jpg", img,[int(cv2.IMWRITE_JPEG_QUALITY), 5])
- # png图像控制压缩等级
- cv2.imwrite("./cat.png", img, [int(cv2.IMWRITE_PNG_COMPRESSION), 0])
- cv2.imwrite("./cat2.png", img, [int(cv2.IMWRITE_PNG_COMPRESSION), 9])
下面是一个完整的, 关于文件夹内图像处理的代码, 这段代码的主要作用是将图像保存为统一的大小.
- def image_preprocess(dir_path='./dogs_cats/cat/'):
- """图片预处理
- """
- i = 0
- for img in tqdm(os.listdir(dir_path)): # 调用 tqdm 可视化循环处理过程
- img_path = os.path.join(dir_path, img) # 图像的完整路径
- img_data = cv2.imread(img_path) # 使用 opencv读取图像
- img_data = cv2.resize(img_data, (64, 64)) # 图片处理成统一大小
- os.remove(img_path) # 删除原始图像
- cv2.imwrite(img_path, img_data)# 保存新的图像
- i = i + 1
- if i%5000 == 0:
- print('i:',i,'img_name:',img,image_label(img))
文件的填充和裁剪
有的时候会对文件进行填充和裁剪. 比如都裁剪为相同的大小. 这里就说明以下如何进行文件的裁剪和填充.
文件填充
- with open('my_file', 'ab') as f:
- f.write(bytes([0]*1000))
上面的代码时向文件中填充0, 填充1000bytes, 最终的效果如下所示.
文件裁剪
我们希望直接对文件进行末尾截断. 比如100bytes的文件, 我们只保留前50bytes的内容. 我们可以使用f.seek()来定位到文件的某个byte, 再使用f.truncate()来删除该比特后面的所有内容.
如我们生成一个101byte的文件, 文件内容如下.
我们希望保留前50bytes, 也就是到十六进制的31, 我们可以执行下面的操作.
- with open('my_file', 'ab') as f:
- f.seek(50)
- f.truncate()
这样就是保留前50bytes. 最终的结果如下图所示.
同时打开多个文件
我们可以使用with来打开多个文件,下面介绍两种写法:
方法一:
- with open('file1') as f1, open('file2') as f2, open('file3') as f3:
- for i in f1:
- j = f2.readlinereadline()
- k = f3.readlinereadline()
- print(i,j,k)
方法二:
- from contextlib import nested
- with nested(open('file1'), open('file2'), open('file3')) as (f1,f2,f3):
- for i in f1:
- j = f2.readlinereadline()
- k = f3.readlinereadline()
- print(i,j,k)
一次读取文件N行
有的时候我们会遇到文件比较大,不能一次性全部读取,需要N行读一次,下面介绍一下方法:
- with open(...) as f:
- while True:
- next_n_lines = list(islice(f, n))
- if not next_n_lines:
- break
- else:
- # process next_n_lines
一个详细的例子可以参考:Python多进程用法中的文件处理的例子。
文件内容修改
有的时候我们需要对源文件进行一些修改,可以使用如下的方式进行修改。
- def alter(file,old_str,new_str):
- """
- 替换文件中的字符串
- :param file:文件名
- :param old_str:就字符串
- :param new_str:新字符串
- :return:
- """
- file_data = ""
- with open(file, "r", encoding="utf-8") as f:
- for line in f:
- if old_str in line:
- line = line.replace(old_str,new_str)
- file_data += line
- with open(file,"w",encoding="utf-8") as f:
- f.write(file_data)
- alter("./20190301.csv", "\,", ",")
获取文件夹内所有文件
这一部分可以查看,Python入门教程[7]-常用模块中的os模块的使用。
更多入门教程链接
关于更多入门教程, 可以通过下面的链接查看.
- 微信公众号
- 关注微信公众号
- QQ群
- 我们的QQ群号
评论