简介

在实际开发中我们需要对文件做一些操作,例如读写文件、在文件中新添内容等,通常情况下,我们会使用open函数进行相关文件的操作,下面将介绍一下关于open读写的相关内容。

open()方法

open方法打开文件并返回一个文件对象,之后对文件的处理均需要基于返回的文件对象,如果文件不存在或者无法打开,则抛出OSError,详细方法如下:

open(file, mode='r', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

常用参数

file: 需要打开的文件或者文件描述符,通常直接时文件即可

mode:对于文件需要操作的模式,常用的如下:

字符 含意
'r' 读取(默认)
'w' 写入,并先截断文件
'x' 排它性创建,如果文件已存在则失败
'a' 打开文件用于写入,如果文件存在则在末尾追加
'b' 二进制模式
't' 文本模式(默认)
'+' 打开用于更新(读取与写入)

encoding:操作文件时的编码,如果所读文件中包含中文,最好设置为utf-8格式,否则中文读出来会是乱码;如果是读取文件的原生字节的格式,则不能设置encoding。

不常用参数

buffering:是否采用行缓冲,0:不采用(适用于二进制模式),默认为1

默认的缓冲策略

* 二进制文件以固定大小的块进行缓冲;使用启发式方法选择缓冲区的大小,尝试确定底层设备的“块大小”或使用 io.DEFAULT_BUFFER_SIZE。在许多系统上,缓冲区的长度通常为4096或8192字节。
* “交互式”文本文件( isatty() 返回 True 的文件)使用行缓冲。其他文本文件使用上述策略用于二进制文件。

errors:可选字符串参数,用于指定如何处理编码和解码错误 - 这不能在二进制模式下使用。

newline:控制 universal newlines 模式如何生效(它仅适用于文本模式)。它可以是 None,'','\n','\r' 和 '\r\n,主要在读取流或者写入流时做处理,具体如下:

读取流时:如果newlines为None,则启用通用的换行模式,也可以使用其他可选参数
写入流时: 如果newlines为None,则会默认将\n转换为系统分隔符(os.linesep),如果不为None,则使用给定字符串

closefd:关闭文件描述符(只在file为文件描述符的情况下生效,否则会报错),默认为True,关闭文件描述符,当为False时,文件描述符在操作时会出现,文件关闭后,对应的文件描述符不会关闭。

opener:自定义开启器,注意必须要返回一个文件描述符,正常默认为None即可,详单与os.open() as opener

返回的文件对象的操作

open方法返回了一个文件对象,其实就是IO对象,我们需要知道IO对象中部分方法或者函数。

读取内容

  • read(size): 读取内容,按照size的大小读取内容,可能会出现裁切的情况,当文件足够大时,size的大小决定了程序占用内存的大小,建议不要太大。
  • readable():是否可以读取流,可以则返回True,反之为False,当为False时则无法读取文件流内容。
  • readline(size=- 1):一行一行读取,可以设置size大小,代表最多读取的大小,主要是对于一些异常情况,例如一行有比较长的字符的时候
  • readlines(hint=- 1):读取整个文件的内容并安装换行符进行输出,返回一个列表,hint可以指定读取的行数。官方建议,如果可以使用 for line in file,就不需要使用for line in file.readlines()

写入内容

  • writable():是否可以写入流,可以则返回True,反之为False,当为False时无法写入文件。
  • writelines(lines): 写入多行数据,传入的是序列,默认会在每一个序列中的元素后添加换行
  • write(line: str):写入单行数据,传入的字符串

其他

  • isatty(): 如果流是交互式的(即连接到终端/tty设备),则返回 True
  • fileno(): 返回流的底层文件描述符(整数)---如果存在。如果 IO 对象不使用文件描述符,则会引发 OSError 。
  • tell():返回当前流的位置。与seek()中位置类似。需要注意的是,想要获取正确的位置,不能使用如下方式进行操作,会出现下方问题。
    with open(file_path, mode="r") as f:
    for line in f:
    print(line)
    print(f.tell()) OSError: telling position disabled by next() call

    需要使用readline逐行读取

    with open(file_path, mode="r") as f:
    while True:
    line = f.readline()
    print(line)
    if not line:
    break
    print(f.tell())
  • seekable():如果流支持随机访问则返回 True。 如为 False,则 seek(), tell() 和 truncate() 将引发 OSError。
  • seek(offset, whence=SEEK_SET):将流位置修改到给定的字节 offset。 offset 将相对于由 whence 指定的位置进行解析。 whence 的默认值为 SEEK_SET。 需要注意的是seek的偏移量是相对于字符的,不是相对于行数的,whence 的可用值有:
    SEEK_SET 或 0 -- 流的开头(默认值);offset 应为零或正值
    SEEK_CUR or 1 -- 当前流位置;offset 可以为负值
    SEEK_END or 2 -- 流的末尾;offset 通常为负值
  • fileno():返回流的底层文件描述符(整数)---如果存在。如果 IO 对象不使用文件描述符,则会引发 OSError 。
  • flush():刷新流的写入缓冲区(如果适用)。因为某些情况下,在写入时会首先写入到缓冲区,为了保证数据全部写入,可以手动调用flush,这对只读和非阻塞流不起作用。

    返回新的绝对位置。
  • truncate(size=None):将流的大小调整为给定的 size 个字节(如果未指定 size 则调整至当前位置)。 当前的流位置不变。 这个调整操作可扩展或减小当前文件大小。 在扩展的情况下,新文件区域的内容取决于具体平台(在大多数系统上,额外的字节会填充为零)。 返回新的文件大小。在 3.5 版更改: 现在Windows在扩展时将文件填充为零。
  • close(): 刷新并关闭此流。如果文件已经关闭,则此方法无效。文件关闭后,对文件的任何操作(例如读取或写入)都会引发 ValueError 。为方便起见,允许多次调用此方法。但是,只有第一个调用才会生效。
  • closed:如果流已关闭,则返回 True。

操作文件常用函数

复制一个文件的内容到另一个文件

with open(file_path, mode="r", encoding="utf-8") as f, open(
file_path2, mode="w", encoding="utf8"
) as w_f:
for line in f:
print(line)
w_f.write(line)

获取对应行的位置

with open(file_path, mode="r") as f:
while True:
line = f.readline()
print(line)
if not line:
break
print(f.tell())

替换一个文件中的部分内容

在文件中的部分内容周围添加内容

假设存在test.cpp,我们需要在#include前后添加相应的内容,替换内容均为add_test.

/**
* @file test.cpp
*
*/ #include <glog/logging.h>
int main(int argc, char *argv[])
{
google::InitGoogleLogging(argv[0]);
FLAGS_alsologtostderr = true;
LOG(INFO) << "------conan test-----------------"; google::ShutdownGoogleLogging();
return 0;
}
import pathlib
from pathlib import Path def content_before_add(file_path: Path, add_content: str):
"""add before content Args:
file_path (Path): file to be operated
add_content (str): What needs to be added
"""
new_file_path = file_path.parent.joinpath(file_path.name + ".bak")
with open(file_path, mode="r", encoding="utf-8") as r_f, open(
new_file_path, mode="w", encoding="utf-8"
) as w_f:
old_index = -1
for line in r_f:
w_f.write(line)
if line.strip().startswith("#"):
w_f.seek(old_index)
w_f.write(add_content + "\n" + line)
old_index = w_f.tell()
new_file_path.replace(file_path) def content_after_add(file_path: Path, add_content: str):
"""add after content Args:
file_path (Path): file to be operated
add_content (str): What needs to be added
"""
new_file_path = file_path.parent.joinpath(file_path.name + ".bak")
with open(file_path, mode="r", encoding="utf-8") as r_f, open(
new_file_path, mode="w", encoding="utf-8"
) as w_f:
for line in r_f:
w_f.write(line)
if line.strip().startswith("#"):
w_f.write(add_content + "\n")
new_file_path.replace(file_path)

替换后内容如下:

/**
* @file test.cpp
*
*/ add_test
#include <glog/logging.h>
int main(int argc, char *argv[])
{
google::InitGoogleLogging(argv[0]);
FLAGS_alsologtostderr = true;
LOG(INFO) << "------conan test-----------------"; google::ShutdownGoogleLogging();
return 0;
}

大文件的读取

注意事项

1.需要注意对于文件操作时候的模式,w默认会覆盖文件, a默认会追加文件中的内容。

参考

python 官方文档 open

python官方文档 io

python 文件操作(读写等)的更多相关文章

  1. Python文件操作——读写图片,音频,视频

    注意:其实就是将mode="rb"或者mode="wb",因为图片,视频,音频就是二进制进行读取,b  代表binary ,其他的和一般文件操作步骤一样,另外, ...

  2. Python基础篇【第2篇】: Python文件操作

    Python文件操作 在Python中一个文件,就是一个操作对象,通过不同属性即可对文件进行各种操作.Python中提供了许多的内置函数和方法能够对文件进行基本操作. Python对文件的操作概括来说 ...

  3. [Python学习笔记][第七章Python文件操作]

    2016/1/30学习内容 第七章 Python文件操作 文本文件 文本文件存储的是常规字符串,通常每行以换行符'\n'结尾. 二进制文件 二进制文件把对象内容以字节串(bytes)进行存储,无法用笔 ...

  4. 初学Python——文件操作第二篇

    前言:为什么需要第二篇文件操作?因为第一篇的知识根本不足以支撑基本的需求.下面来一一分析. 一.Python文件操作的特点 首先来类比一下,作为高级编程语言的始祖,C语言如何对文件进行操作? 字符(串 ...

  5. day8.python文件操作

    打开和关闭文件 open函数 用Python内置的open()函数打开一个文件,创建一个file对象,相关的方法才可以调用它进行读写. file = open(file_name [, access_ ...

  6. 关于python 文件操作os.fdopen(), os.close(), tempfile.mkstemp()

    嗯.最近在弄的东西也跟这个有关系,由于c基础渣渣.现在基本上都忘记得差不多的情况下,是需要花点功夫才能弄明白. 每个语言都有相关的文件操作. 今天在flask 的例子里看到这样一句话.拉开了文件操作折 ...

  7. Python之路Python文件操作

    Python之路Python文件操作 一.文件的操作 文件句柄 = open('文件路径+文件名', '模式') 例子 f = open("test.txt","r&qu ...

  8. python 文件操作 r w a

    python基础-文件操作   一.文件操作 对文件操作的流程 打开文件,得到文件句柄并赋值给一个变量 通过句柄对文件进行操作 关闭文件       打开文件时,需要指定文件路径和以何等方式打开文件, ...

  9. Python:文件操作技巧(File operation)(转)

    Python:文件操作技巧(File operation) 读写文件 # ! /usr/bin/python #  -*- coding: utf8 -*- spath = " D:/dow ...

  10. 小学生都能学会的python(文件操作)

    小学生都能学会的python(文件操作) 1. open("文件路径", mode="模式", encoding="编码") 文件的路径: ...

随机推荐

  1. Dapr 不是服务网格,只是我长的和他很像

    概述 我们快速看一遍官方文档:https://docs.dapr.io/concepts/service-mesh/#how-dapr-and-service-meshes-compare ,看看 D ...

  2. Go 项目配置文件的定义和读取

    前言 我们在写应用时,基本都会用到配置文件,从各种 shell 到 nginx 等,都有自己的配置文件.虽然这没有太多难度,但是配置项一般相对比较繁杂,解析.校验也会比较麻烦.本文就给大家讲讲我们是怎 ...

  3. 自增特性,外键,级联更新与级联删除,表间关系,SELECT用法,GROUP BY

    自增特性 自动增长的作用: 问题:为数据表设置主键约束后,每次插入记录时,如果插入的值已经存在,会插入失败. 如何解决:为主键生成自动增长的值. 自动增长的语法: 字段名 数据类型 AUTO_INCR ...

  4. 为什么列式存储会被广泛用在 OLAP 中?

    大家好,我是大D. 不知是否有小伙伴们疑问,为什么列式存储会广泛地应用在 OLAP 领域,和行式存储相比,它的优势在哪里?今天我们一起来对比下这两种存储方式的差别. 其实,列式存储并不是一项新技术,最 ...

  5. Spring Boot 3.0.0 M3、2.7.0发布,2.5.x将停止维护

    昨晚(5月19日),Spring Boot官方发布了一系列Spring Boot的版本更新,其中包括: Spring Boot 3.0.0-M3 Spring Boot 2.7.0 Spring Bo ...

  6. c++ web框架实现之静态反射实现

    0 前言 最近在写web框架,框架写好后,需要根据网络发来的请求,选择用户定义的servlet来处理请求.一个问题就是,我们框架写好后,是不知道用户定义了哪些处理请求的类的,怎么办? 在java里有一 ...

  7. 产品揭秘】来也Lead 2022产品亮点解读-RPA学习天地

    2022年4月26日,来也举行新品发布会.作为技术人员,花里胡哨的我且不说,我且说技术相关.整体架构"概念"整个平台覆盖了智能自动化的全生命周期包含:业务理解.流程创建.随处运行. ...

  8. Go微服务框架go-kratos实战01:quickstart 快速开始

    先来感受下用 kratos 快速创建项目 一.环境准备 1.1 安装依赖软件 protoc protoc-gen-go 建议开启 GO111MODULE 1.2 安装 kratos cli go in ...

  9. 解锁!玩转 HelloGitHub 的新姿势

    本文不会涉及太多技术细节和源码,请放心食用 大家好,我是 HelloGitHub 的老荀,好久不见啊! 我在完成 HelloZooKeeper 系列之后,就很少"露面了".但是我对 ...

  10. Spring bean到底是如何创建的?(上)

    前言 众所周知,spring对于java程序员来说是一个及其重要的后端框架,几乎所有的公司都会使用的框架,而且深受广大面试官的青睐.所以本文就以常见的一个面试题"spring bean的生命 ...