python:读取带有非ascii nam的二进制文件

2024-04-28 15:09:06 发布

您现在位置:Python中文网/ 问答频道 /正文

我试着做一个脚本,在文件夹中搜索双文件,然后在这样的字典中返回它 {filehash1:[dirfile1,dirfile2],filehash2:[dirfile3]} (dirfile1和dirfile2相同的文件名/位置不同)

第一个代码:

import glob
import hashlib

def getallfolders(dir):
    print dir+"*\\"
    folders = glob.glob(dir+"*\\")
    return folders

def getallfiles(dir):
    folders = glob.glob(dir+"*.*")
    return folders


def filehash(file):
    BLOCKSIZE = 65536
    hasher = hashlib.sha1()
    with open(file, 'rb') as afile:
        buf = afile.read(BLOCKSIZE)
        while len(buf) > 0:
            hasher.update(buf)
            buf = afile.read(BLOCKSIZE)
    return hasher.hexdigest()


def double_files(dir):
    mil = {}
    folders = getallfolders(dir)
    for folder in folders:
        mil.update(double_files(folder))
    files = getallfiles(dir)
    for file in files:
        fhash = filehash(file)
        if fhash in mil.keys():
            mil[fhash] = mil[fhash] + [file]
        else:
            mil[fhash] = [file]
    return mil



print double_files("E:\\not organised\\")

但是如果我试着运行它,它会出错崩溃

^{pr2}$

因为不是所有的文件名都是英文的 所以我尝试修复它,现在代码如下所示:

# -*- coding: utf-8 -*-
import glob
import hashlib
import codecs

def getallfolders(dir):
    print dir+"*\\"
    folders = glob.glob(dir+"*\\")
    return folders

def getallfiles(dir):
    folders = glob.glob(dir+"*.*")
    return folders



def filehash(file):
    BLOCKSIZE = 65536
    hasher = hashlib.sha1()
    file = file.decode("utf8")
    with codecs.open(file, "rb", encoding="utf8") as afile:
        buf = afile.read(BLOCKSIZE)
        while len(buf) > 0:
            buf = buf.encode("ISO-8859-1")
            hasher.update(buf)
            buf = afile.read(BLOCKSIZE)
    return hasher.hexdigest()

def double_files(dir):
    mil = {}
    folders = getallfolders(dir)
    for folder in folders:
        mil.update(double_files(folder))
    files = getallfiles(dir)
    for file in files:
        fhash = filehash(file)
        if fhash in mil.keys():
            mil[fhash] = mil[fhash] + [file]
        else:
            mil[fhash] = [file]
    return mil



print double_files("E:\\not organised\\")

我补充道 # -*- coding: utf-8 -*- 改变 with open(file, 'rb')with open(file, encoding='utf-8') 但现在我得到了一个错误:

UnicodeDecodeError: 'utf8' codec can't decode byte .. in position ..: Tnvalid start byte

(那个。。意思是不总是一样的) 它发生在buf = afile.read(BLOCKSIZE)线上 我知道文件已打开,但当我尝试使用read函数时,它会崩溃并出现错误。 我不知道怎么解决它。。。 请帮忙。在


Tags: inreadreturndefdirfilesglobfolders
2条回答

你似乎对编码很困惑。。。在

  • # -*- coding: utf-8 -*-仅适用于代码中的非asciiliteral字符串。

  • file = file.decode("utf8")将字符串file(最好命名为filename)从utf-8解码为unicode。这只适用于文件系统的编码(文件和文件夹名称)是utf-8(或者更确切地说,只要所有文件和文件夹的名称都可以解释为有效的utf-8)。当然,它对文件的内容没有多大作用。

  • codecs.open(file, "rb", encoding="utf8"):只有当文件的内容实际上是一些utf-8编码的文本时,这才有意义,而且显然您正在读取任何类型的二进制数据,因此,如果出现虚假的编码错误,这一点也不奇怪。

  • buf.encode("ISO-8859-1"):只是毫无用处,hashlib.sha1()可以很好地与utf-8配合使用。

长话短说:你的“修复”没有一个是有意义的。在

回到问题的根源:

IOError: [Errno 2] No such file or directory: file It caused because not all the files name in english

我真的认为你在这里假设的太多了-如果你从浏览文件系统得到了一个非ascii(不是“非英语”)文件名,那么你的文件系统应该支持这种非ascii编码(好吧,它是Windows,所以这里可能会发生一些特殊的事情,但我可以告诉你,我从来没有在Linux上遇到过这样的问题也不是MacOS)。最坏的情况下,如果您的“非英语”(非ascii)文件名是utf8,那么您可以尝试使用file = file.decode('utf-8')来查看它是否工作得更好,但仍然是programming by accident。在

实际上,由于您没有发布有效的回溯(使用完整的文件名),所以很难判断原始代码到底出了什么问题,所以您最好的选择当然是切换回第一个实现并仔细阅读完整的回溯。然后可以使用交互式pythonshell或the step debugger进一步检查问题。在

哦,是的:我假设您使用的是Python2.x-Python3处理编码的方式有点不同。在

所以在我读了你们所有人写的东西之后,我理解了我的问题,这次真的修复了代码,它工作得很好 (在字典上发现了另一个我没有注意到的问题) 工作守则:

import hashlib
from os import listdir
from os.path import isfile, join
import os


def getallfolders(dir):
    folders = [d for d in os.listdir(dir) if os.path.isdir(os.path.join(dir, d))]
    return folders


def getallfiles(dir):
    folders = [f for f in listdir(dir) if isfile(join(dir, f))]
    return folders


def filehash(file):
    BLOCKSIZE = 65536
    hasher = hashlib.sha1()
    with open(file, "rb") as afile:
        buf = afile.read(BLOCKSIZE)
        while len(buf) > 0:
            hasher.update(buf)
            buf = afile.read(BLOCKSIZE)
    return hasher.hexdigest()


def double_files(dir):
    print dir
    mil = {}
    folders = getallfolders(dir)
    for folder in folders:
        newmil = double_files(dir + folder + "\\")
        for i in newmil:
            if i in mil.keys():
                mil[i] = mil[i] + newmil[i]
            else:
                mil[i] = newmil[i]
    files = getallfiles(dir)
    for file in files:
        fhash = filehash(dir + file)
        if fhash in mil.keys():
            mil[fhash] = mil[fhash] + [dir + file]
        else:
            mil[fhash] = [dir + file]
    return mil


mil = double_files(u"E:\\not organised\\")
f = open('double_files.txt', 'w')
for i in mil:
    if len(mil[i]) > 1:
        for y in mil[i]:
            f.write(y.encode('utf8')+"\n")
        f.write("\n\n")
f.close()

相关问题 更多 >