如何在附加模式下寻找写指针?
How to seek write pointer in append mode?
我正在尝试打开一个文件来读取它的内容,然后使用之前读取的内容写入它。我正在以 'a+' 模式打开文件。我无法使用 'r+' 模式,因为如果文件不存在,它不会创建文件。
a+
会将指针放在文件末尾。
可以用tell()
保存,以后再写。
然后用seek(0,0)
到return归档开始阅读。
默认开启
使用默认的 a(+)
选项,这是不可能的,如文档中所提供的:
''mode 是一个可选的字符串,指定文件所在的模式
被打开。它默认为 'r' 这意味着打开以阅读文本
模式。其他常用值是 'w' 用于写入(截断文件如果
它已经存在),'x' 用于创建和写入新文件, 和
'a' 用于追加(在某些 Unix 系统上,这意味着所有写入
无论当前搜索位置如何,都追加到文件末尾。''
备选
使用默认打开,这不是possible.However我们当然可以创建我们自己的文件处理程序,它将在r
和r+
模式下创建一个文件,当它没有' t 存在。
一个与 open(filename, 'r+', *args, **kwargs)
完全相同的最小工作示例是:
import os
class FileHandler:
def __init__(self, filename, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True):
self.filename = filename
self.mode = mode
self.kwargs = dict(buffering=buffering, encoding=encoding, errors=errors, newline=newline, closefd=closefd)
if self.kwargs['buffering'] is None:
del self.kwargs['buffering']
def __enter__(self):
if self.mode.startswith('r') and not os.path.exists(self.filename):
with open(self.filename, 'w'): pass
self.file = open(self.filename, self.mode, **self.kwargs)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
self.file.close()
现在当您使用以下代码时:
with FileHandler("new file.txt", "r+") as file:
file.write("First line\n")
file.write("Second line\n")
file.seek(0, 0)
file.write("Third line\n")
它将生成一个新文件 new file.txt
,当它不存在时,上下文为:
Third line
Second line
如果您使用 open
,如果文件不存在,您将收到 FileNotFoundError
。
备注
- 我只在模式以
r
开始时创建一个新文件,所有其他文件都按正常 open
函数处理。
- 出于某种原因,将
buffering=None
直接传递给 open
函数会使它崩溃并带有 TypeError: an integer is required (got type NoneType)
,因此我必须将其从关键字参数中删除,如果它是 None
。尽管根据文档这是默认参数(如果有人知道为什么,请告诉我)
编辑
以上代码没有处理以下情况:
file = FileHandler("new file.txt", "r+")
file.seek(0, 0)
file.write("Welcome")
file.close()
为了支持 open
个用例中的 all 个,上面的 class 可以使用 __getattr__
调整如下:
import os
class FileHandler:
def __init__(self, filename, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True):
self.filename = filename
self.mode = mode
self.kwargs = dict(buffering=buffering, encoding=encoding, errors=errors, newline=newline, closefd=closefd)
if self.kwargs['buffering'] is None:
del self.kwargs['buffering']
if self.mode.startswith('r') and not os.path.exists(self.filename):
with open(self.filename, 'w'): pass
self.file = open(self.filename, self.mode, **self.kwargs)
def __enter__(self):
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
self.file.close()
def __getattr__(self, item):
if hasattr(self.file, item):
return getattr(self.file, item)
raise AttributeError(f"{type(self).__name__}, doesn't have the attribute {item!r}")
我正在尝试打开一个文件来读取它的内容,然后使用之前读取的内容写入它。我正在以 'a+' 模式打开文件。我无法使用 'r+' 模式,因为如果文件不存在,它不会创建文件。
a+
会将指针放在文件末尾。
可以用tell()
保存,以后再写。
然后用seek(0,0)
到return归档开始阅读。
默认开启
使用默认的 a(+)
选项,这是不可能的,如文档中所提供的:
''mode 是一个可选的字符串,指定文件所在的模式 被打开。它默认为 'r' 这意味着打开以阅读文本 模式。其他常用值是 'w' 用于写入(截断文件如果 它已经存在),'x' 用于创建和写入新文件, 和 'a' 用于追加(在某些 Unix 系统上,这意味着所有写入 无论当前搜索位置如何,都追加到文件末尾。''
备选
使用默认打开,这不是possible.However我们当然可以创建我们自己的文件处理程序,它将在r
和r+
模式下创建一个文件,当它没有' t 存在。
一个与 open(filename, 'r+', *args, **kwargs)
完全相同的最小工作示例是:
import os
class FileHandler:
def __init__(self, filename, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True):
self.filename = filename
self.mode = mode
self.kwargs = dict(buffering=buffering, encoding=encoding, errors=errors, newline=newline, closefd=closefd)
if self.kwargs['buffering'] is None:
del self.kwargs['buffering']
def __enter__(self):
if self.mode.startswith('r') and not os.path.exists(self.filename):
with open(self.filename, 'w'): pass
self.file = open(self.filename, self.mode, **self.kwargs)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
self.file.close()
现在当您使用以下代码时:
with FileHandler("new file.txt", "r+") as file:
file.write("First line\n")
file.write("Second line\n")
file.seek(0, 0)
file.write("Third line\n")
它将生成一个新文件 new file.txt
,当它不存在时,上下文为:
Third line
Second line
如果您使用 open
,如果文件不存在,您将收到 FileNotFoundError
。
备注
- 我只在模式以
r
开始时创建一个新文件,所有其他文件都按正常open
函数处理。 - 出于某种原因,将
buffering=None
直接传递给open
函数会使它崩溃并带有TypeError: an integer is required (got type NoneType)
,因此我必须将其从关键字参数中删除,如果它是None
。尽管根据文档这是默认参数(如果有人知道为什么,请告诉我)
编辑
以上代码没有处理以下情况:
file = FileHandler("new file.txt", "r+")
file.seek(0, 0)
file.write("Welcome")
file.close()
为了支持 open
个用例中的 all 个,上面的 class 可以使用 __getattr__
调整如下:
import os
class FileHandler:
def __init__(self, filename, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True):
self.filename = filename
self.mode = mode
self.kwargs = dict(buffering=buffering, encoding=encoding, errors=errors, newline=newline, closefd=closefd)
if self.kwargs['buffering'] is None:
del self.kwargs['buffering']
if self.mode.startswith('r') and not os.path.exists(self.filename):
with open(self.filename, 'w'): pass
self.file = open(self.filename, self.mode, **self.kwargs)
def __enter__(self):
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
self.file.close()
def __getattr__(self, item):
if hasattr(self.file, item):
return getattr(self.file, item)
raise AttributeError(f"{type(self).__name__}, doesn't have the attribute {item!r}")