为什么在连续打开和写入调用时出现“[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.open
和 json.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
更新
它现在直接调用并在关系文档中抛出错误。我完全摆脱了 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.open
和 json.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