Как я могу обнаружить, если файл является двоичным (нетекст) в Python?

Интеграционное тестирование обычно происходит после модульного тестирования. Я не уверен, какое значение имеет тестирование взаимодействий между юнитами, которые сами не были протестированы.

Нет смысла проверять, как шестерни машины вращаются вместе, если они могут сломаться.

96
задан JayRizzo 10 July 2019 в 06:01
поделиться

8 ответов

Вы также можете использовать модуль mimetypes :

import mimetypes
...
mime = mimetypes.guess_type(file)

Достаточно легко составить список двоичных типов mime. Например, Apache распространяется с файлом mime.types, который можно разобрать на набор списков, двоичных и текстовых, а затем проверить, есть ли mime в текстовом или двоичном списке.

37
ответ дан 24 November 2019 в 05:40
поделиться

вы используете unix? если да, то попробуйте:

isBinary = os.system("file -b" + name + " | grep text > /dev/null")

Значения, возвращаемые оболочкой, инвертируются (0 - нормально, поэтому, если он найдет «текст», он вернет 0, а в Python это выражение False).

0
ответ дан 24 November 2019 в 05:40
поделиться

Обычно вам приходится угадывать.

Вы можете рассматривать расширения как одну из подсказок, если они есть в файлах.

Вы также можете распознавать известные двоичные форматы и игнорировать их.

В противном случае посмотрите, какая у вас доля непечатаемых байтов ASCII, и сделайте предположение.

Вы также можете попробовать декодирование из UTF-8 и посмотреть, дает ли это разумный результат.

4
ответ дан 24 November 2019 в 05:40
поделиться

Here's a suggestion that uses the Unix file command:

import re
import subprocess

def istext(path):
    return (re.search(r':.* text',
                      subprocess.Popen(["file", '-L', path], 
                                       stdout=subprocess.PIPE).stdout.read())
            is not None)

Example usage:

>>> istext('/etc/motd') 
True
>>> istext('/vmlinuz') 
False
>>> open('/tmp/japanese').read()
'\xe3\x81\x93\xe3\x82\x8c\xe3\x81\xaf\xe3\x80\x81\xe3\x81\xbf\xe3\x81\x9a\xe3\x81\x8c\xe3\x82\x81\xe5\xba\xa7\xe3\x81\xae\xe6\x99\x82\xe4\xbb\xa3\xe3\x81\xae\xe5\xb9\x95\xe9\x96\x8b\xe3\x81\x91\xe3\x80\x82\n'
>>> istext('/tmp/japanese') # works on UTF-8
True

It has the downsides of not being portable to Windows (unless you have something like the file command there), and having to spawn an external process for each file, which might not be palatable.

6
ответ дан 24 November 2019 в 05:40
поделиться

Если это помогает, многие двоичные типы начинаются с магических чисел. Вот список сигнатур файлов.

8
ответ дан 24 November 2019 в 05:40
поделиться

Если вы не в Windows, вы можете использовать Python Magic для определения типа файла. Затем вы можете проверить, является ли это типом текста / пантомимы.

3
ответ дан 24 November 2019 в 05:40
поделиться

Попробуйте следующее:

def is_binary(filename):
    """Return true if the given filename is binary.
    @raise EnvironmentError: if the file does not exist or cannot be accessed.
    @attention: found @ http://bytes.com/topic/python/answers/21222-determine-file-type-binary-text on 6/08/2010
    @author: Trent Mick <TrentM@ActiveState.com>
    @author: Jorge Orpinel <jorge@orpinel.com>"""
    fin = open(filename, 'rb')
    try:
        CHUNKSIZE = 1024
        while 1:
            chunk = fin.read(CHUNKSIZE)
            if '\0' in chunk: # found null byte
                return True
            if len(chunk) < CHUNKSIZE:
                break # done
    # A-wooo! Mira, python no necesita el "except:". Achis... Que listo es.
    finally:
        fin.close()

    return False
10
ответ дан 24 November 2019 в 05:40
поделиться

Думаю, лучшее решение - использовать функцию guess_type. Он содержит список с несколькими типами mimetypes, и вы также можете включать свои собственные типы. Вот сценарий, который я написал для решения моей проблемы:

from mimetypes import guess_type
from mimetypes import add_type

def __init__(self):
        self.__addMimeTypes()

def __addMimeTypes(self):
        add_type("text/plain",".properties")

def __listDir(self,path):
        try:
            return listdir(path)
        except IOError:
            print ("The directory {0} could not be accessed".format(path))

def getTextFiles(self, path):
        asciiFiles = []
        for files in self.__listDir(path):
            if guess_type(files)[0].split("/")[0] == "text":
                asciiFiles.append(files)
        try:
            return asciiFiles
        except NameError:
            print ("No text files in directory: {0}".format(path))
        finally:
            del asciiFiles

Он находится внутри класса, как вы можете видеть на основе структуры кода. Но вы можете в значительной степени изменить то, что хотите реализовать в своем приложении. Пользоваться им довольно просто. Метод getTextFiles возвращает объект списка со всеми текстовыми файлами, которые находятся в каталоге, который вы передаете в переменной пути.

1
ответ дан 24 November 2019 в 05:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: