在我的django应用程序中,我提供了一个允许用户上传文件的表单.该文件可以采用多种格式(Excel,CSV),来自各种平台(Mac,Linux,Windows),并以各种编码(ASCII,UTF-8)编码.
出于这个问题的目的,让我们假设我有一个正在接收的视图request.FILES['file']
,这是一个InMemoryUploadedFile
被调用的实例file
.我的问题是InMemoryUploadedFile
对象(如file
):
\xef\xbb\xbf
在文件的开头看到一个,据我所知是一个标志,意思是'这个文件是UTF-8').使问题复杂化的是我希望将文件传递给python csv
模块,该模块本身不支持Unicode.我很乐意接受避免这个问题的答案 - 一旦我让django玩UTF-8,我相信我可以大胆csv
地做同样的事情.(同样,请忽略支持Excel的要求 - 在解决Excel文件之前,我要等到CSV工作.)
我已经尝试使用StringIO
,mmap
,codec
,和任何的各种各样的在访问数据的方法InMemoryUploadedFile
的对象.每种方法都产生了不同的错误,到目前为止还没有一种是完美的.这显示了一些我认为最接近的代码:
import csv
import codecs
class CSVParser:
def __init__(self,file):
# 'file' is assumed to be an InMemoryUploadedFile object.
dialect = csv.Sniffer().sniff(codecs.EncodedFile(file,"utf-8").read(1024))
file.open() # seek to 0
self.reader = csv.reader(codecs.EncodedFile(file,"utf-8"),
dialect=dialect)
try:
self.field_names = self.reader.next()
except StopIteration:
# The file was empty - this is not allowed.
raise ValueError('Unrecognized format (empty file)')
if len(self.field_names) <= 1:
# This probably isn't a CSV file at all.
# Note that the csv module will (incorrectly) parse ALL files, even
# binary data. This will catch most such files.
raise ValueError('Unrecognized format (too few columns)')
# Additional methods snipped, unrelated to issue
Run Code Online (Sandbox Code Playgroud)
请注意,我没有花太多时间在实际的解析算法上,所以它可能效率非常低,现在我更关心的是让编码按预期工作.
问题是尽管被包装在Unicode codecs.EncodedFile
文件包装器中,结果也没有被编码.
编辑:事实证明,上面的代码实际上工作.codecs.EncodedFile(file,"utf-8")
是票.事实证明我认为它不起作用的原因是我使用的终端不支持UTF-8.活到老,学到老!
如上所述,我提供的代码片段实际上是按预期工作的 - 问题出在我的终端上,而不是python编码.
如果您的视图需要访问UTF-8 UploadedFile
,您只需使用utf8_file = codecs.EncodedFile(request.FILES['file_field'],"utf-8")
正确的编码打开文件对象.
我还注意到,至少对于InMemoryUploadedFile
s,通过codecs.EncodedFile
包装器打开文件不会重置seek()
文件描述符的位置.要返回文件的开头(再次,这可能是InMemoryUploadedFile
具体的)我只是用来request.FILES['file_field'].open()
将seek()
位置发回0.
归档时间: |
|
查看次数: |
7833 次 |
最近记录: |