首页 > 编程语言 >python积累--读写文本文件实例

python积累--读写文本文件实例

时间:2023-08-08 23:35:30浏览次数:40  
标签:文件 读取 10 python -- read 文本文件 line open


读写文件是最常见的 IO 操作。我们经常从文件读取输入,将内容写到文件。

读文件

在 Python 中,读文件主要分为三个步骤:
打开文件
读取内容
关闭文件

一般使用形式如下:

try:
    f = open('/path/to/file', 'r')    # 打开文件
    data = f.read()                   # 读取文件内容
finally:
    if f:
        f.close()                     # 确保文件被关闭

注意到,我们在代码中加了 try…finally,这是因为,如果打开和读取文件时出现错误,文件就没有被关闭。为了确保在任何情况下,文件都能被关闭,我们加了 try…finally。

上面的代码中,‘r’ 模式表示读模式,open 函数的常用模式主要有:

‘r'	读模式
‘w'	写模式
‘a'	追加模式
‘b'	二进制模式(可添加到其他模式中使用)
‘+'	读/写模式(可添加到其他模式中使用)

上面的读文件做法很繁琐,我们可以使用 Python 的 with 语句来帮我们自动调用 close 方法:

with open('/path/to/file', 'r') as f:
    data = f.read()

可以看到,这种方式很简洁,而且还能在出现异常的情况下自动关闭文件。
强烈推荐。

通常而言,读取文件有以下几种方式:

一次性读取所有内容,使用 read() 或 readlines();
按字节读取,使用 read(size);
按行读取,使用 readline();

读取所有内容

读取所有内容可以使用 read() 或 readlines()。我们在上面已经介绍过 read() 了,现在,让我们看看 readlines()。

readlines() 方法会把文件读入一个字符串列表,在列表中每个字符串就是一行。

假设有一个文件 data.txt,它的文件内容如下(数字之间的间隔符是’\t’):

10  1   9   9
6   3   2   8
20  10  3   23
1   4   1   10
10  8   6   3
10  2   1   6

我们使用 readlines() 将文件读入一个字符串列表:

with open('data.txt', 'r') as f:
    lines = f.readlines()
    line_num = len(lines)
    print lines
    print line_num

执行结果:

['10\t1\t9\t9\n', '6\t3\t2\t8\n', '20\t10\t3\t23\n', '1\t4\t1\t10\n', '10\t8\t6\t3\n', '10\t2\t1\t6']
6

可以看到,列表中的每个元素都是一个字符串,刚好对应文件中的每一行。

按字节读取

如果文件较小,一次性读取所有内容确实比较方便。但是,如果文件很大,比如有 100G,那就不能一次性读取所有内容了。这时,我们构造一个固定长度的缓冲区,来不断读取文件内容。

看看例子:

with open('path/to/file', 'r') as f:
    while True:
        piece = f.read(1024)        # 每次读取 1024 个字节(即 1 KB)的内容
        if not piece:
            break
        print piece

在上面,我们使用 f.read(1024) 来每次读取 1024 个字节(1KB) 的文件内容,将其存到 piece,再对 piece 进行处理。

事实上,我们还可以结合 yield 来使用:

def read_in_chunks(file_object, chunk_size=1024):
    """Lazy function (generator) to read a file piece by piece.
    Default chunk size: 1k."""
    while True:
        data = file_object.read(chunk_size)
        if not data:
            break
        yield data

with open('path/to/file', 'r') as f:
    for piece in read_in_chunks(f):
        print piece

逐行读取

在某些情况下,我们希望逐行读取文件,这时可以使用 readline() 方法。

看看例子:

with open('data.txt', 'r') as f:
    while True:
        line = f.readline()     # 逐行读取
        if not line:
            break
        print line,             # 这里加了 ',' 是为了避免 print 自动换行

执行结果:

10  1   9   9
6   3   2   8
20  10  3   23
1   4   1   10
10  8   6   3
10  2   1   6

文件迭代器

在 Python 中,文件对象是可迭代的,这意味着我们可以直接在 for 循环中使用它们,而且是逐行迭代的,也就是说,效果和 readline() 是一样的,而且更简洁。

看看例子:

with open('data.txt', 'r') as f:
    for line in f:
        print line

在上面的代码中,f 就是一个文件迭代器,因此我们可以直接使用 for line in f,它是逐行迭代的。

看看执行结果:

10  1   9   9
6   3   2   8
20  10  3   23
1   4   1   10
10  8   6   3
10  2   1   6

再看一个例子:

with open(file_path, 'r') as f:
    lines = list(f)
    print lines

执行结果:

['10\t1\t9\t9\n', '6\t3\t2\t8\n', '20\t10\t3\t23\n', '1\t4\t1\t10\n', '10\t8\t6\t3\n', '10\t2\t1\t6']

可以看到,我们可以对文件迭代器执行和普通迭代器相同的操作,比如上面使用 list(open(filename)) 将 f 转为一个字符串列表,这样所达到的效果和使用 readlines 是一样的。

读取其他文件

二进制文件
前面讲的默认都是读取文本文件,并且是UTF-8编码的文本文件。要读取二进制文件,比如图片、视频等等,用’rb’模式打开文件即可:

>>> f = open('/Users/michael/test.jpg', 'rb')
>>> f.read()
b'\xff\xd8\xff\xe1\x00\x18Exif\x00\x00...' # 十六进制表示的字节

字符编码

要读取非UTF-8编码的文本文件,需要给open()函数传入encoding参数,例如,读取GBK编码的文件:

>>> f = open('/Users/michael/gbk.txt', 'r', encoding='gbk')
>>> f.read()

异常编码字符处理

遇到有些编码不规范的文件,你可能会遇到UnicodeDecodeError,因为在文本文件中可能夹杂了一些非法编码的字符。遇到这种情况,open()函数还接收一个errors参数,表示如果遇到编码错误后如何处理。最简单的方式是直接忽略:

>>> f = open('/Users/michael/gbk.txt', 'r', encoding='gbk', errors='ignore')

read()、readline() 和 readlines()对比

Python的文本文件的内容读取中,有三类方法:read()、readline()、readlines(),这三种方法各有利弊,下面逐一介绍其使用方法和利弊。

假设 sxl.txt文件内容如下:

i like the movie
i ate an egg

###read()方法

read()方法表示一次读取文件全部内容,该方法返回字符串。

f = open("sxl.txt")
lines = f.read()
print lines
print(type(lines))
f.close()

输出结果:

i like the movie
i ate an egg
<class 'str'>

read()是最简单的一种方法,一次性读取文件的所有内容放在一个大字符串中,即存在内存中。

read()的利端:
方便、简单
一次性独读出文件放在一个大字符串中,速度最快
read()的弊端:
文件过大的时候,占用内存会过大

readline()方法

该方法每次读出一行内容,所以,读取时占用内存小,比较适合大文件,该方法返回一个字符串对象。

f = open("sxl.txt")
line = f.readline()
while line:
    print (line)
    print(type(line))
    line = f.readline()
f.close()

输出结果:

i like the movie
<class 'str'>
i ate an egg
<class 'str'>

readline()逐行读取文本,结果是一个list。
readline()的利端:
占用内存小,逐行读取
readline()的弊端:
由于是逐行读取,速度比较慢

readlines()方法

readlines()方法读取整个文件所有行,保存在一个列表(list)变量中,每次读取一行,但读取大文件会比较占内存。

f = open("sxl.txt")
lines = f.readlines()
for line in lines:
    print (line)
    print(type(line))
f.close()

输出结果:

i like the movie
<class 'str'>
i ate an egg
<class 'str'>

readlines()一次性读取文本的所有内容,结果是一个list

这种方法读取的文本内容,每行文本末尾都会带一个’\n’换行符 (可以使用L.rstrip(’\n’)去掉换行符)

readlines()的利端:
一次性读取文本内容,速度比较快
readlines()的弊端:
随着文本的增大,占用内存会越来越多

最后还有一种方式,与第三种方法类似。

f = open("sxl.txt")
print (type(f))
for line in f:
    print (line)
    print(type(line))
f.close()

输出结果:

<class '_io.TextIOWrapper'>
i like the movie
<class 'str'>
i ate an egg
<class 'str'>

#写文件

写文件使用 write 方法,如下:

with open('/Users/ethan/data2.txt', 'w') as f:
    f.write('one\n')
    f.write('two')

如果上述文件已存在,则会清空原内容并覆盖掉;
如果上述路径是正确的(比如存在 /Users/ethan 的路径),但是文件不存在(data2.txt 不存在),则会新建一个文件,并写入上述内容;
如果上述路径是不正确的(比如将路径写成 /Users/eth ),这时会抛出 IOError;
如果我们想往已存在的文件追加内容,可以使用 ‘a’ 模式,如下:

with open('/Users/ethan/data2.txt', 'a') as f:
    f.write('three\n')
    f.write('four')

#小结
推荐使用 with 语句操作文件 IO。
如果文件较大,可以按字节读取或按行读取。
使用文件迭代器进行逐行迭代。

标签:文件,读取,10,python,--,read,文本文件,line,open
From: https://blog.51cto.com/u_16218512/7013752

相关文章

  • aws----文件存储efs的全面了解
    efs简介AmazonElasticFileSystem可扩展的、弹性原生云NFS文件系统,每月0.08USD/GBAmazonEFS是一项完全托管的服务,让您可以轻松地在Amazon云中设置和扩展文件存储,并对其进行成本优化。只需在AWS管理控制台中单击几次,您就可以创建文件系统,供AmazonEC2实例通过文件系统......
  • 单调栈
    LargestRectangleinaHistogram经典题单调栈:保持栈内元素单调递增因为如果递减后面的元素的高度就会替换前面的元素的高度前面元素等价于多个后面元素当有新元素加入是将原先的递增序列从后往前更新答案最后使得栈保持原有性质这样可以保证每个元素只会被考虑一次,不用......
  • k8s--kubernetes--argo----使用动态存储PVC---基于nfs 的storageclass
    PVC简介Docker中有volumes的概念,在Docker中,volume是对物理节点服务器node路径目录的一种映射,也就是我们可以把服务器的一个目录挂载给镜像使用。同样的,k8s创建的pod也可以挂载volume,而且不仅仅支持pod所在的服务器node的目录映射,也可以挂载其他网络存储的作为目录挂载。k8s支......
  • 红帽认证RedHat-RHCSA shell的基本应用用户和组管理网络配置和防火墙管理笔记汇总
    shell命令概述Shell作用:命令解释器介于操作系统内核与用户之间,负责解释命令行获得命令帮助内部命令help命令的“--help”选项使用man命令阅读手册页命令行编辑的几个辅助操作Tab键:自动补齐反斜杠“\”:强制换行快捷键Ctrl+U:清空至行首快捷键Ctrl+K:清空至行尾快捷键Ctr......
  • Kotlin中的Data Class
    DataClassKotlin中的DataClass主要用于封装和持有数据,作用类似Java中的POJO对象。dataclassUser(nickname:String,sex:Int,age:Int)在class之前加上data关键字即可声明一个DataClass。Kotlin中编译器会自动为DataClass实现equals()方法hashcode()方法toStr......
  • docker--k8s---终端terminal和普通程序以及jupyter notebook-创建永久的静态环境变量-
    终端terminal和普通程序linux系统的中主要有两种启用系统环境的情况,一种是用户登录,比如进入bash或者sh等命令行操作shell界面,一种是用户不登录,而是程序自动运行。根据两种情况,适用的创建永久的环境变量的方式就会有所不同。创建永久的静态环境变量静态环境变量是指内容不会变......
  • hadoop组件---spark实战-----airflow----调度工具airflow定时运行任务的理解
    我们在前面已经初步了解了airflow:hadoop组件—spark实战-----airflow----调度工具airflow的介绍和使用示例但是我们开始尝试使用airflow的定时任务的时候,常常遇到一个尴尬的情况,任务没有成功运行,或者说设置开始时间是今天,但是明天才开始运行。本篇文章尝试说明其中的......
  • k8s 学习笔记之配置存储——ConfigMap&Secret
    配置存储ConfigMapConfigMap是一种比较特殊的存储卷,它的主要作用是用来存储配置信息的。创建configmap.yaml,内容如下:apiVersion:v1kind:ConfigMapmetadata:name:configmapnamespace:devdata:info:|(这个|后面整个都是值)username:adminpassword:12......
  • hadoop组件---spark实战-----airflow----调度工具airflow部署到k8s中使用
    在之前的文章中我们已经了解了airflow和它的工作原理。hadoop组件—spark实战-----airflow----调度工具airflow的介绍和使用示例Scheduler进程,WebServer进程和Worker进程需要单独启动。Scheduler和WebServer可以跑在一个操作系统内,也可以分开,而通常Worker需要很多,如果是部署特定......
  • k8s---使用ingress配置域名转发时的traefik路径规则详解
    ingress中traefik的使用方式如下:apiVersion:extensions/v1beta1kind:Ingressmetadata:name:spark-client-testnamespace:defaultannotations:kubernetes.io/ingress.class:traefiktraefik.frontend.rule.type:PathPrefixspec:rules:-host:......