为什么在连续打开和写入调用时出现“[Errno 13] Permission denied:”?

Why am I getting "[Errno 13] Permission denied:" when making consecutive open and write calls?

更新

它现在直接调用并在关系文档中抛出错误。我完全摆脱了 write_el(),只是这样做:

...
if el["doc_type"] == "node":
    with codecs.open((fo_pre+"_nodes.json"), mode) as fo:
        fo.write(json.dumps(el, indent=2)+"\n")
...

此外,应该注意 XML 文档 (OSM) 首先是所有节点元素,然后是方式元素,然后是关系元素。

原版post

我正在使用 codecs.openjson.dumps 从 Python xml.etree.ElemenTree.iterparse 中写入多个 JSON 文件。我调用了一个单独的函数来写入文件。

这适用于部分 elements/documents,但并非全部。它只写这么多,然后以 PermissionError: [Errno 13] Permission denied: <file name> 停止。最后调用文件写入方法returns 207,但之前的很多调用也是如此。而且,下一个元素看起来很正常:

<!--Last element written to JSON file.-->
  <node id="7898832843" lat="48.7888301" lon="-122.5067978" version="1" timestamp="2020-09-11T22:37:30Z" changeset="90779671" uid="10612244" user="mapstuffs"/>

<!--Next element, not written to JSON file.-->
  <node id="7898832844" lat="48.7888177" lon="-122.5058429" version="1" timestamp="2020-09-11T22:37:30Z" changeset="90779671" uid="10612244" user="mapstuffs"/>

此外,每次我尝试时它都会在不同的元素上抛出错误。而且,它有时不会抛出错误。

精简 Python:

import xml.etree.ElementTree as ET
import codecs
import json

def write_el(el, file_out, mode = "a"):
    with codecs.open(file_out, mode) as fo:
        fo.write(json.dumps(el, indent=2)+"\n")
    return

def process_map(file_in, fo_pre, mode = "a"):
    
    for _, element in ET.iterparse(file_in):
        # shape_element() formats XML elements into JSON-compatible Python
        # dictionaries and lists.
        el = shape_element(element)
        if el:
            if el["doc_type"] == "node":
# Calling open/write directly works.
#                 with codecs.open(fo_pre+"_nodes.json", mode) as fo:
#                     fo.write(json.dumps(el, indent=2)+"\n")
# But, calling write_el for this doc_type throws permission error
# halfway through the document. The element following the last written looks
# just fine.
                write_el(el=el, file_out=fo_pre+"_nodes.json", mode=mode)
# Calling write_el works fine for the other doc_types, if error not thrown
# from previous block first.
            elif el["doc_type"] == "way":
                write_el(el=el, file_out=fo_pre+"_ways.json", mode=mode)
            elif el["doc_type"] == "relation":
                write_el(el=el, file_out=(fo_pre+"_relations.json"),
                         mode=mode, write=write, pretty=pretty)
                
def test():
    process_map(file_in=filename, fo_pre="test_bham", write=True)

    return

test()

Returns

PermissionError: [Errno 13] Permission denied: 'test_bham_nodes.json'

感谢一些评论者,我发现在 iterparse() 之外嵌套 with open() 可以解决问题。

我的防病毒程序可能是罪魁祸首,每次关闭文件时都会访问该文件,这偶尔会导致下一次打开文件时发生访问冲突。

由于操作成本,我不喜欢为每个元素打开和关闭文件,并且我最初在写入单个文件时从打开的文件中解析了 XML。但是,当我决定写入多个文件时,我不想为每个我想从中写入的 JSON 文件重新解析 XML。

现在看起来很容易,但嵌套文件打开工作并节省计算。如果你想写很多文件,它可能会增加缩进,但是这就是生活。

def process_map(file_in, fo_pre, mode = "a"):
    
    with codecs.open(fo_pre+"_nodes.json", mode) as nd_fo, \
    codecs.open(fo_pre+"_ways.json", mode) as wy_fo, \
    codecs.open(fo_pre+"_relations.json", mode) as rl_fo:

        for _, element in ET.iterparse(file_in):
                el = shape_element(element)
                if el:
                    if el["doc_type"] == "node":
                        write_el(el=el, file_out=fo_pre+"_nodes.json",
                                 mode=mode)
                    elif el["doc_type"] == "way":
                        write_el(el=el, file_out=fo_pre+"_ways.json",
                                 mode=mode)
                    elif el["doc_type"] == "relation":
                        write_el(el=el, file_out=fo_pre+"_relations.json",
                                 mode=mode)

    return