O que são descritores de arquivos, explicados em termos simples?

383
  1. Qual seria uma descrição mais simplificada dos descritores de arquivos em comparação com os da Wikipedia? Por que eles são necessários? Digamos, considere os processos do shell como um exemplo e como ele se aplica a ele?

  2. Uma tabela de processos contém mais de um descritor de arquivo. Se sim, por que?

Nishant
fonte
3
E os conceitos de stdin stdout stderr etc? Eu tenho uma instância como, digamos, processo do navegador aberto e ele abriu alguns arquivos temporários para exibir meu html. O processo usa o mesmo fd para ler / escrever? Também a tabela de processos ....... possui entradas como ponteiro fd0 ponteiro fd1 ponteiro fd2 ..... isso significa que todos esses arquivos estão na RAM? Por que mais ponteiros?
Nishant
43
Quando você abre um arquivo, o SO cria um fluxo para esse arquivo e conecta esse fluxo ao arquivo aberto, o descritor de fato representa esse fluxo. Da mesma forma, existem alguns fluxos padrão criados pelo sistema operacional. Esses fluxos são conectados ao seu terminal em vez de arquivos. Então, quando você escreve algo no terminal, ele vai para o stdin stream e o SO. E quando você escreve o comando "ls" no terminal, o sistema operacional grava a saída no fluxo stdout. O stdout stream está conectado ao terminal do seu monitor para que você possa ver a saída lá.
Tayyab
11
Em relação ao exemplo do navegador, não é necessário que o navegador mantenha os arquivos abertos. Depende da implementação do navegador, mas na maioria dos casos, o navegador abre um arquivo temporário, grava o arquivo e fecha o arquivo; portanto, não é necessário que o arquivo seja aberto, mesmo que a página da Web esteja aberta. E o descritor apenas mantém as informações do arquivo e não necessariamente mantém o arquivo na RAM. Quando você lê os dados de um descritor, o SO lê os dados do disco rígido. As informações no descritor de arquivo representa apenas o local do arquivo no disco rígido etc ..
Tayyab
5
O descritor de arquivo para arquivo não é um mapeamento individual. Eu poderia abrir () o mesmo arquivo 4 vezes e obter 4 descritores de arquivos diferentes. Cada um dos quais poderia ser usado (dependendo dos sinalizadores passados ​​para o open ()) para leitura, escrita ou ambos. Tanto quanto o arquivo reside na RAM ou no disco - isso está oculto para você pelo kernel e seus vários caches. Por fim, o que é o cache corresponderá ao que está no disco (para gravação) e o kernel não voltará ao disco, para leitura, se os dados já estiverem no cache.
Beano
7
Este é um bom artigo para compreendê-lo facilmente bottomupcs.com/file_descriptors.xhtml
Krishan Gopal

Respostas:

561

Em palavras simples, quando você abre um arquivo, o sistema operacional cria uma entrada para representar esse arquivo e armazena as informações sobre esse arquivo aberto. Portanto, se houver 100 arquivos abertos no seu sistema operacional, haverá 100 entradas no sistema operacional (em algum lugar do kernel). Essas entradas são representadas por números inteiros como (... 100, 101, 102 ....). Este número de entrada é o descritor de arquivo. Portanto, é apenas um número inteiro que representa exclusivamente um arquivo aberto no sistema operacional. Se seu processo abrir 10 arquivos, sua tabela Process terá 10 entradas para descritores de arquivos.

Da mesma forma, quando você abre um soquete de rede, ele também é representado por um número inteiro e é chamado de Descritor de Soquete. Espero que entenda.

Tayyab
fonte
7
Além disso, é por isso que você pode ficar sem descritores de arquivo, se abrir muitos arquivos de uma só vez. O que impedirá a execução de sistemas * nix, pois eles abrem descritores para coisas /proco tempo todo.
Spencer Rathbun
8
@ ErbenMo: Não, pode não ser o mesmo. Quando você abre um arquivo, o sistema operacional atribui um FD disponível e, quando você o fecha, libera o FD e pode atribuir esse FD a outro arquivo aberto depois disso. A maneira de seu sistema operacional rastrear arquivos abertos e não tem nada a ver com um arquivo específico.
Tayyab
49
" Portanto, é apenas um número inteiro que representa exclusivamente um arquivo aberto no sistema operacional. " Isso está incorreto. Esse número inteiro representa exclusivamente um arquivo aberto dentro de um processo . O descritor de arquivo 0, por exemplo, representará um arquivo aberto em um processo e um arquivo aberto completamente diferente em outro processo.
Keith Thompson
15
@ Tayyab: Eu acredito que você está enganado. Os descritores de arquivo 0, 1 e 2 são entrada padrão, saída padrão e erro padrão para cada processo em execução. Uma chamada inicial bem-sucedida open()fornecerá o descritor de arquivo 3, mesmo que outro processo em execução possua um descritor de arquivo 3. Consulte a definição POSIX deopen() : "A função open () retornará um descritor de arquivo para o arquivo nomeado mais baixo atualmente, o descritor de arquivo não está aberto para esse processo . " (enfase adicionada).
perfil completo de Keith Thompson
17
@KeithThompson: Sim, você está certo. Na verdade, é sobre o nível de abstração. Na verdade, duas tabelas são mantidas, onde a primeira é por processo e a segunda, em todo o sistema. O FD na tabela por processo (ou seja, fdtable) não é exclusivo do sistema. No entanto, ele mapeia para a tabela do nó v que contém as entradas exclusivas em todo o sistema. Portanto, quando você chama a função fopen () e fileno () para verificar o descritor, pode obter o mesmo número de FD em 2 processos diferentes, pois ele retorna o índice de fdtable que é por processo. Obrigado por mencionar !!
Tayyab
116

Um descritor de arquivo é um identificador opaco usado na interface entre o espaço do usuário e do kernel para identificar recursos de arquivo / soquete. Portanto, quando você usa open()ou socket()(o sistema chama para fazer interface com o kernel), você recebe um descritor de arquivo, que é um número inteiro (na verdade, é um índice dos processos na estrutura - mas isso não é importante). Portanto, se você quer fazer a interface diretamente com o kernel, usando chamadas de sistema para read(), write(), close()etc. a alça que você usa é um descritor de arquivo.

Há uma camada de abstração sobreposta nas chamadas do sistema, que é a stdiointerface. Isso fornece mais funcionalidades / recursos do que as chamadas básicas do sistema. Para essa interface, o identificador opaco que você recebe é a FILE*, que é retornado pela fopen()chamada. Há muitas muitas funções que usam a stdiointerface de fprintf(), fscanf(), fclose(), que estão lá para tornar sua vida mais fácil. Em C, stdin, stdoute stderrsão FILE*, que em UNIX mapear, respectivamente, para descritores de arquivos 0, 1e 2.

Beano
fonte
6
Pessoalmente, acho que essa resposta é melhor do que a marcada como resposta. Votado.
Tarik
101

Ouça da boca do cavalo: APUE (Richard Stevens).
Para o kernel, todos os arquivos abertos são referidos pelos descritores de arquivos. Um descritor de arquivo é um número não negativo.

Quando abrimos um arquivo existente ou criamos um novo arquivo, o kernel retorna um descritor de arquivo para o processo. O kernel mantém uma tabela de todos os descritores de arquivos abertos, que estão em uso. A distribuição dos descritores de arquivo é geralmente seqüencial e eles são atribuídos ao arquivo como o próximo descritor de arquivo livre do conjunto de descritores de arquivo gratuitos. Quando fechamos o arquivo, o descritor de arquivo é liberado e fica disponível para distribuição adicional.
Veja esta imagem para mais detalhes:

Processo dois

Quando queremos ler ou gravar um arquivo, identificamos o arquivo com o descritor de arquivo retornado por chamada de função open () ou create () e o usamos como argumento para ler () ou write () .
Por convenção, as conchas do sistema UNIX associam o descritor de arquivo 0 à entrada padrão de um processo, o descritor de arquivo 1 à saída padrão e o descritor de arquivo 2 ao erro padrão .
O descritor de arquivo varia de 0 a OPEN_MAX. O valor máximo do descritor de arquivo pode ser obtido com ulimit -n. Para obter mais informações, consulte o terceiro capítulo do livro APUE.

Shekhar Kumar
fonte
11
Como 0, 1, 2 estão associados a "stdin", "stdout" e "stderr" de um processo, podemos usar esses descritores ao mesmo tempo para diferentes processos?
Tarik
@Tarik: os descritores de arquivo são por processo. Para ver isso, baixe o osquery e execute osqueryi <<< echo '.all process_open_files'em um shell bash.
Ben Creasy
29

Outras respostas adicionaram ótimas coisas. Vou adicionar apenas meus 2 centavos.

De acordo com a Wikipedia, sabemos com certeza: um descritor de arquivo é um número inteiro não negativo. A coisa mais importante que acho que falta, seria dizer:

Os descritores de arquivo estão vinculados a um ID do processo.

Sabemos que os descritores de arquivos mais famosos são 0, 1 e 2. 0 corresponde a STDIN, 1 a STDOUTe 2 a STDERR.

Digamos, considere os processos do shell como um exemplo e como ele se aplica a ele?

Confira este código

#>sleep 1000 &
[12] 14726

Criamos um processo com o ID 14726 (PID). Usando o lsof -p 14726nós podemos obter coisas assim:

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

A 4ª coluna FD e a próxima coluna TYPE correspondem ao tipo de descritor de arquivo e descritor de arquivo.

Alguns dos valores para o FD podem ser:

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

Mas o descritor de arquivo real está em:

NUMBER – Represent the actual file descriptor. 

O caractere após o número, ou seja, "1u", representa o modo em que o arquivo é aberto. r para leitura, w para gravação, u para leitura e gravação.

TYPE especifica o tipo do arquivo. Alguns dos valores dos TYPEs são:

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

Mas todos os descritores de arquivo são CHR - arquivo especial de caractere (ou arquivo de dispositivo de caractere)

Agora, podemos identificar os descritores de arquivo para STDIN, STDOUTe STDERRfácil com lsof -p PID, ou podemos ver o mesmo se ls /proc/PID/fd.

Observe também que a tabela de descritores de arquivos que o kernel controla não é a mesma que a tabela de arquivos ou a tabela de inodes. Estes são separados, como algumas outras respostas explicadas.

tabela fd

Você pode se perguntar onde estão esses descritores de arquivos fisicamente e o que é armazenado, /dev/pts/6por exemplo

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

Bem, /dev/pts/6vive puramente na memória. Esses arquivos não são comuns, mas os chamados arquivos de dispositivo de caracteres . Você pode verificar isso com: ls -l /dev/pts/6e eles começarão com c, no meu caso crw--w----.

Apenas para lembrar, a maioria dos Linux como o SO define sete tipos de arquivos:

  • Arquivos regulares
  • Diretórios
  • Arquivos de dispositivo de caracteres
  • Bloquear arquivos de dispositivo
  • Soquetes de domínio local
  • Pipes nomeados (FIFOs) e
  • Links simbólicos
prosti
fonte
11
Obrigado. De fato, é importante ressaltar que é por processo! Ajuda a visualizar melhor as coisas.
Nishant 22/09
11
Os tipos de arquivos definidos pelo sistema operacional, que você mencionou na resposta, realmente ajudam a entender os arquivos em um nível inferior.
Rohan Bhale 13/02/19
20

Mais pontos em relação a File Descriptor:

  1. File Descriptors(FD) são números inteiros não negativos (0, 1, 2, ...)associados a arquivos abertos.

  2. 0, 1, 2são padrão FD é que corresponde STDIN_FILENO, STDOUT_FILENOe STDERR_FILENO(definido no unistd.h) aberta por padrão, em nome do shell quando o programa começar.

  3. Os DFs são alocados na ordem seqüencial, significando o menor valor inteiro possível não alocado.

  4. Os FDs de um processo específico podem ser vistos em /proc/$pid/fd(em sistemas baseados em Unix).

Sandeep_black
fonte
16

Como complemento a outras respostas, o unix considera tudo como um sistema de arquivos. Seu teclado é um arquivo que é somente leitura da perspectiva do kernel. A tela é um arquivo somente para gravação. Da mesma forma, pastas, dispositivos de entrada e saída etc. também são considerados arquivos. Sempre que um arquivo é aberto, digamos, quando os drivers de dispositivo [para arquivos de dispositivo] solicitam um open (), ou quando um processo abre um arquivo de usuário, o kernel aloca um descritor de arquivo, um número inteiro que especifica o acesso a esse arquivo, apenas para leitura. , escreva apenas etc. [para referência: https://en.wikipedia.org/wiki/Everything_is_a_file ]

Balu
fonte
Os descritores de arquivo também podem se referir a coisas que não existem no sistema de arquivos, como pipes anônimos e soquetes de rede.
Kbolino # 7/18
12

Descritores de arquivo (FD):

  • No Linux / Unix , tudo é um arquivo. Arquivos regulares, diretórios e até dispositivos são arquivos. Todo arquivo tem um número associado chamado File Descriptor (FD).
  • Sua tela também possui um descritor de arquivo. Quando um programa é executado, a saída é enviada para o Descritor de Arquivos da tela e você vê a saída do programa no seu monitor. Se a saída for enviada para o Descritor de Arquivos da impressora, a saída do programa teria sido impressa.

    Redirecionamento de erro:
    Sempre que você executa um programa / comando no terminal, 3 arquivos estão sempre abertos
    1. entrada padrão
    2. saída padrão
    3. erro padrão.

    Esses arquivos estão sempre presentes sempre que um programa é executado. Conforme explicado antes de um descritor de arquivo, está associado a cada um desses arquivos.
    Arquivo                                        Descritor de arquivo
    Entrada padrão STDIN 0
    Saída padrão STDOUT 1
    Erro padrão STDERR 2

  • Por exemplo, durante a pesquisa de arquivos, normalmente se obtém erros de permissão negada ou algum outro tipo de erro. Esses erros podem ser salvos em um arquivo específico.
    Exemplo 1

$ ls mydir 2> errorsfile.txt

O descritor de arquivo para o erro padrão é 2.
Se não houver nenhum diretório chamado mydir, a saída do comando será salva no arquivo errorfile.txt.
Usando "2>", redirecionamos a saída do erro para um arquivo chamado "errorfile. txt "
Portanto, a saída do programa não está cheia de erros.

Espero que você tenha sua resposta.

Abhishek Kamal
fonte
5

Qualquer sistema operacional possui processos (p) em execução, por exemplo , p1, p2, p3 e assim por diante. Cada processo geralmente faz um uso contínuo de arquivos.

Cada processo consiste em uma árvore de processos (ou uma tabela de processos, em outro fraseado).

Geralmente, os sistemas operacionais representam cada arquivo em cada processo por um número (ou seja, em cada árvore / tabela de processos).

O primeiro arquivo usado no processo é o arquivo0 , o segundo é o arquivo1 , o terceiro é o arquivo2 e assim por diante.

Qualquer número desse tipo é um descritor de arquivo.

Os descritores de arquivo geralmente são números inteiros (0, 1, 2 e não 0,5, 1,5, 2,5).

Como geralmente descrevemos processos como "tabelas de processos", e como as tabelas possuem linhas (entradas), podemos dizer que a célula do descritor de arquivo em cada entrada é usada para representar a entrada inteira.

De maneira semelhante, quando você abre um soquete de rede, ele possui um descritor de soquete.

Em alguns sistemas operacionais, você pode ficar sem descritores de arquivos, mas esse caso é extremamente raro, e o usuário comum de computador não deve se preocupar com isso.

Os descritores de arquivo podem ser globais (o processo A começa em digamos 0 e termina em 1; o processo B começa em 2 e termina em 3) e assim por diante, mas até onde eu sei, geralmente nos sistemas operacionais modernos, o arquivo os descritores não são globais e são realmente específicos do processo (o processo A começa em digamos 0 e termina em 5, enquanto o processo B começa em 0 e termina em 10).


fonte
Leia mais sobre FD's no Linux aqui: unix.stackexchange.com/questions/358022/…
11
grande resposta :)
humble_wolf
5

Descritores de arquivo

  • Para o Kernel, todos os arquivos abertos são referidos pelos descritores de arquivos.
  • Um descritor de arquivo é um número inteiro não negativo.
  • Quando abrimos um arquivo existente ou criamos um novo arquivo, o kernel retorna um descritor de arquivo para um processo.
  • Quando queremos ler ou gravar em um arquivo, identificamos o arquivo com o descritor de arquivo que foi ajustado novamente por abrir ou criar, como um argumento para ler ou gravar.
  • Cada processo UNIX possui 20 descritores de arquivo e seu descarte, numerado de 0 a 19, mas foi estendido para 63 por muitos sistemas.
  • Os três primeiros já estão abertos quando o processo começa 0: A entrada padrão 1: A saída padrão 2: A saída de erro padrão
  • Quando o processo pai bifurca um processo, o processo filho herda os descritores de arquivo do pai
Mahendra suthar
fonte
1

Além de acima de todas as respostas simplificadas.
Se você estiver trabalhando com arquivos no script bash, é melhor usar o descritor de arquivos.
Por exemplo: -
Você deseja ler e gravar de / para o arquivo "test.txt".
Use o descritor de arquivo como mostrado abaixo

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
sumitsinghdeode
fonte
-5

Descritores de arquivo são os descritores de um arquivo. Eles fornecem links para um arquivo. Com a ajuda deles, podemos ler, escrever e abrir um arquivo.

Motimahal
fonte