Python 3.6处理含NUL字节CSV文件 解决Impala字段分隔识别问题
背景
- 操作系统:Red Hat Linux
- Python 版本:3.6
我每周需要将数千个文件加载到HDFS中,为若干Impala表提供数据。部分字段内部存在逗号,示例如下:
"ingredient","amount" "CORN, GROUND",1
字段虽有引号包裹,但Impala会忽略引号,将字段内部的逗号识别为字段分隔符。我尝试使用Python删除这些内部逗号。从源系统(可能为SQL Server,暂无法确认)导出时,字段中的NULL会被导出为NUL字节,如下图所示:
问题
代码运行到含NUL字节的文件时会抛出错误。我本以为errors='ignore'参数可以避免读取器被NUL字节阻塞,还尝试使用Python内置的chardet提前检测编码以正确打开文件,均未生效。虽然确认部分文件确实存在不同编码,但调整open()参数似乎无法解决问题。
代码
工具模块方法(与执行脚本分离)
def hasInFieldDelimiters(self,file_obj_to_parse,quote_char='"',field_delimiter=',',delimiter_to_find=','): print("Finding commas in file {}".format(file_obj_to_parse)) row_reader = csv.reader(file_obj_to_parse, delimiter=field_delimiter, quotechar=quote_char) for row in row_reader: for field in row: if delimiter_to_find in field: print("In-field comma found") return True print("No commas found") return False
执行脚本
## 上方方法在下方第三行被调用,调用方式为"util.hasInFieldDelimiters()" for file in os.listdir(file_path): encoding = util.getEncoding(file_path,file) with open(file_path+file,'r+',newline='',encoding=encoding,errors='ignore') as file_obj_to_parse: has_in_field_delimiters = util.hasInFieldDelimiters(file_obj_to_parse) if has_in_field_delimiters==True: to_write = [] with open(file_path+file,'r+',newline='',encoding=encoding,errors='ignore') as file_obj_to_parse: reader = csv.reader(file_obj_to_parse,delimiter=',',quotechar='"') for row in reader: for field in row: field = field.replace(',','') to_write += row with open(file_path+file,'w',encoding='latin-1') as replacement: writer = csv.writer(replacement) writer.writerows(to_write)
已尝试的解决方案
我尝试了多种调用open()和csv.reader()的方式。由于使用的是共享远程系统,无法安装codecs、xlrd等新模块,只能使用内置的CSV库。
已参考的相关问题:
- Python CSV error: line contains NULL byte
- python Dictread of CSV file with NUL bytes in data
- File not opening past NUL byte
- Python - Finding unicode/ascii problems
内容的提问来源于stack exchange,提问作者Drew R
相关产品推荐
相关产品推荐

