Cosa sono i descrittori di file, spiegati in termini semplici?


384
  1. Quale sarebbe una descrizione più semplificata dei descrittori di file rispetto a quella di Wikipedia? Perché sono richiesti? Ad esempio, prendi i processi di shell come esempio e come si applica?

  2. Una tabella dei processi contiene più di un descrittore di file. Se si, perché?


3
E i concetti di stdin stdout stderr ecc? Ho un'istanza come dire il processo del browser aperto e ha aperto alcuni file temporanei per visualizzare il mio HTML. Il processo usa lo stesso fd per leggere / scrivere? Anche la tabella dei processi ....... ha voci come puntatore fd0 puntatore fd1 puntatore fd2 ..... significa che tutti questi file sono nella RAM? Perché altri puntatori?
Nishant

43
Quando si apre un file, il sistema operativo crea un flusso per quel file e si collega tale flusso al file aperto, il descrittore rappresenta effettivamente quel flusso. Allo stesso modo ci sono alcuni flussi predefiniti creati dal sistema operativo. Questi flussi sono collegati al terminale anziché ai file. Quindi quando scrivi qualcosa nel terminale va allo stream stdin e al sistema operativo. E quando si scrive il comando "ls" sul terminale, il sistema operativo scrive l'output sul flusso stdout. il flusso stdout è collegato al terminale del monitor in modo da poter vedere l'output lì.
Tayyab

1
Per quanto riguarda l'esempio del browser, non è necessario che il browser mantenga i file aperti. Dipende dall'implementazione del browser, ma nella maggior parte dei casi il browser apre un file temporaneo, scrive il file e chiude il file, quindi non è necessario che il file venga aperto anche se la pagina Web è aperta. E il descrittore contiene solo le informazioni del file e non mantiene necessariamente il file nella RAM. Quando leggi i dati da un descrittore, il sistema operativo legge i dati dal disco rigido. Le informazioni nel descrittore di file rappresentano solo la posizione del file sul disco rigido ecc.
Tayyab

5
Il descrittore di file su file non è un mapping uno a uno. Potrei aprire () lo stesso file 4 volte e ottenere 4 descrittori di file diversi. Ognuno dei quali potrebbe essere usato (a seconda dei flag passati a open ()) per leggere, scrivere o entrambi. Sia che il file risieda nella RAM o sul disco, questo è nascosto dal kernel e dalle sue varie cache. Alla fine, qual è la cache corrisponderà a ciò che è sul disco (per la scrittura) e il kernel non tornerà sul disco, per la lettura, se i dati sono già nella cache.
Beano,

7
Questo è un buon articolo per capirlo facilmente bottomupcs.com/file_descriptors.xhtml
Krishan Gopal

Risposte:


562

In parole semplici, quando si apre un file, il sistema operativo crea una voce per rappresentare quel file e memorizzare le informazioni su quel file aperto. Quindi se ci sono 100 file aperti nel tuo SO allora ci saranno 100 voci nel SO (da qualche parte nel kernel). Queste voci sono rappresentate da numeri interi come (... 100, 101, 102 ....). Questo numero di voce è il descrittore di file. Quindi è solo un numero intero che rappresenta in modo univoco un file aperto nel sistema operativo. Se il processo apre 10 file, la tabella del processo avrà 10 voci per i descrittori di file.

Allo stesso modo quando si apre un socket di rete, è anche rappresentato da un numero intero e si chiama Socket Descriptor. Spero che tu capisca.


8
Inoltre, è per questo che puoi esaurire i descrittori di file, se apri molti file contemporaneamente. Ciò impedirà l'esecuzione dei sistemi * nix, poiché aprono descrittori alle cose in /procogni momento.
Spencer Rathbun,

8
@ErbenMo: No, potrebbe non essere lo stesso. Quando si apre un file, il sistema operativo assegnerà un FD disponibile e quando lo si chiude, il sistema operativo rilascia l'FD e può assegnare quell'FD a un altro file aperto successivamente. Il modo in cui il suo sistema operativo tiene traccia dei file aperti e non ha nulla a che fare con un file specifico.
Tayyab,

49
" Quindi è solo un numero intero che rappresenta in modo univoco un file aperto nel sistema operativo. " Questo non è corretto. Quel numero intero rappresenta in modo univoco un file aperto all'interno di un processo . Il descrittore di file 0, ad esempio, rappresenterà un file aperto in un processo e un file aperto completamente diverso in un altro processo.
Keith Thompson,

15
@Tayyab: credo che ti sbagli. I descrittori di file 0, 1 e 2 sono input standard, output standard ed errore standard per ogni processo in esecuzione. Una chiamata iniziale riuscita a open()fornirà il descrittore di file 3, anche se un altro processo in esecuzione ha un descrittore di file 3. Vedere la definizione POSIX diopen() : "La funzione open () restituisce un descrittore di file per il file indicato che è il più basso descrittore di file attualmente non aperto per tale processo . " (enfasi aggiunta).
Keith Thompson,

17
@KeithThompson: Sì, hai ragione. In realtà si tratta del livello di astrazione. In realtà vengono mantenute due tabelle, in cui la prima è per processo e la seconda a livello di sistema. L'FD nella tabella per processo (cioè fdtable) non è univoco a livello di sistema. Tuttavia, esegue il mapping alla tabella v-node che contiene le voci univoche a livello di sistema. Quindi quando si chiama la funzione fopen () e fileno () per controllare il descrittore, è possibile ottenere lo stesso numero FD in 2 processi diversi perché restituisce l'indice di fdtable che è per processo. Grazie per averlo sollevato !!
Tayyab,

116

Un descrittore di file è un handle opaco che viene utilizzato nell'interfaccia tra spazio utente e kernel per identificare le risorse di file / socket. Pertanto, quando si utilizza open()o socket()(il sistema chiama per interfacciarsi al kernel), viene fornito un descrittore di file, che è un numero intero (in realtà è un indice nella struttura dei processi u - ma questo non è importante). Pertanto, se si vuole interfacciarsi direttamente con il kernel, utilizzando chiamate di sistema a read(), write(), close()ecc il manico si utilizza è un descrittore di file.

C'è uno strato di astrazione sovrapposto alle chiamate di sistema, che è l' stdiointerfaccia. Ciò fornisce più funzionalità / caratteristiche rispetto alle chiamate di sistema di base. Per questa interfaccia, l'handle opaco che ottieni è a FILE*, che viene restituito dalla fopen()chiamata. Ci sono molte molte funzioni che utilizzano l' stdiointerfaccia fprintf(), fscanf(), fclose(), che sono lì per fare la vita più facile. In C, stdin, stdout, e stderrsono FILE*, che in UNIX, rispettivamente, per mappare descrittori di file 0, 1e 2.


6
Personalmente penso che questa risposta sia migliore di quella contrassegnata come risposta. Upvoted.
Tarik,

101

Ascoltalo da Horse's Mouth: APUE (Richard Stevens).
Al kernel, tutti i file aperti sono indicati dai descrittori di file. Un descrittore di file è un numero non negativo.

Quando apriamo un file esistente o creiamo un nuovo file, il kernel restituisce un descrittore di file al processo. Il kernel mantiene una tabella di tutti i descrittori di file aperti, che sono in uso. L'assegnazione dei descrittori di file è generalmente sequenziale e vengono assegnati al file come successivo descrittore di file libero dal pool di descrittori di file gratuiti. Quando chiudiamo il file, il descrittore di file viene liberato ed è disponibile per ulteriori riparazioni.
Vedi questa immagine per maggiori dettagli:

Due processi

Quando vogliamo leggere o scrivere un file, identifichiamo il file con il descrittore di file che è stato restituito dalla chiamata di funzione open () o create () e lo usiamo come argomento per read () o write () .
È per convenzione che le shell di sistema UNIX associano il descrittore di file 0 con l' input standard di un processo, il descrittore di file 1 con output standard e il descrittore di file 2 con errore standard .
Il descrittore di file varia da 0 a OPEN_MAX. Il valore massimo del descrittore di file può essere ottenuto con ulimit -n. Per ulteriori informazioni, consulta il terzo capitolo del libro APUE.


1
Poiché 0, 1, 2 sono associati a "stdin", "stdout" e "stderr" di un processo, possiamo usare questi descrittori contemporaneamente per processi diversi?
Tarik,

@Tarik: i descrittori di file sono per processo. Per vedere questo, scarica osquery ed eseguiloosqueryi <<< echo '.all process_open_files' in una shell bash.
Ben Creasy,

29

Altre risposte hanno aggiunto grandi cose. Aggiungerò solo i miei 2 centesimi.

Secondo Wikipedia lo sappiamo per certo: un descrittore di file è un numero intero non negativo. La cosa più importante che penso manchi, sarebbe quella di dire:

I descrittori di file sono associati a un ID processo.

Sappiamo che i descrittori di file più famosi sono 0, 1 e 2. 0 corrisponde a STDIN, 1 a STDOUTe 2 a STDERR.

Ad esempio, prendi i processi di shell come esempio e come si applica?

Dai un'occhiata a questo codice

#>sleep 1000 &
[12] 14726

Abbiamo creato un processo con l'id 14726 (PID). Usando il lsof -p 14726possiamo ottenere le cose in questo modo:

COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
sleep   14726 root  cwd    DIR    8,1     4096 1201140 /home/x
sleep   14726 root  rtd    DIR    8,1     4096       2 /
sleep   14726 root  txt    REG    8,1    35000  786587 /bin/sleep
sleep   14726 root  mem    REG    8,1 11864720 1186503 /usr/lib/locale/locale-archive
sleep   14726 root  mem    REG    8,1  2030544  137184 /lib/x86_64-linux-gnu/libc-2.27.so
sleep   14726 root  mem    REG    8,1   170960  137156 /lib/x86_64-linux-gnu/ld-2.27.so
sleep   14726 root    0u   CHR  136,6      0t0       9 /dev/pts/6
sleep   14726 root    1u   CHR  136,6      0t0       9 /dev/pts/6
sleep   14726 root    2u   CHR  136,6      0t0       9 /dev/pts/6

La quarta colonna FD e la successiva colonna TYPE corrispondono al tipo di descrittore di file e al descrittore di file.

Alcuni dei valori per l'FD possono essere:

cwd – Current Working Directory
txt – Text file
mem – Memory mapped file
mmap – Memory mapped device

Ma il descrittore di file reale è sotto:

NUMBER – Represent the actual file descriptor. 

Il carattere dopo il numero, ad esempio "1u", rappresenta la modalità di apertura del file. r per leggere, w per scrivere, u per leggere e scrivere.

TYPE specifica il tipo di file. Alcuni dei valori di TYPE sono:

REG – Regular File
DIR – Directory
FIFO – First In First Out

Ma tutti i descrittori di file sono CHR - File speciale carattere (o file dispositivo carattere)

Ora, siamo in grado di identificare i descrittori di file per STDIN, STDOUTe STDERRfacile con lsof -p PID, o siamo in grado di vedere lo stesso se noi ls /proc/PID/fd.

Si noti inoltre che la tabella dei descrittori di file di cui il kernel tiene traccia non è la stessa della tabella dei file o della tabella degli inode. Questi sono separati, come hanno spiegato alcune altre risposte.

tabella fd

Potresti chiederti dove sono fisicamente questi descrittori di file e in cosa sono memorizzati /dev/pts/6ad esempio

sleep   14726 root    0u   CHR  136,6      0t0       9 /dev/pts/6
sleep   14726 root    1u   CHR  136,6      0t0       9 /dev/pts/6
sleep   14726 root    2u   CHR  136,6      0t0       9 /dev/pts/6

Bene, /dev/pts/6vive puramente nella memoria. Questi non sono file regolari, ma i cosiddetti file di dispositivi a caratteri . Puoi verificarlo con: ls -l /dev/pts/6e inizieranno con c, nel mio caso crw--w----.

Solo per ricordare la maggior parte di Linux come OS definire sette tipi di file:

  • File regolari
  • Elenchi
  • File del dispositivo carattere
  • Blocca i file del dispositivo
  • Socket di dominio locale
  • Named pipe (FIFOs) e
  • Collegamenti simbolici

1
Grazie. In effetti è importante sottolineare che è per processo! Aiuta a visualizzare meglio le cose.
Nishant,

1
I tipi di file definiti dal sistema operativo, che hai menzionato nella tua risposta, aiutano davvero a comprendere i file a un livello inferiore.
Rohan Bhale,

20

Più punti riguardanti File Descriptor:

  1. File Descriptors(FD) sono numeri interi non negativi (0, 1, 2, ...)associati ai file aperti.

  2. 0, 1, 2sono standard FD 's che corrisponde STDIN_FILENO, STDOUT_FILENOe STDERR_FILENO(definito unistd.h) aperta per impostazione predefinita a nome della shell all'avvio del programma.

  3. Gli FD sono allocati in ordine sequenziale, ovvero il valore intero non allocato più basso possibile.

  4. Gli FD per un particolare processo possono essere visualizzati in /proc/$pid/fd(su sistemi basati su Unix).


16

In aggiunta ad altre risposte, unix considera tutto come un file system. La tua tastiera è un file che viene letto solo dal punto di vista del kernel. Lo schermo è un file di sola scrittura. Allo stesso modo, anche le cartelle, i dispositivi di input-output ecc. Sono considerati file. Ogni volta che viene aperto un file, dire quando i driver di dispositivo [per file di dispositivo] richiedono un open () o un processo apre un file utente, il kernel alloca un descrittore di file, un numero intero che specifica l'accesso a quel file in modo che sia di sola lettura , scrivere solo ecc. [per riferimento: https://en.wikipedia.org/wiki/Everything_is_a_file ]


I descrittori di file possono anche riferirsi a cose che non esistono nel file system, come pipe anonime e socket di rete.
Kbolino,

12

Descrittori di file (FD):

  • In Linux / Unix , tutto è un file. File regolari, directory e persino dispositivi sono file. Ogni file ha un numero associato chiamato File Descriptor (FD).
  • Lo schermo ha anche un descrittore di file. Quando viene eseguito un programma, l'output viene inviato al descrittore di file della schermata e sul monitor viene visualizzato l'output del programma. Se l'output fosse inviato al descrittore di file della stampante, l'output del programma sarebbe stato stampato.

    Reindirizzamento errori:
    ogni volta che si esegue un programma / comando sul terminale, 3 file sono sempre aperti
    1. input standard
    2. uscita standard
    3. errore standard.

    Questi file sono sempre presenti ogni volta che si esegue un programma. Come spiegato prima di un descrittore di file, è associato a ciascuno di questi file.
    File                                        Descrittore File
    Input standard STDIN 0
    Output standard STDOUT 1
    Errore standard STDERR 2

  • Ad esempio, durante la ricerca di file, in genere si ottengono errori di autorizzazione negata o altri tipi di errori. Questi errori possono essere salvati in un determinato file.
    Esempio 1

$ ls mydir 2> errorsfile.txt

Il descrittore di file per l'errore standard è 2.
Se non esiste alcuna directory denominata mydir, l'output del comando verrà salvato nel file errorfile.txt
Usando "2>" reindirizziamo l'output dell'errore a un file chiamato "errorfile. txt "
Pertanto, l'output del programma non è ingombro di errori.

Spero che tu abbia la tua risposta


5

Qualsiasi sistema operativo ha processi (p) in esecuzione, ad esempio p1, p2, p3 e così via. Ogni processo di solito fa un uso continuo dei file.

Ogni processo è costituito da un albero dei processi (o una tabella dei processi, in un altro fraseggio).

Di solito, i sistemi operativi rappresentano ogni file in ogni processo con un numero (vale a dire, in ogni albero / tabella del processo).

Il primo file utilizzato nel processo è file0 , il secondo è file1 , il terzo è file2 e così via.

Qualsiasi tale numero è un descrittore di file.

I descrittori di file sono generalmente numeri interi (0, 1, 2 e non 0,5, 1,5, 2,5).

Dato che spesso descriviamo i processi come "tabelle di processo" e dato che le tabelle hanno righe (voci), possiamo dire che la cella del descrittore di file in ogni voce, utilizza per rappresentare l'intera voce.

Allo stesso modo, quando si apre un socket di rete, ha un descrittore di socket.

In alcuni sistemi operativi, è possibile esaurire i descrittori di file, ma tale caso è estremamente raro e l'utente medio del computer non dovrebbe preoccuparsene.

I descrittori di file potrebbero essere globali (il processo A inizia in dire 0 e finisce in 1; il processo B inizia in 2 e termina in 3) e così via, ma per quanto ne so, di solito nei moderni sistemi operativi, file i descrittori non sono globali e in realtà sono specifici del processo (il processo A inizia in dire 0 e termina in 5, mentre il processo B inizia in 0 e termina in 10).


Maggiori informazioni su FD in Linux qui: unix.stackexchange.com/questions/358022/…

1
ottima risposta :)
humble_wolf il

5

Descrittori di file

  • Al kernel tutti i file aperti sono indicati dai descrittori di file.
  • Un descrittore di file è un numero intero non negativo.
  • Quando apriamo un esistente o creiamo un nuovo file, il kernel restituisce un descrittore di file a un processo.
  • Quando vogliamo leggere o scrivere su un file, identifichiamo il file con il descrittore di file che è stato risintonizzato da open o create, come argomento per leggere o scrivere.
  • Ogni processo UNIX ha 20 descrittori di file e lo smaltimento, numerati da 0 a 19 ma è stato esteso a 63 da molti sistemi.
  • I primi tre sono già aperti all'avvio del processo 0: input standard 1: output standard 2: output errore standard
  • Quando il processo padre genera un processo, il processo figlio eredita i descrittori di file del padre

1

Aggiunta a risposte soprattutto semplificate.
Se stai lavorando con file in script bash, è meglio usare il descrittore di file.
Ad esempio: -
Si desidera leggere e scrivere da / nel file "test.txt".
Utilizzare il descrittore di file come mostrato di seguito

FILE=$1 # give the name of file in the command line
exec 5<>$FILE # '5' here act as the file descriptor
# Reading from the file line by line using file descriptor
while read LINE; do
    echo "$LINE"
done <&5

# Writing to the file using descriptor
echo "Adding the date: `date`" >&5 
exec 5<&- # Closing a file descriptor

-5

I descrittori di file sono i descrittori di un file. Danno collegamenti a un file. Con l'aiuto di loro possiamo leggere, scrivere e aprire un file.

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.