【发布时间】:2022-01-18 08:35:56
【问题描述】:
我有一个程序可以接受多个输入文件的组合,也可以使用目录来扫描这些输入文件。
通常,我只接受具有 CSV、XML 和 JSON 的有效文件扩展名的文件 - 但正如我多年来了解到的那样,你不能真正相信用户提供正确的文件。
例如,如果用户有一个带有 XML 扩展名的文件,但实际内容是 JSON,我想警告用户并将该文件视为 JSON 文件。 另一种情况是在基于 Unix 的操作系统上,文件扩展名不像 Windows 那样用于识别文件类型,与文件内容相比,这可能会导致更多文件类型不正确的情况。
现在,我的程序收集文件列表,将它们过滤为仅具有可接受文件扩展名的文件,然后我创建一个concurrent.futures.ThreadPoolExecutor 以便能够同时检查所有文件。实际检查如下:
with open(the_file, "r") as f:
check = f.read(1)
if check == "{" or check == "[":
file_type = "json"
elif check == "<":
file_type = "xml"
else:
file_type = "csv"
这有两个主要问题:
- 如果文件应该是 CSV,并且它的第一个字符是
[或{或<,那么程序将为其分配错误的文件类型。 - 相反,如果文件不是任何可接受的类型,并且它不是以
[或{或<开头,那么程序将假设该文件应该是一个CSV .
我有以下想法来解决这个问题:
import csv
import json
import defusedxml.ElementTree as xml
try:
loaded = xml.parse(the_file)
return "XML"
except xml.ParseError:
del loaded
try:
loaded = json.load(the_file)
return "JSON"
except json.JSONDecodeError:
del loaded
try:
with open(the_file, "r") as csv_file:
loaded = csv.DictReader(csv_file)
return "CSV"
except csv.Error:
print("The file is not in any acceptable format")
问题在于,由于我的程序尝试同时对多个文件运行此检查,因此同时打开这么多文件时,内存使用率可能会变得非常高。另一个小问题是一次打开和关闭这么多文件以检查文件类型的 I/O 成本。
对于我正在尝试做的事情,是否有更有效的替代方法?
【问题讨论】:
-
对于xml文件,你可以试试正则表达式,看看这个文件的第一行是否包含
<?xml version="1.0" encoding="ISO-8859-1"?>之类的东西。 -
并非所有 XML 文件实际上都需要以
<?xml version开头,它们也不必包含编码类型。为这些东西添加正则表达式可以作为检查 XML 文件的补充,但是当不能完全保证判断文件是否是有效的 XML 文件时,我不会仅仅依赖它。 -
不会尝试使用正则表达式,不妨尝试解析它,否则您不知道这是一个有效的 XML 或 JSON 文件。
-
如果资源/时间不是问题,我会尝试对每种格式进行解析,然后继续使用不会产生解析错误的格式。
-
@Hunter_AP 你说得对,确实,这个问题基本上没有好的解决办法,总会有一些极端的情况。
标签: python python-3.x file