পাইথনে কোনও ফাইল বাইনারি (অ-পাঠ্য) রয়েছে কিনা তা আমি কীভাবে সনাক্ত করতে পারি?


105

পাইথনে কোনও ফাইল বাইনারি (অ-পাঠ্য) হয় কিনা তা আমি কীভাবে বলতে পারি?

আমি পাইথনে বড় আকারের ফাইলগুলি অনুসন্ধান করছি এবং বাইনারি ফাইলগুলিতে ম্যাচগুলি পেতে থাকি। এটি আউটপুটটিকে অবিশ্বাস্যরকম অগোছালো দেখাচ্ছে।

আমি জানি যে আমি ব্যবহার করতে পারি grep -I, তবে গ্রিপ যা অনুমতি দেয় তার চেয়ে আমি ডেটা দিয়ে আরও বেশি করছি।

অতীতে, আমি কেবলমাত্র এর চেয়ে বড় চরিত্রগুলি অনুসন্ধান করেছি 0x7f, তবে utf8এবং এর মতো আধুনিক সিস্টেমে এটি অসম্ভব করে তুলেছে। আদর্শভাবে সমাধানটি দ্রুত হবে তবে কোনও সমাধান তা করবে।


IF "অতীতে আমি কেবল 0x7f এর চেয়ে বেশি অক্ষরের সন্ধান করতে চাইতাম" আপনি যখন সরল ASCII পাঠ্য নিয়ে কাজ করতেন তখন এখনও কোনও সমস্যা নেই যেহেতু ASCII পাঠ্যটি ইউটিএফ -8 হিসাবে এনকোড থাকে ASCII (যেমন কোনও বাইট> 127) নেই।
tzot

@ ΤΖΩΤΖΙΟΥ: সত্য, তবে আমি জানতে পেরেছি যে আমি যে কয়েকটি ফাইলের সাথে কাজ করছি সেগুলি utf8। আমি এই ফাইলগুলির নির্দিষ্ট অর্থে নয়, সাধারণ অর্থে অভ্যস্ত ছিলাম। :)
শোক

1
শুধুমাত্র সম্ভাবনা সঙ্গে। আপনি যাচাই করতে পারেন: 1) ফাইলটিতে \ n রয়েছে 2) \ n এর মধ্যে বাইটের পরিমাণ তুলনামূলকভাবে ছোট (l এটি নির্ভরযোগ্য নয়) l 3) ফাইল এএসসিসিআই "স্পেস" অক্ষর ('') এর চেয়ে কম মানের সাথে বাইট দেয় না ) - ছাড়াই "। N" "\ r" "\ t" এবং শূন্যগুলি।
সিগটার্ম

3
grepবাইনারি ফাইলগুলি সনাক্ত করতে যে কৌশলটি নিজেই ব্যবহার করে সেগুলি নীচে জর্জে অরপিনেলের পোস্টের মতো । আপনি যদি -zবিকল্পটি সেট না করেন , এটি কেবল "\000"ফাইলের নাল অক্ষর ( ) এর জন্য স্ক্যান করবে । সহ -z, এটি জন্য স্ক্যান "\200"। যারা আগ্রহী এবং / অথবা সংশয়ী তারা 1126 এর লাইন চেক করতে পারেন grep.c। দুঃখিত, আমি উত্স কোড সহ একটি ওয়েবপৃষ্ঠাটি খুঁজে পাইনি, তবে অবশ্যই আপনি এটি gnu.org থেকে বা কোনও ডিস্ট্রোর মাধ্যমে পেতে পারেন ।
অনুভূতি

3
পিএস জোর্সের পোস্টের জন্য মন্তব্য থ্রেডে উল্লিখিত হিসাবে, এই কৌশলটি ফাইলগুলির জন্য মিথ্যা ধনাত্মকতা দেবে, উদাহরণস্বরূপ, ইউটিএফ -16 পাঠ্য। যাইহোক, git diffএবং GNU উভয় diffএকই কৌশল ব্যবহার করে। আমি নিশ্চিত নই যে এটি এতটা প্রচলিত কারণ বিকল্পের চেয়ে এটি এত বেশি দ্রুত এবং সহজ, বা যদি এটি কেবল এই সিস্টেমে ইউটিএফ -১ files ফাইলগুলির আপেক্ষিক বিরলতার কারণে এই ব্যবহারগুলি ইনস্টল করে থাকে।
intuited

উত্তর:


42

আপনি মাইম টাইপ মডিউলটিও ব্যবহার করতে পারেন :

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

বাইনারি মাইম ধরণের তালিকা তৈরি করা মোটামুটি সহজ। উদাহরণস্বরূপ আপাচি একটি মাইম.টাইপস ফাইলের সাথে বিতরণ করে যা আপনি তালিকা, বাইনারি এবং পাঠ্যের একটি সেটে পার্স করতে পারেন এবং তারপরে মাইমটি আপনার পাঠ্য বা বাইনারি তালিকায় রয়েছে কিনা তা পরীক্ষা করে দেখুন।


16
mimetypesকোনও ফাইলের বিষয়বস্তু কেবলমাত্র নামের পরিবর্তে ব্যবহার করার কী উপায় আছে ?
intuited

4
@ ছদ্মবেশী না, তবে লিবারম্যাজিক তা করে। পাইথন-ম্যাজিকের মাধ্যমে এটি ব্যবহার করুন ।
বেঞ্চ

এখানে কিছু ভাল উত্তরের সঙ্গে একটি অনুরূপ প্রশ্ন নেই: stackoverflow.com/questions/1446549/... আমাকে একটি activestate রেসিপি সৌন্দর্য ভাল উপর ভিত্তি করে উত্তর, এটা কিছু মুদ্রণযোগ্য নয় এমন অক্ষরের একটি ছোট অনুপাত (কিন্তু কোন \ 0 অনুমতি দেয়, কারণ)।
স্যাম ওয়াটকিন্স

5
এটি কেবল দুর্দান্ত উত্তর নয় কারণ মাইমটাইপস মডিউলটি সমস্ত ফাইলের পক্ষে ভাল নয়। আমি এখন একটি ফাইল খুঁজছি যা সিস্টেমটি file"ইউটিএফ -8 ইউনিকোড পাঠ্য হিসাবে খুব দীর্ঘ লাইনযুক্ত" হিসাবে রিপোর্ট করে তবে মিমিটাইপস.জেস্ট_ টাইপ () ফিরে আসবে (কিছুই নয়, কিছুই নয়)। এছাড়াও, অ্যাপাচি এর মাইমটাইপ তালিকাটি একটি শ্বেত তালিকা / সাবসেট। এটি কোনওভাবেই মাইমটাইপগুলির সম্পূর্ণ তালিকা নয়। এটি সমস্ত ফাইলকে পাঠ্য বা অ-পাঠ্য হিসাবে শ্রেণিবদ্ধ করতে ব্যবহার করা যায় না।
22-221 তে পুনর্েলল

1
অনুমান_প্রকারগুলি ফাইলের নাম এক্সটেনশনের উপর ভিত্তি করে তৈরি করা হয়, ইউনিক্স কমান্ড "ফাইল" এর মতো আসল সামগ্রী নয়।
এরিক এইচ।

61

ফাইলের (1) আচরণের ভিত্তিতে অন্য একটি পদ্ধতি :

>>> textchars = bytearray({7,8,9,10,12,13,27} | set(range(0x20, 0x100)) - {0x7f})
>>> is_binary_string = lambda bytes: bool(bytes.translate(None, textchars))

উদাহরণ:

>>> is_binary_string(open('/usr/bin/python', 'rb').read(1024))
True
>>> is_binary_string(open('/usr/bin/dh_python3', 'rb').read(1024))
False

মিথ্যা ধনাত্মক এবং মিথ্যা নেতিবাচক উভয়ই পেতে পারে তবে তবুও এটি একটি চতুর পন্থা যা প্রচুর পরিমাণে ফাইলের জন্য কাজ করে। +1 টি।
স্পেকট্রা

2
আকর্ষণীয়ভাবে যথেষ্ট, ফাইল (1) নিজেই 0x7f কেও বিবেচনা থেকে বাদ দেয়, তাই প্রযুক্তিগতভাবে বলতে গেলে আপনার bytearray([7,8,9,10,12,13,27]) + bytearray(range(0x20, 0x7f)) + bytearray(range(0x80, 0x100))পরিবর্তে ব্যবহার করা উচিত । দেখুন পাইথন, ফাইল (1) - কেন সংখ্যার [7,8,9,10,12,13,27] এবং পরিসীমা (0x20, 0x100) বনাম বাইনারি ফাইল টেক্সট নির্ধারণের জন্য ব্যবহার করা হয় এবং github.com/file/file/ ব্লব /…
মার্টিজন পিটারস

@ মার্তিজ্নপিটারস: আপনাকে ধন্যবাদ আমি বাদ দিয়ে উত্তর আপডেট করেছি 0x7f( DEL)।
jfs

1
সেট ব্যবহার করে দুর্দান্ত সমাধান :-)
মার্টিজন পিটারস

আপনি বাদ 11বা কেন VT? সারণীতে 11 টি সরল ASCII পাঠ্য হিসাবে বিবেচনা করা হয়, এবং এটি vertical tab
darksky

15

আপনি যদি পাইথন 3 ব্যবহার করে ইউটিএফ -8 দিয়ে এটি সরাসরি এগিয়ে চলেছেন, কেবল ফাইলটি পাঠ্য মোডে খুলুন এবং আপনি যদি এটি পান তবে প্রক্রিয়াজাতকরণ বন্ধ করুন UnicodeDecodeError। টেক্সট মোডে (এবং বাইনারি মোডে বাইটারি) ফাইলগুলি হ্যান্ডেল করার সময় পাইথন 3 ইউনিকোড ব্যবহার করবে - যদি আপনার এনকোডিং স্বেচ্ছাসেবী ফাইলগুলি ডিকোড করতে না পারে তবে সম্ভবত এটি পাবেন UnicodeDecodeError

উদাহরণ:

try:
    with open(filename, "r") as f:
        for l in f:
             process_line(l)
except UnicodeDecodeError:
    pass # Fond non-text data

with open(filename, 'r', encoding='utf-8') as fসরাসরি ব্যবহার করছেন না কেন ?
টেরি

8

যদি এটি সহায়তা করে তবে অনেকগুলি বাইনারি ধরণের যাদুসংখ্যার সাথে শুরু হয়। ফাইল স্বাক্ষরের একটি তালিকা এখানে


এটিই লিবারমজিক। পাইথন-ম্যাজিকের মাধ্যমে অজগরটিতে এটি অ্যাক্সেস করা যায় ।
বেংট

2
দুর্ভাগ্যক্রমে, "একটি পরিচিত যাদু নম্বর দিয়ে শুরু হয় না" "এটি একটি পাঠ্য ফাইল" এর সমান নয়।
22-22 তে পুনরেল

8

এটা চেষ্টা কর:

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

9
-1 "বাইনারি" শূন্য বাইট সমন্বিত হিসাবে সংজ্ঞায়িত করে। UTF-16- এনকোডযুক্ত পাঠ্য ফাইলগুলিকে "বাইনারি" হিসাবে শ্রেণিবদ্ধ করবে।
জন মাচিন

5
@ জন মেশিন: মজার বিষয় হল, git diffআসলে এইভাবে কাজ করে এবং যথেষ্ট নিশ্চিত এটি ইউটিএফ -১-ফাইলগুলিকে বাইনারি হিসাবে সনাক্ত করে।
13:56

হুনহ .. জিএনইউও diffএইভাবে কাজ করে। এটিতে ইউটিএফ -16 ফাইলগুলির সাথে একই রকম সমস্যা রয়েছে। fileUTF-16 পাঠ্যের মতো একই ফাইলগুলি সঠিকভাবে সনাক্ত করে। আমি grepএর কোড পরীক্ষা করে দেখিনি , তবে এটি ইউটিএফ -16 ফাইলগুলি বাইনারি হিসাবে সনাক্ত করে।
13:57

1
+1 @ জন ম্যাকিন: ইউটিএফ -16 হ'ল একটি চরিত্রের তথ্য file(1)যা রূপান্তর ছাড়াই মুদ্রণ করা নিরাপদ নয় সুতরাং এই পদ্ধতিটি এই ক্ষেত্রে উপযুক্ত।
jfs

2
-1 - আমি মনে করি না 'শূন্য বাইট রয়েছে' বাইনারি বনাম পাঠ্যের জন্য পর্যাপ্ত পরীক্ষা, উদাহরণস্বরূপ আমি সমস্ত 0x01 বাইট সমন্বিত একটি ফাইল তৈরি করতে পারি বা 0xDEADBEEF পুনরাবৃত্তি করতে পারি, তবে এটি কোনও পাঠ্য ফাইল নয়। ফাইলের ভিত্তিতে উত্তর (1) আরও ভাল।
স্যাম ওয়াটকিন্স

6

এখানে একটি পরামর্শ যা ইউনিক্স ফাইল কমান্ড ব্যবহার করে :

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)

ব্যবহারের উদাহরণ:

>>> আইটেক্সট ('/ ইত্যাদি / মোটিড') 
সত্য
>>> আইটেক্সট ('/ ভিএমলিনুজ') 
মিথ্যা
>>> খোলা ('/ টিএমপি / জাপানি') 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 '
>>> আইটেক্সট ('/ টিএমপি / জাপানি') # ইউটিএফ -8 এ কাজ করে
সত্য

এটিতে উইন্ডোজে পোর্টেবল না হওয়ার ডাউনসাইড রয়েছে (যদি আপনার কাছে fileকমান্ডের মতো কিছু না থাকে), এবং প্রতিটি ফাইলের জন্য একটি বাহ্যিক প্রক্রিয়া তৈরি করতে হবে, যা আপত্তিজনক হতে পারে না।


এটি আমার স্ক্রিপ্টটি ভেঙে দিয়েছে :( তদন্ত করে, আমি জানতে পেরেছি যে কিছু পাঠককে file" সেন্ডমেল হিমায়িত কনফিগারেশন - সংস্করণ এম" হিসাবে বর্ণনা করা হয়েছে — "টেক্সট" স্ট্রিংয়ের অনুপস্থিতি উল্লেখ করুন use সম্ভবত ব্যবহার করবেন file -i?
মেলিসা_বাইকো

1
TypeError: একটি অবজেক্টকে বাইট মত একটি স্ট্রিং প্যাটার্ন ব্যবহার করতে পারবেন না
Abg

5

বাইনারিওরনট লাইব্রেরি ( গিটহাব ) ব্যবহার করুন ।

এটি খুব সহজ এবং এই স্ট্যাকওভারফ্লো প্রশ্নটিতে পাওয়া কোডের ভিত্তিতে।

আপনি কোডের 2 লাইনে এটি লিখতে পারেন, তবে এই প্যাকেজটি আপনাকে সমস্ত ধরণের অদ্ভুত ফাইল প্রকারের, ক্রস প্ল্যাটফর্মের সাথে 2 লাইনের কোডের লিখন এবং ভালভাবে পরীক্ষা করতে বাঁচায়।


4

সাধারণত আপনার অনুমান করতে হবে।

আপনি যদি এক্সটেনশানগুলিকে এক ক্লু হিসাবে দেখতে পারেন তবে ফাইলগুলি সেগুলিতে থাকে।

আপনি বাইনারি ফর্ম্যাটগুলিও চিনতে পারেন এবং সেগুলি এড়িয়ে যান।

অন্যথায় প্রিন্টযোগ্য এএসসিআইআই বাইটগুলির অনুপাত দেখুন এবং সেখান থেকে অনুমান করুন।

আপনি ইউটিএফ -8 থেকে ডিকোডিংয়ের চেষ্টা করতে পারেন এবং দেখুন যে এটি বুদ্ধিমান আউটপুট উত্পাদন করে।


4

একটি ইউটিএফ -16 সতর্কতা সহ একটি সংক্ষিপ্ত সমাধান:

def is_binary(filename):
    """ 
    Return true if the given filename appears to be binary.
    File is considered to be binary if it contains a NULL byte.
    FIXME: This approach incorrectly reports UTF-16 as binary.
    """
    with open(filename, 'rb') as f:
        for block in f:
            if b'\0' in block:
                return True
    return False

দ্রষ্টব্য: সন্ধান for line in fileনা b'\n'পাওয়া পর্যন্ত সীমাহীন পরিমাণের মেমরি গ্রাস করতে পারে
jfs

@Community হবে: ".read()"ফেরৎ একটি এখানে bytestring যে হয় iterable (এটা পৃথক বাইট উৎপাদ)।
jfs

4

কোনও ফাইল বাইনারি কিনা তা পরীক্ষা করার জন্য আমরা অজগরটি নিজেই ব্যবহার করতে পারি, কারণ যদি আমরা পাঠ্য মোডে বাইনারি ফাইল খোলার চেষ্টা করি তবে এটি ব্যর্থ হয়

def is_binary(file_name):
    try:
        with open(file_name, 'tr') as check_file:  # try open file in text mode
            check_file.read()
            return False
    except:  # if fail then file is non-text (binary)
        return True

এটি প্রচুর `.avi (ভিডিও) ফাইলের জন্য ব্যর্থ।
আনমল সিং জাগি

3

আপনি যদি উইন্ডোজে না থাকেন তবে আপনি ফাইল টাইপ নির্ধারণ করতে পাইথন ম্যাজিক ব্যবহার করতে পারেন । তারপরে আপনি এটি কোনও পাঠ্য / মাইম ধরণের কিনা তা পরীক্ষা করতে পারেন।


2

এখানে একটি ফাংশন রয়েছে যা ফাইলটি কোনও বিওএম দিয়ে শুরু হয় কিনা এবং প্রাথমিক 8192 বাইটের মধ্যে শূন্য বাইটের সন্ধান না করে তা পরীক্ষা করে দেখুন:

import codecs


#: BOMs to indicate that a file is a text file even if it contains zero bytes.
_TEXT_BOMS = (
    codecs.BOM_UTF16_BE,
    codecs.BOM_UTF16_LE,
    codecs.BOM_UTF32_BE,
    codecs.BOM_UTF32_LE,
    codecs.BOM_UTF8,
)


def is_binary_file(source_path):
    with open(source_path, 'rb') as source_file:
        initial_bytes = source_file.read(8192)
    return not any(initial_bytes.startswith(bom) for bom in _TEXT_BOMS) \
           and b'\0' in initial_bytes

প্রযুক্তিগতভাবে ইউটিএফ -8 বিওএমের জন্য চেক অপ্রয়োজনীয় কারণ এতে সমস্ত ব্যবহারিক উদ্দেশ্যে জিরো বাইট থাকা উচিত নয়। তবে এটি খুব সাধারণ এনকোডিং হওয়ায় 0 এর জন্য সমস্ত 8192 বাইট স্ক্যান করার পরিবর্তে শুরুতে বিওএমের জন্য চেক করা দ্রুত।


2

বর্তমানে রক্ষিত অজগর-যাদু ব্যবহার করার চেষ্টা করুন যা @ কামি কিসিয়েলের উত্তরে একই মডিউল নয়। এটি উইন্ডোজ সহ সমস্ত প্ল্যাটফর্ম সমর্থন করে তবে আপনার প্রয়োজন হবেlibmagic বাইনারি ফাইলগুলির । এটি README এ ব্যাখ্যা করা হয়েছে।

মাইমটাইপস মডিউলটির বিপরীতে , এটি ফাইলটির এক্সটেনশন ব্যবহার করে না এবং পরিবর্তে ফাইলের সামগ্রীগুলি পরীক্ষা করে।

>>> import magic
>>> magic.from_file("testdata/test.pdf", mime=True)
'application/pdf'
>>> magic.from_file("testdata/test.pdf")
'PDF document, version 1.2'
>>> magic.from_buffer(open("testdata/test.pdf").read(1024))
'PDF document, version 1.2'

1

আমি ঠিক একই জিনিসটির জন্য এখানে এসেছি - বাইনারি বা পাঠ্য সনাক্ত করার জন্য স্ট্যান্ডার্ড লাইব্রেরি দ্বারা সরবরাহ করা একটি বিস্তৃত সমাধান। লোকেরা প্রস্তাবিত বিকল্পগুলি পর্যালোচনা করার পরে, নিক্স ফাইল কমান্ডটি সেরা পছন্দ বলে মনে হচ্ছে (আমি কেবল লিনাক্স বক্সেনের জন্য বিকাশ করছি)। অন্য কেউ কেউ ফাইল ব্যবহার করে সমাধান পোস্ট করেছেন তবে তারা আমার মতে অযৌক্তিকভাবে জটিল, তাই আমি এখানে যা এলাম তা এখানে:

def test_file_isbinary(filename):
    cmd = shlex.split("file -b -e soft '{}'".format(filename))
    if subprocess.check_output(cmd)[:4] in {'ASCI', 'UTF-'}:
        return False
    return True

এটি বলার অপেক্ষা রাখে না, তবে আপনার কোড যা এই ফাংশনটিকে কল করে তা পরীক্ষা করার আগে আপনি কোনও ফাইলটি পড়তে পারেন তা নিশ্চিত করা উচিত, অন্যথায় এটি ভুলভাবে ফাইলটিকে বাইনারি হিসাবে সনাক্ত করা হবে।


1

আমার অনুমান যে অনুমান_প্রকার ফাংশনটি ব্যবহার করা সবচেয়ে ভাল সমাধান। এটি বেশ কয়েকটি মাইম টাইপ সহ একটি তালিকা ধারণ করে এবং আপনি নিজের ধরণেরও অন্তর্ভুক্ত করতে পারেন। আমার সমস্যা সমাধানের জন্য আমি যে স্ক্রিপ্টটি করেছি তা এখানে আসুন:

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

* এনআইএক্স-এ:

fileশেল-কমান্ডে আপনার অ্যাক্সেস থাকলে শ্লেক্স সাব-প্রসেস মডিউলটিকে আরও ব্যবহারযোগ্য করে তুলতে সহায়তা করতে পারে:

from os.path import realpath
from subprocess import check_output
from shlex import split

filepath = realpath('rel/or/abs/path/to/file')
assert 'ascii' in check_output(split('file {}'.format(filepth).lower()))

অথবা, আপনি বর্তমান ডিয়ারের সমস্ত ফাইলের আউটপুট পেতে একটি লুপে এটি আটকে রাখতে পারেন:

import os
for afile in [x for x in os.listdir('.') if os.path.isfile(x)]:
    assert 'ascii' in check_output(split('file {}'.format(afile).lower()))

বা সকল সাবডায়ারদের জন্য:

for curdir, filelist in zip(os.walk('.')[0], os.walk('.')[2]):
     for afile in filelist:
         assert 'ascii' in check_output(split('file {}'.format(afile).lower()))

1

প্রোগ্রামগুলির বেশিরভাগই ফাইলটিকে বাইনারি হিসাবে বিবেচনা করে (যা কোনও ফাইল যা "লাইন-ভিত্তিক" নয়) যদি এতে একটি নাল বর্ণ থাকে

পাইথনে পার্লের pp_fttext()( pp_sys.c) সংস্করণটি প্রয়োগ করা হয়েছে:

import sys
PY3 = sys.version_info[0] == 3

# A function that takes an integer in the 8-bit range and returns
# a single-character byte object in py3 / a single-character string
# in py2.
#
int2byte = (lambda x: bytes((x,))) if PY3 else chr

_text_characters = (
        b''.join(int2byte(i) for i in range(32, 127)) +
        b'\n\r\t\f\b')

def istextfile(fileobj, blocksize=512):
    """ Uses heuristics to guess whether the given file is text or binary,
        by reading a single block of bytes from the file.
        If more than 30% of the chars in the block are non-text, or there
        are NUL ('\x00') bytes in the block, assume this is a binary file.
    """
    block = fileobj.read(blocksize)
    if b'\x00' in block:
        # Files with null bytes are binary
        return False
    elif not block:
        # An empty file is considered a valid text file
        return True

    # Use translate's 'deletechars' argument to efficiently remove all
    # occurrences of _text_characters from the block
    nontext = block.translate(None, _text_characters)
    return float(len(nontext)) / len(block) <= 0.30

আরও লক্ষ করুন যে এই কোডটি পাইথন 2 এবং পাইথন 3 উভয়ই পরিবর্তন ছাড়াই চালানোর জন্য লেখা হয়েছিল।

উত্স: পাইথনে প্রয়োগ করা পার্লের "যদি ফাইলটি পাঠ্য বা বাইনারি হয় তবে অনুমান" implemented


0

আপনি কি ইউনিক্সে আছেন? যদি তা হয় তবে চেষ্টা করুন:

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

শেল রিটার্ন মানগুলি উল্টানো হয় (0 ঠিক আছে, সুতরাং এটি যদি "পাঠ্য" সন্ধান করে তবে এটি 0 প্রদান করে এবং পাইথনে এটি একটি মিথ্যা অভিব্যক্তি)।


রেফারেন্সের জন্য, ফাইল কমান্ড ফাইলের সামগ্রীর উপর ভিত্তি করে একটি প্রকার অনুমান করে। এটি ফাইল এক্সটেনশনে কোনও মনোযোগ দেয় কিনা তা আমি নিশ্চিত নই।
ডেভিড জেড

আমি প্রায় নিশ্চিত এটি সামগ্রী এবং এক্সটেনশন উভয়ই দেখায়।
ফোরট্রান

পাথটিতে "পাঠ্য" থাকলে এটি ভাঙবে। শেষ ':' এ প্লাস্টিকের বিষয়টি নিশ্চিত করুন (ফাইলের ধরণের বিবরণে কোনও কোলন নেই)।
অ্যালান বরই 18

3
স্যুইচ fileসহ ব্যবহার করুন -b; এটি পাথ ছাড়াই কেবল ফাইল টাইপ প্রিন্ট করবে।
দুবেক

2
একটি সামান্য সুন্দর সংস্করণ:is_binary_file = lambda filename: "text" in subprocess.check_output(["file", "-b", filename])
jfs

0

সরল উপায় হ'ল ফাইলটি অপারেটর \x00ব্যবহার করে নুল বর্ণ ( ) অন্তর্ভুক্ত করে কিনা তা পরীক্ষা করে দেখুন in:

b'\x00' in open("foo.bar", 'rb').read()

সম্পূর্ণ উদাহরণ নীচে দেখুন:

#!/usr/bin/env python3
import argparse
if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('file', nargs=1)
    args = parser.parse_args()
    with open(args.file[0], 'rb') as f:
        if b'\x00' in f.read():
            print('The file is binary!')
        else:
            print('The file is not binary!')

নমুনা ব্যবহার:

$ ./is_binary.py /etc/hosts
The file is not binary!
$ ./is_binary.py `which which`
The file is binary!

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.