2015-08-15 50 views
3

我想要一个函数,它接受一个文件的路径,检查文件是否以\n结尾,如果不是,则添加\nPython确保文件以行返回结束?

我知道我可以通过打开文件两次,一次是读取模式,然后是再次追加模式来做到这一点,但我觉得我必须错过一些东西......例如,我觉得像'w+'模式必须能够做到。

下面是一个打开文件两次的方法(我希望简单一些,只打开一次)。

def ensureFileEndsWith(path, end): 
    with open(path) as f: 
     f.seek(-1, 2) 
     alreadyGood = f.read(1) == end 
    if not alreadyGood: 
     with open(path, 'a') as f: 
      f.write(end) 

我想做同样的事情,但只打开一次文件。我尝试这样做:

def ensureFileEndsWith(path, end): 
    with open(path, 'w+') as f: 
     f.seek(-1, 2) 
     if not f.read(1) == end: 
      f.write(end) 

但它打印出此异常:

IOError: [Errno 22] Invalid argument 

关于在'w+'模式打开的文件我的seek使用。

+0

从2.7 docs - '''(注意'w +'截断文件)'''。 – wwii

+0

@wwii:呃 - 那很糟糕。我的整个文件现在都消失了。这只是一个日志文件,我不认为我有什么重要的东西,但现在它是空的。 – ArtOfWarfare

+0

在做任何可能弄乱文件的事情之前,请务必进行备份! :) – Cyphase

回答

1

首先你要open(path, 'r+'); 'w+'截断该文件。你得到这个错误的原因是因为你不能在空文件中执行f.seek(-1, 2)。这应该为你做:

def ensureFileEndsWith(path, end): 
    with open(path, 'r+') as f: 
     try: 
      f.seek(-len(end), 2) 
     except IOError: 
      # The file is shorter than end (possibly empty) 
      f.seek(0, 2) 

     # Passing in a number to f.read() is unnecessary 
     if f.read() != end: 
      f.write(end) 
+0

不太对 - 我编辑了你的答案。你的回答没有处理文件已经以正确字符结束的可能性,在这种情况下,函数应该关闭文件并返回。 – ArtOfWarfare

+1

@ArtOfWarfare,谢谢你指出。我进一步改进了代码以允许可变长度的'end'。 – Cyphase