生成含特殊字符的XML文件时触发OSError无效参数错误求助
解决Windows下文件名含非法字符导致的OSError问题
问题场景
我需要生成两种命名规则的XML文件:
- 自动命名格式:
23-10-2022|21-03-11.xml - 用户自定义名称拼接时间格式:
userGeneratedName23-10-2022-21-03-11.xml
但程序将文件保存到指定文件夹时抛出Invalid argument错误,最初怀疑是os.path.join使用不当,相关代码及报错信息如下:
相关代码
if not os.path.exists("Generated XMLs"): os.makedirs("Generated XMLs") #open file today = date.today() now = datetime.now() #if filename is not specified, create file with today's date and time of creation if filename == "": filename = today.strftime("%d-%m-%Y") +"|"+ now.strftime("%H-%M-%S") #if filename is specified,ad at the and of filename today's date and time of creation else: filename = filename + today.strftime("%d-%m-%Y")+"|"+ now.strftime("%H-%M-%S") # open file wchich is in Generated XMLs folder and name it with variable filename file = open(os.path.join("Generated XMLs", filename + ".xml"), "w") #write to file #write header file.write("\n<root>\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>") file.write("\t<POZYCJE>\n") #write data # ask user if he wont netto or brutto meters and ad flag flag = input("Enter 'n' if you want to use netto meters or 'b' if you want to use brutto meters: ") for i in range(len(convertedData)): file.write("\t\t<POZYCJA>\n") file.write("\t\t\t<LP>" + str(i+1) + "</LP>\n") file.write("\t\t\t<TOWAR>\n") file.write("\t\t\t\t<KOD>" + convertedData[i][0] + " " + convertedData[i][1] + "</KOD>\n") file.write("\t\t\t\t<NAZWA>" + convertedData[i][0] + " " + convertedData[i][1] + "</NAZWA>\n") file.write("\t\t\t\t<OPIS/>") file.write("\t\t\t\t<EAN/>") file.write("\t\t\t\t<SWW/>") file.write("\t\t\t\t<NUMER_KATALOGOWY/>") file.write("\t\t\t\t<MPP>" + "0" + "</MPP>\n") file.write("\t\t\t</TOWAR>\n") file.write("\t\t\t<STAWKA_VAT>\n") file.write("\t\t\t\t<STAWKA>" + "23.00" + "</STAWKA>\n") file.write("\t\t\t\t<FLAGA>" + "2" + "</FLAGA>\n") file.write("\t\t\t\t<ZRODLOWA>" + "0.00" + "</ZRODLOWA>\n") file.write("\t\t\t</STAWKA_VAT>\n") file.write("\t\t\t<CENY>\n") file.write("\t\t\t\t<CENAZCZTEREMAMIEJSCAMI>0</CENAZCZTEREMAMIEJSCAMI>\n") file.write("\t\t\t\t<POCZATKOWA_WAL_CENNIKA>00.0000</POCZATKOWA_WAL_CENNIKA>\n") file.write("\t\t\t\t<POCZATKOWA_WAL_DOKUMENTU>00.0000</POCZATKOWA_WAL_DOKUMENTU>\n") file.write("\t\t\t\t<PO_RABACIE_WAL_CENNIKA>00.0000</PO_RABACIE_WAL_CENNIKA>\n") file.write("\t\t\t\t<PO_RABACIE_PLN>00.0000</PO_RABACIE_PLN>\n") file.write("\t\t\t\t<PO_RABACIE_WAL_DOKUMENTU>00.0000</PO_RABACIE_WAL_DOKUMENTU>\n") file.write("\t\t\t</CENY>\n") file.write("\t\t\t<WALUTA>\n") file.write("\t\t\t\t<SYMBOL>PLN</SYMBOL>\n") file.write("\t\t\t\t<KURS_L>1.00</KURS_L>\n") file.write("\t\t\t\t<KURS_M>1</KURS_M>\n") file.write("\t\t\t</WALUTA>\n") file.write("\t\t\t<RABAT>0.00</RABAT>\n") file.write("\t\t\t<WARTOSC_NETTO>0.00</WARTOSC_NETTO>\n") file.write("\t\t\t<WARTOSC_BRUTTO>0.00</WARTOSC_BRUTTO>\n") file.write("\t\t\t<WARTOSC_NETTO_WAL>00.00</WARTOSC_NETTO_WAL>\n") file.write("\t\t\t<WARTOSC_BRUTTO_WAL>833.94</WARTOSC_BRUTTO_WAL>\n") if flag == "n": file.write("\t\t\t<ILOSC>" + convertedData[i][3] + "00" + "</ILOSC>\n") elif flag == "b": file.write("\t\t\t<ILOSC>" + convertedData[i][2] + "00" + "</ILOSC>\n") else: print("Error: Wrong flag. Enter 'n' or 'b'.") file.write("\t\t\t<JB>" + convertedData[i][4] + "</JB>\n") file.write("\t\t\t<JM_CALKOWITE>0.00</JM_CALKOWITE>\n") file.write("\t\t\t<JM_ZLOZONA>\n") file.write("\t\t\t\t\n") file.write("\t\t\t\t\n") file.write("\t\t\t\t\n") file.write("\t\t\t</JM_ZLOZONA>\n") file.write("\t\t\t<JMZ>" + convertedData[i][4] + "</JMZ>\n") file.write("\t\t\t<JM_PRZELICZNIK_L>1.00</JM_PRZELICZNIK_L>\n") file.write("\t\t\t<JM_PRZELICZNIK_M>1</JM_PRZELICZNIK_M>\n") file.write("\t\t</POZYCJA>\n") #write footer file.write("\t</POZYCJE>\n") file.write("</root>") #close file file.close()
报错信息
Traceback (most recent call last): File "C:\Users\reczul\PycharmProjects\pythonProject5\main.py", line 23, in <module> main() File "C:\Users\reczul\PycharmProjects\pythonProject5\main.py", line 13, in main XMLCreator.CreateXML(DataConverter.ConvertData(data)) File "C:\Users\reczul\PycharmProjects\pythonProject5\venv\Functions\XMLCreator.py", line 20, in CreateXML file = open(os.path.join("Generated XMLs", filename + ".xml"), "w") OSError: [Errno 22] Invalid argument: 'Generated XMLs\\24-10-2022|09-23-45.xml' Process finished with exit code 1
错误原因
问题和os.path.join无关,核心原因是Windows系统禁止文件名包含竖线|,除此之外,:、*、?、<、>、"这些字符也属于非法字符,都会触发OSError。从报错路径可以看到,文件名里的|是罪魁祸首。
修复方案
1. 替换文件名中的非法竖线
将生成文件名时使用的竖线|替换为合法字符,比如横线-或者下划线_,修改后的代码如下:
替换为横线:
if filename == "": filename = today.strftime("%d-%m-%Y") + "-" + now.strftime("%H-%M-%S") else: filename = filename + today.strftime("%d-%m-%Y") + "-" + now.strftime("%H-%M-%S")
替换为下划线(更清晰的分隔):
if filename == "": filename = f"{today.strftime('%d-%m-%Y')}_{now.strftime('%H-%M-%S')}" else: filename = f"{filename}{today.strftime('%d-%m-%Y')}_{now.strftime('%H-%M-%S')}"
2. 过滤用户自定义名称中的非法字符
如果允许用户输入自定义文件名,建议提前过滤掉所有Windows非法字符,避免后续报错:
import re # 匹配所有Windows文件名非法字符的正则表达式 invalid_filename_chars = r'[\\/:*?"<>|]' # 将非法字符替换为下划线 filename = re.sub(invalid_filename_chars, '_', filename)
内容的提问来源于stack exchange,提问作者Mateusz Reiczel
相关产品推荐
相关产品推荐

