Projelerde UTF-8 BOM'lu dosyaları bulma scripti (Python)

Bu konuyu okuyanlar

Ben Kenobi

Dekan
Katılım
6 Kasım 2011
Mesajlar
7,336
Reaksiyon puanı
3,155
Puanları
113
bom.png


Arkadaşlar merhaba.
Birden fazla kişiyle birlikte çalıştığınız projelerde arkadaşlarınızdan herhangi biri güzel güzel editörler durur iken Windows'un Notepad'i ile kodunuzu değiştirir ise bu değiştirilen kod ileride problem çıkarmaya meyillidir. (Özellikle yorumlanan bir dile ait ise)
Bunun nedeni Notepad'in UTF-8 ile enkode edilmiş (Programlama dünyasının en büyük kod encoding standardıdır, byte büyüklüğü değişken olması sebebiyle tercih edilir) dosyaların başına kendi standardı olan BOM bitlerini eklemesidir.
Bu bitler Windows'un herhangi bir topluluk, komite vs kararı olmadan kendi kendine belirlemiş olduğu bir standart olduğu için ve daha da önemlisi işe yaramayan gereksiz bir standart olduğu için (BOM bitleri olmadan da UTF-8 encoding tespit edilebilir ayrıca BOM bitleri UTF-8 ile ANSI arasındaki yüzde yüz uyumluluğa darbe indirir) kimse kullanmamakta ve bu bitlerin varlığı çeşitli yorumlayıcılarda şu an olmasa dahi problem oluşturma potansiyeline sahip olmaktadır.

Bununla ilgili projelerinizde BOM bitleri ile başlayan bir dosya olup olmadığını tespit eden kendimin yazmış olduğu ufak bir Python scriptini sizler ile paylaşmak istedim. Kodu kopyalayıp loglar ile aynı isimde olması için verify_bom.py ismiyle kaydedebilirsiniz. Çalıştırıp çıkan soruya projenizin ana klasörünü yazdığınızda projenizdeki tüm dosyaları analiz edip gerekli bilgilendirmeyi log dosyalarına yazacaktır. (3 farklı çeşit BOM türünü de kontrol etmektedir)

Kod:
import os
import pathlib

log_file_info = open('verify_bom-info.log', mode='w', newline='\n', encoding='utf-8')
log_file_error = open('verify_bom-error.log', mode='w', newline='\n', encoding='utf-8')
log_file_info_no = log_file_info.fileno()
log_file_error_no = log_file_error.fileno()

def print_and_log_info(message):
    print(message)
    log_file_info.write('{}\n'.format(message))
    log_file_info.flush()
    os.fsync(log_file_info_no)

def print_and_log_error(message):
    print(message)
    log_file_error.write('{}\n'.format(message))
    log_file_error.flush()
    os.fsync(log_file_error_no)

location = input('Type location: ')

for any_file_name in pathlib.Path(location).rglob('*'):

    if any_file_name.is_file():
        any_file = any_file_name.open('rb')
        any_file_data = any_file.read(3)
        any_file.close()

        if len(any_file_data) >= 3 and any_file_data[0] == 0xEF and any_file_data[1] == 0xBB and any_file_data[2] == 0xBF:
            print_and_log_error('{} : found BOM UTF-8'.format(any_file_name))
        elif len(any_file_data) >= 2 and any_file_data[0] == 0xFE and any_file_data[1] == 0xFF:
            print_and_log_error('{} : found BOM UCS-2 Endian Big'.format(any_file_name))
        elif len(any_file_data) >= 2 and any_file_data[0] == 0xFF and any_file_data[1] == 0xFE:
            print_and_log_error('{} : found BOM UCS-2 Endian Little'.format(any_file_name))
        else:
            print_and_log_info('{} : not found any kind of BOM'.format(any_file_name))

log_file_info.close()
log_file_error.close()
 
Üst