Bir dosyanın POSIX tarafından tanımlandığı şekilde bir metin dosyası olması için hangi koşullar yerine getirilmelidir?


22

POSIX bir metin dosyasını şu şekilde tanımlar:

Sıfır veya daha fazla satırda düzenlenmiş karakterleri içeren bir dosya. Satırlar NUL karakteri içermez ve hiçbiri <newline> karakteri dahil olmak üzere {LINE_MAX} bayt uzunluğunu aşamaz. POSIX.1-2017, metin dosyaları ve ikili dosyalar arasında ayrım yapmamasına rağmen (ISO C standardına bakın), çoğu yardımcı program yalnızca metin dosyaları üzerinde çalışırken öngörülebilir veya anlamlı çıktılar üretir. Bu tür kısıtlamaları olan standart yardımcı programlar her zaman STDIN veya INPUT FILES bölümlerinde "metin dosyaları" belirtir.

Kaynak: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_403

Ancak belirsiz bulduğum birkaç şey var:

  1. Bir metin dosyası normal bir dosya mı olmalı? Yukarıdaki alıntıda açıkça, dosyanın normal bir dosya olması gerektiğini söylemez

  2. Bir karakter yalnızca bir karakter ve yalnızca bir karakter içeriyorsa bir dosya olarak kabul edilebilir mi (yani, yeni bir satırla sonlandırılmayan tek bir karakter)? Bu sorunun nitpicky kulağa geldiğini biliyorum, ancak "bir veya daha fazla karakter" yerine "karakter" kelimesini kullanıyorlar. Diğerleri aynı fikirde olmayabilir, ancak "bir veya daha fazla karakter" anlamına geliyorlarsa açıkça söylemeleri gerektiğini düşünüyorum

  3. Yukarıdaki alıntıda, "çizgiler" e atıfta bulunur. "Boş Satır", "Ekran Satırı", "Eksik Satır" ve "Satır" adında satırlı dört tanım buldum. "Boş", "Ekran" ve "Tamamlanmadı" eksikliklerinden dolayı "Satır" anlamına geldiği ya da yukarıdaki alıntıda yer alan bu tanımların dördü mü?

Bu metin bloğundan sonra gelen tüm sorular, "karakterlerin" "bir veya daha fazla karakter" anlamına geldiğine göre değişir:

  1. Bir dosya boşsa, bir veya daha fazla karakter içermediğinden dolayı bir metin dosyası olmadığını güvenle söyleyebilir miyim?

Bu metin bloğundan sonra gelen tüm sorular, yukarıdaki alıntıda, bir satırın bir "Satır" olarak tanımlandığına ve adlarında "Satır" ı içeren diğer üç tanımın dışlanması gerektiği sonucuna dayanır:

  1. "Sıfır veya daha fazla satırlardaki" "sıfır", bir dosyanın newline ile sonlandırılmayan bir veya daha fazla karakter içeriyorsa, hala bir metin dosyası olarak kabul edilebileceği anlamına mı geliyor?

  2. "Sıfır veya daha fazla satır", tek bir "Satır" (0 veya daha fazla karakter artı sonlanan bir yeni satır) devreye girdiğinde, son satırın "Tamamlanmamış Satır" (bir veya daha fazla olmayan) olması yasa dışı kaldığı anlamına mı geliyor? dosyanın sonunda yeni satır karakterleri)?

  3. "None [no line]" satırsonu karakteri de dahil olmak üzere {LINE_MAX} bayt uzunluğunu geçebilir mi "anlamına gelir", bir metin dosyasındaki herhangi bir "Satır" da izin verilen karakter sayısında bir sınırlama olduğu anlamına gelir (bir kenara, değer Ubuntu 18.04 ve FreeBSD 11.1'deki LINE_MAX "2048" olur?


Güzel soru Harold! Terminolojinin harika bir tartışmasını yapar. Soruyu ekstra sürelerden vazgeçebilmeyi isterdim
Sergiy Kolodyazhnyy

Yanıtlar:


23
  1. Bir metin dosyası normal bir dosya mı olmalı? Yukarıdaki alıntıda açıkça, dosyanın normal bir dosya olması gerektiğini söylemez

    Yok hayır; alıntı, hatta standart girdiyi potansiyel bir metin dosyası olarak not eder. Gibi diğer standart programları, make, özellikle kullanmak karakter özel bir dosya /dev/null bir metin dosyası olarak .

  2. Bir karakter yalnızca bir karakter ve yalnızca bir karakter içeriyorsa bir dosya olarak kabul edilebilir mi (yani, yeni bir satırla sonlandırılmayan tek bir karakter)?

    Bu karakter bir <newline> olmalı veya bu bir çizgi değil , yani içinde bulunduğu dosya bir metin dosyası değil. Tam olarak bayt 0A içeren bir dosya, tek satırlık bir metin dosyasıdır. Boş bir satır geçerli bir satırdır.

  3. Yukarıdaki alıntıda, "çizgiler" e atıfta bulunur. "Boş Satır", "Ekran Satırı", "Eksik Satır" ve "Satır" adında satırlı dört tanım buldum. "Boş", "Ekran" ve "Tamamlanmadı" ihmali nedeniyle "Satır" anlamına geldiği sonucuna varmalı mıyım?

    Bu gerçekten bir çıkarım değil, sadece söylediği. "Satır" kelimesine bağlamsal olarak uygun bir tanım verilmiştir ve bu yüzden bahsettiği şey budur.

  4. Bir dosya boşsa, bir veya daha fazla karakter içermediğinden dolayı bir metin dosyası olmadığını güvenle söyleyebilir miyim?

    Boş bir dosya sıfır (veya daha fazla) satırdan oluşur ve bu nedenle bir metin dosyasıdır.

  5. "Sıfır veya daha fazla satırlardaki" "sıfır", bir dosyanın newline ile sonlandırılmayan bir veya daha fazla karakter içeriyorsa, hala bir metin dosyası olarak kabul edilebileceği anlamına mı geliyor?

    Hayır, bu karakterler satırlar halinde düzenlenmemiş.

  6. "Sıfır veya daha fazla satır", tek bir "Satır" (0 veya daha fazla karakter artı sonlanan bir yeni satır) devreye girdiğinde, son satırın "Tamamlanmamış Satır" (bir veya daha fazla olmayan) olması yasa dışı kaldığı anlamına mı geliyor? dosyanın sonunda yeni satır karakterleri)?

    Bu yasadışı değil , sadece bir metin dosyası değil. Bir metin dosyası gerektiren bir yarar o verilecek olabilir yerine bu dosyayı verilirse olumsuz davranır.

  7. "None [no line]" satırsonu karakteri de dahil olmak üzere {LINE_MAX} bayttan uzun olabilir, "metin dosyasında herhangi bir" Satır "da izin verilen karakter sayısında bir sınırlama olduğu anlamına gelir

    Evet.

Bu tanım, yalnızca metin tabanlı bir yardımcı programın ( örneğingrep ) kesinlikle kabul edeceği bazı sınırlar koymaya çalışıyor - başka bir şey değil. Ayrıca işleri daha liberal bir şekilde kabul etmekte özgürler ve pratikte sık sık yapıyorlar. Bir çizgiyi işlemek için sabit boyutlu bir tampon kullanmaları, bir dolgunun dolmadan yeni bir satır görünmesini sağlamak için izin verilir, vb. Çok fazla şeyler okuyor olabilirsiniz.


1
2. noktadan emin misin? Standart açıkça " 0 veya daha fazla satır" belirtir . Böylece printf "a" > filebu tanıma göre bir metin dosyası oluşturabilir. 4 numaralı cevabınız, 2 ve 5'e verdiğiniz cevaplarla çelişiyor gibi görünmektedir, ancak bunu yapmazken touch filebir metin dosyası oluşturduğunuza göre printf "a" > file.
terdon

4
@ terdon: Michael'ın cevabında herhangi bir çelişki görmüyorum. Temel olarak, bir POSIX metin dosyasının, içeriği yeni bir çizgiyle eşleşen ve yeni bir satır olmayan herhangi bir karakterle eşleşen ve sayısal değer için bir yer tutucunun (.{0,M}\n)*bulunduğu , regexp ile eşleştirilen (dolaylı olarak bağlantılı ve her iki uçtaki) herhangi bir dosya olduğunu söylüyor gibi görünüyor. LINE_MAX-1. Bu, boş bir dosyanın sıfır satırdan oluşan geçerli bir metin dosyası olduğunu, ancak boş olmayan herhangi bir metin dosyasının yeni bir satırda bitmesi gerektiğini belirtir (aksi halde eksik bir satır içerecektir ve tamamlanmamış bir satır bir satır değildir) ). \n.M
Ilmari Karonen

@Michael Homer Düzenli dosya işiyle ilgili olarak, / dev / null dışında başka örnekler var mı? Bir veya daha fazla boş karakter içerdiğinden, aslında bir metin dosyası değil.
Harold Fischer

1
@HaroldFischer /dev/nullboş bir dosyadır. Düşünüyorsun /dev/zero.
Michael Homer

@HaroldFischer, hayır, /dev/nullokuduğunuzda hiçbir veri alamadığınız gibi boş okur. Burada normal olmayan dosyaları düşünmenin pek bir anlamı olmadığından emin değilim, çünkü pek çoğu doğada dinamik. Bu, temelde yalnızca diğer bazı varlıklara / diğer varlıklardan ara yüzleri taşıyan boruları, soketleri, char aygıtlarını içerir. Herhangi bir statik veri kümesine sahip değiller, bu nedenle dosyanın özellikleri yerine, aktarılan verilerin özelliklerini göz önünde bulundurmak daha mantıklı olur .
ilkkachu

7

POSIX tarafından tanımlandığı gibi:

Evet, bir metin dosyası (temel olarak):

Sıfır veya daha fazla satırda düzenlenmiş karakterleri içeren bir dosya.

Bu tanımları da dahil etmek faydalı olacaktır:

3.92 Karakteri Dize

İlk boş bayt tarafından sonlandırılan ve sonlandırılan bitişik karakter dizisi.

3.195 Eksik Hat

Dosyanın sonundaki bir veya daha fazla <yeni satır dışı> karakter dizisi.

3.206 Satır

Sıfır veya daha fazla <newline> karakter dizisi artı bir son <newline> karakter dizisi.

3.243 Newline Karakteri (<newline>)

Çıktı akışında yazdırmanın bir sonraki satırın başında başlaması gerektiğini belirten bir karakter. C dilinde '\ n' ile gösterilen karakter. Bir sonraki satıra geçişi gerçekleştirmek için bu karakterin sistem tarafından bir çıkış cihazına iletilen tam dizinin olup olmadığı belirtilmez.

3.247 NUL

Tüm bitleri sıfıra ayarlanmış bir karakter.

Bir "Metin Dosyası" hükmü Not değil NUL içeriyor bayt.


Yani:

  1. Bir metin dosyası normal bir dosya mı olmalı?
    Hayır, olması gerekmez. Bir "metin dosyası", okurken ne içerdiğine göre tanımlanır. Bir dosya "sıfır veya daha fazla satır" içeriyorsa, bir metin dosyasıdır. Bazı dosyalar/dev/stdin bir daha okunduğunda değil, bir kerede okunursa bir metin dosyası içerebilir.
  2. Bir karakter yalnızca bir karakter içeriyorsa, dosya metin dosyası olarak kabul edilebilir mi…?
    Hayır, bu tamamlanmamış bir satır (3.195).
    Bir metin dosyası sadece "Eksik Satırlar" içermelidir.
  3. Onların "Çizgi" demek istediklerini mi söylemeliyim…?
    Evet yapmalısın.
  4. Bir dosya boşsa, bunun bir metin dosyası olmadığını güvenle söyleyebilir miyim?
    Hayır, boş bir dosya (sıfır karakter) geçerli bir "metin dosyası" dır.
    Yukarıdan: … sıfır veya daha fazla satır… . Sıfır satırları (sıfır karakter) geçerli bir "Metin dosyası" dır.
  5. … Newline ile sonlandırılmayan bir veya daha fazla karakter içeriyorsa, bir metin dosyası olarak kabul edilir.
    Hayır, "Eksik Satır" değil (teknik olarak) geçerli bir "satır" değil.
  6. "Sıfır ya da daha fazla satırda" "sıfır", bir dosyanın newline ile sonlandırılmayan bir veya daha fazla karakter içeriyorsa, hala bir metin dosyası olarak kabul edilebileceği anlamına mı geliyor?
    Hayır, tamamlanmamış bir satır "Satır" değil. Bir metin dosyasının tamamlanmamış satırları olmamalıdır .

  7. … Bir metin dosyasındaki herhangi bir “Satır” da izin verilen karakter sayısında bir sınırlama var mı?
    Evet, geçerli bir "metin dosyasının" herhangi bir satırında {LINE_MAX} bayttan (karakterlerin aksine) daha fazlasına izin verilmeyecektir.
    {LINE_MAX} değeri <limi.h> dosyasında verilir
    (ayrıca C? De Algılanabilir satır arabelleği boyutunu oku ? ):

    {LINE_MAX}
    Aksi belirtilmediği sürece, yardımcı program metin dosyaları işleme olarak tanımlandığında, yardımcı programın giriş satırının (standart giriş veya başka bir dosya) bayt cinsinden maksimum uzunluğu. Uzunluk takip için yer içerir.
    Minimum Kabul Edilebilir Değer: {_POSIX2_LINE_MAX}

    GNU tabanlı bir sistem için belirlenmiş limit yoktur (bellek hariç) :

    Makro: int LINE_MAX
    Metin odaklı POSIX.2 yardımcı programlarının destekleyebileceği en büyük metin satırı. (Bu yardımcı programların GNU sürümlerini kullanıyorsanız, kullanılabilir sanal belleğin getirdiği durum dışında gerçek bir sınır yoktur, ancak kütüphanenin size bunu söyleyebilmesinin imkânı yoktur.)

    posix_lim.h2048 olarak tanımlandı (en az 64 bit linux GNU sistemleri için):

    $ grep -ri 'POSIX2_LINE_MAX' /usr/include/ 
    
    /usr/include/x86_64-linux-gnu/bits/xopen_lim.h:#define NL_LANGMAX       _POSIX2_LINE_MAX
    /usr/include/x86_64-linux-gnu/bits/posix2_lim.h:#define _POSIX2_LINE_MAX                2048
    /usr/include/x86_64-linux-gnu/bits/posix2_lim.h:#define LINE_MAX                _POSIX2_LINE_MAX
    

    POSIX yardımcı programı getconf kullanılarak da bulunabilir :

    $ getconf LINE_MAX
    2048
    

İlgili: Metin dosyaları neden yeni bir satırla bitmeli?


2
Bu cevap çoğunlukla doğru, ancak “bir metin dosyası normal bir dosya olmalı” doğru cevaptır hayır . Her türlü dosya bir metin dosyası olabilir, bu bir içerik meselesi, dosya tipi alakasız. Yardımcı fileprogram yalnızca özel dosyalar için dosya türünü bildirir, ancak yardımcı programın özel bir dosyanın dosya içeriğindeki sezgiselliğini görmek için çalışma, kullanım file - <…veya (Linux) file -s …. Özel bir dosya her açışınızda farklı içeriklere sahip olabilir, bu yüzden her zaman bir metin dosyası olabilir veya olabilir. /dev/nulliçeriği her zaman bir metin dosyası olduğundan her zaman bir metin dosyasıdır.
Gilles 'SO- kötülük'

1
grepDosyaları kullanmak yerine , getconfsisteme özgü değerleri elde etmek için kullanabilirsiniz , örneğin getconf LINE_MAXbu arada sistemimde 2048 (bayt) döner (Ubuntu 16.04).
heemayl

Değişkenin tanımlandığı dosyayı bulmak istedim, bu yüzden grep gerekliydi ve işi yaptı (oldukça hızlı). Ancak evet, getconfconfig'in mevcut değerini okumayı sağlar.
Isaac,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.