Quali condizioni devono essere soddisfatte affinché un file sia un file di testo come definito da POSIX?


22

POSIX definisce un file di testo come:

Un file che contiene caratteri organizzati in zero o più righe. Le righe non contengono caratteri NUL e nessuna può superare i {LINE_MAX} byte di lunghezza, incluso il carattere <newline>. Sebbene POSIX.1-2017 non distingua tra file di testo e file binari (vedere lo standard ISO C), molte utility producono output prevedibili o significativi solo quando si opera su file di testo. Le utility standard che hanno tali restrizioni specificano sempre "file di testo" nelle loro sezioni STDIN o INPUT FILES.

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

Tuttavia, ci sono diverse cose che trovo poco chiare:

  1. Un file di testo deve essere un file normale? Nell'estratto sopra non si dice esplicitamente che il file deve essere un file normale

  2. Un file può essere considerato un file di testo se contiene un solo carattere e un solo carattere (ovvero un singolo carattere che non termina con una nuova riga)? So che questa domanda può sembrare nitida, ma usano la parola "caratteri" invece di "uno o più caratteri". Altri potrebbero non essere d'accordo, ma se significano "uno o più personaggi" penso che dovrebbero dirlo esplicitamente

  3. Nell'estratto sopra riportato, fa riferimento a "linee". Ho trovato quattro definizioni con la riga nel loro nome: "Linea vuota", "Linea di visualizzazione", "Linea incompleta" e "Linea". Devo dedurre che significano "Linea" a causa della loro omissione di "Vuoto", "Display" e "Incomplete" - oppure tutte e quattro queste definizioni sono considerate una riga nell'esempio sopra?

Tutte le domande che seguono questo blocco di testo dipendono dall'ipotesi che "caratteri" significhi "uno o più caratteri":

  1. Posso dedurre con sicurezza che se un file è vuoto, non è un file di testo perché non contiene uno o più caratteri?

Tutte le domande che sorgono dopo questo blocco di testo dipendono dall'ipotesi che nell'esempio precedente una linea sia definita come "Linea" e che le altre tre definizioni contenenti "Linea" nel loro nome debbano essere escluse:

  1. Lo "zero" in "zero o più righe" significa che un file può ancora essere considerato un file di testo se contiene uno o più caratteri che non sono terminati con newline?

  2. "Zero o più righe" significa che una volta che una singola "Linea" (0 ​​o più caratteri più una nuova riga che termina entra in gioco) diventa illegale che l'ultima riga sia una "Linea incompleta" (una o più non - caratteri di nuova riga alla fine di un file)?

  3. "Nessuna [nessuna riga] può superare i {LINE_MAX} byte di lunghezza, incluso il carattere di nuova riga" significa che esiste un limite al numero di caratteri consentiti in una determinata "Linea" in un file di testo (a parte, il valore di LINE_MAX su Ubuntu 18.04 e FreeBSD 11.1 è "2048")?


Bella domanda, Harold! È un'ottima discussione sulla terminologia. Vorrei poter votare la domanda in più volte
Sergiy Kolodyazhnyy

Risposte:


23
  1. Un file di testo deve essere un file normale? Nell'estratto sopra non si dice esplicitamente che il file deve essere un file normale

    No; l'estratto nota anche in modo specifico l'input standard come potenziale file di testo. Altre utility standard, come ad esempio make, utilizzano specificamente il file speciale di caratteri /dev/null come file di testo .

  2. Un file può essere considerato un file di testo se contiene un solo carattere e un solo carattere (ovvero un singolo carattere che non termina con una nuova riga)?

    Quel personaggio deve essere una <newline>, o questa non è una linea , quindi il file in cui si trova non è un file di testo. Un file contenente esattamente il byte 0A è un file di testo a riga singola. Una riga vuota è una riga valida.

  3. Nell'estratto sopra riportato, fa riferimento a "linee". Ho trovato quattro definizioni con la riga nel loro nome: "Linea vuota", "Linea di visualizzazione", "Linea incompleta" e "Linea". Devo dedurre che significano "Linea" a causa della loro omissione di "Vuoto", "Display" e "Incompleto"

    Non è proprio un'inferenza, è proprio quello che dice. Alla parola "linea" è stata data una definizione contestualmente appropriata ed è di questo che parla.

  4. Posso dedurre con sicurezza che se un file è vuoto, non è un file di testo perché non contiene uno o più caratteri?

    Un file vuoto è costituito da zero (o più) righe ed è quindi un file di testo.

  5. Lo "zero" in "zero o più righe" significa che un file può ancora essere considerato un file di testo se contiene uno o più caratteri che non sono terminati con newline?

    No, questi personaggi non sono organizzati in linee.

  6. "Zero o più righe" significa che una volta che una singola "Linea" (0 ​​o più caratteri più una nuova riga che termina entra in gioco) diventa illegale che l'ultima riga sia una "Linea incompleta" (una o più non - caratteri di nuova riga alla fine di un file)?

    Non è illegale , non è solo un file di testo. Un'utilità che richiede di fornire un file di testo può comportarsi in modo negativo se invece viene fornito quel file.

  7. "Nessuna [nessuna riga] può superare i {LINE_MAX} byte di lunghezza, incluso il carattere di nuova riga" significa che esiste un limite al numero di caratteri consentiti in una determinata "Linea" in un file di testo

    Sì.

Questa definizione sta solo cercando di stabilire alcuni limiti su ciò che un'utilità basata su testo ( ad esempiogrep ) accetterà sicuramente - niente di più. Sono anche liberi di accettare le cose più liberamente, e molto spesso lo fanno in pratica. È consentito utilizzare un buffer di dimensioni fisse per elaborare una riga, assumere che una nuova riga appaia prima che sia piena e così via. Potresti leggere troppo nelle cose.


1
Sei sicuro del punto 2? Lo standard afferma esplicitamente " 0 o più righe". Quindi printf "a" > filecreerebbe un file di testo in base a tale definizione. La tua risposta a 4 sembra contraddire le tue risposte a 2 e 5, come suggerisci che touch filecrea un file di testo mentre printf "a" > filenon lo fa.
terdon

4
@terdon: non vedo alcuna contraddizione nella risposta di Michael. Fondamentalmente, sembra dire che un file di testo POSIX è qualsiasi file il cui contenuto corrisponde alla regexp (.{0,M}\n)*(implicitamente ancorato ed entrambe le estremità), dove \ncorrisponde a una nuova riga e .corrisponde a qualsiasi carattere che non è una nuova riga ed Mè un segnaposto per il valore numerico LINE_MAX-1. In particolare, ciò implica che un file vuoto è un file di testo valido costituito da zero righe, ma che qualsiasi file di testo non vuoto deve terminare con una nuova riga (poiché altrimenti conterrebbe una riga incompleta e una riga incompleta non è una riga ).
Ilmari Karonen,

@Michael Homer Per quanto riguarda il file normale, ci sono altri esempi oltre a / dev / null? In realtà non è un file di testo poiché contiene uno o più caratteri null.
Harold Fischer,

1
@HaroldFischer /dev/nullè un file vuoto. Stai pensando /dev/zero.
Michael Homer,

@HaroldFischer, no, /dev/nulllegge come vuoto, poiché in te non ottieni dati quando lo leggi. Non sono sicuro che abbia molto senso considerare i file non regolari qui, dal momento che molti di loro sono di natura dinamica. Ciò include pipe, socket, dispositivi char, che sono essenzialmente solo interfacce di trasporto verso / da qualche altra entità. Non contengono alcun set statico di dati, quindi avrebbe più senso considerare le proprietà dei dati trasferiti, anziché le proprietà del file .
ilkkachu,

7

Come definito da POSIX:

Sì, un file di testo è (sostanzialmente):

Un file che contiene caratteri organizzati in zero o più righe.

Sarebbe utile includere anche queste definizioni:

3.92 Stringa di caratteri

Una sequenza contigua di caratteri terminata da e incluso il primo byte null.

3.195 Linea incompleta

Una sequenza di uno o più caratteri non <newline> alla fine del file.

Linea 3.206

Una sequenza di zero o più caratteri non <newline> più un carattere <newline> che termina.

3.243 Newline Character (<newline>)

Un carattere che nel flusso di output indica che la stampa dovrebbe iniziare all'inizio della riga successiva. È il carattere designato da '\ n' nel linguaggio C. Non è specificato se questo carattere sia la sequenza esatta trasmessa a un dispositivo di output dal sistema per eseguire il movimento alla riga successiva.

3.247 NUL

Un carattere con tutti i bit impostati su zero.

Si noti che un "File di testo" non deve contenere byte NUL.


Così:

  1. Un file di testo deve essere un file normale?
    No, non è necessario. Un "file di testo" è definito in termini di ciò che contiene durante la lettura. Se un file contiene "zero o più righe" è un file di testo. Alcuni file, ad esempio /dev/stdin, potrebbero contenere un file di testo se letto in una volta e non alla successiva lettura.
  2. Un file può essere considerato un file di testo se contiene un carattere e un solo carattere ...?
    No, questa è una linea incompleta (3.195).
    Un file di testo deve contenere solo "Linee incomplete".
  3. Devo dedurre che significano "Linea" ...?
    Si, dovresti.
  4. Posso dedurre con sicurezza che se un file è vuoto, non è un file di testo ...?
    No, un file vuoto (zero caratteri) è un "file di testo" valido.
    Dall'alto: ... zero o più righe ... . Zero linee (zero caratteri) è un "file di testo" valido.
  5. ... considerato un file di testo se contiene uno o più caratteri che non terminano con newline?
    No, una "Linea incompleta" non è (tecnicamente) una "linea" valida.
  6. Lo "zero" in "zero o più righe" significa che un file può ancora essere considerato un file di testo se contiene uno o più caratteri che non sono terminati con newline?
    No, una linea incompleta non è una "Linea". Un file di testo non deve contenere righe incomplete.

  7. ... c'è una limitazione al numero di caratteri consentiti in una determinata "Linea" in un file di testo ...?
    Sì, non più di {LINE_MAX} byte (al contrario dei caratteri) sono consentiti in una determinata riga di un "file di testo" valido.
    Il valore di {LINE_MAX} è dato nel file <limits.h>
    (leggi anche la dimensione del buffer di linea sensibile in C? ):

    {LINE_MAX}
    Se non diversamente specificato, la lunghezza massima, in byte, della riga di input di un'utilità (input standard o un altro file), quando l'utilità viene descritta come elaborazione di file di testo. La lunghezza include spazio per il trailing.
    Valore minimo accettabile: {_POSIX2_LINE_MAX}

    Per un sistema basato su GNU non esiste un limite impostato (tranne la memoria) :

    Macro: int LINE_MAX
    La più grande riga di testo supportata dalle utility POSIX.2 orientate al testo. (Se si utilizzano le versioni GNU di queste utility, non esiste alcun limite effettivo se non quello imposto dalla memoria virtuale disponibile, ma la libreria non può dirlo in alcun modo.)

    Sembra essere definito posix_lim.hcome 2048 (almeno per i sistemi GNU Linux a 64 bit):

    $ 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
    

    Può anche essere trovato usando l' utilità POSIX getconf :

    $ getconf LINE_MAX
    2048
    

Correlati: Perché i file di testo dovrebbero terminare con una nuova riga?


2
Questa risposta è per lo più corretta, ma la risposta corretta a "deve essere un file di testo un file normale" è no . Qualsiasi tipo di file può essere un file di testo, è una questione di contenuto, il tipo di file è irrilevante. L' fileutilità riporta solo il tipo di file per file speciali, ma è così che funziona, usa file - <…o (Linux) l'utilità file -s …per vedere la sua euristica sul contenuto del file per un file speciale. Un file speciale può avere contenuti diversi ogni volta che lo apri, quindi può essere o essere un file di testo ogni volta. /dev/nullè sempre un file di testo perché il suo contenuto è sempre un file di testo.
Gilles 'SO- smetti di essere malvagio'

1
Invece di utilizzare grepsui file, è possibile utilizzare getconfper ottenere valori di configurazione del sistema getconf LINE_MAX, ad esempio , che tra l'altro restituisce 2048 (byte) sul mio sistema (Ubuntu 16.04).
heemayl,

Volevo trovare il file in cui era stata definita la variabile, quindi era necessario grep e ho fatto il lavoro (abbastanza rapidamente). Ma sì, getconfpermette di leggere il valore attuale di config.
Isacco,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.