Avançar para o conteúdo
Imagem com logotipo, contendo link para a página inicial
  • United Stated of America flag, representing the option for the English language.
  • Bandeira do Brasil, simbolizando a opção pelo idioma Português do Brasil.

Sistemas de Arquivos: Arquivos, Diretórios (Pastas) e Caminhos

A saída de alguns comandos relacionados ao uso de sistemas de arquivos em sistemas Linux. A imagem ilustra diretórios e arquivos listados pelos comandos ls, mount e tree.

Créditos para a imagem: Imagem criada pelo autor usando o programa Spectacle.

Paradoxos da Modernidade

Sistemas atuais são, em geral, mais fáceis de usar que há algumas décadas, embora ainda aquém do ideal. Questões de acessibilidade e usabilidade continuam desafiadoras e relevantes -- especialmente para pessoas com deficiência. Entretanto, os sistemas são mais usáveis para mais pessoas que no passado. De fato, a geração atual é, por vezes, chamada nativa digital, reflexo da disponibilidade de tecnologias digitais desde seu nascimento.

Sistemas para Internet (Web) contribuíram para a simplificação, promovendo interfaces padronizadas (ao menos para um mesmo sistema) entre diferentes dispositivos e plataformas. Navegadores melhoram continuamente, incorporando novas funcionalidades. Sistemas Web tornam-se mais completos e sofisticados, por vezes alternativas suficientes aos sistemas tradicionais para computadores de mesa. O termo nuvem torna-se sinônimo de computação e modernidade -- até mesmo de forma exagerada.

Contudo, a simplicidade tem seu preço. A contrapartida é que a migração para a Web reduziu a necessidade de realização operações básicas de informática cotidianas. Isso é algo positivo, de certa forma. Contudo, não de todas as formas.

Talvez paradoxalmente, as pessoas atualmente usem mais tecnologias, mas entendam menos sobre elas. Conceitos tradicionais caíram em desuso. O que é um arquivo? O que é um diretório ou uma pasta?

De Volta ao Básico: Abaixo da Nuvem, o Disco

Não existe nuvem; tudo está armazenado em algum lugar, em alguma máquina. Se a máquina é sua ou não é a pergunta. Existem questões de segurança e privacidade acerca do tema, mas elas não são o foco deste tópico in particular.

Para o momento, o interesse é em sistemas de arquivos. A parte básica. Pode-se pensar em arquivos como caixas que armazenam dados digitais para uso em um computador (ou qualquer outro dispositivo digital). Arquivos incluem:

  • Documentos de texto;
  • Imagens;
  • Apresentações de slides;
  • Vídeos;
  • Músicas;
  • Programas de computador (software, aplicações, aplicativos, ou, simplesmente, apps);
  • Atalhos para programas de computador (ou para quaisquer outros arquivos ou pastas).

O texto desta página está armazenado em um arquivo. A página, como um todo, é um conjunto de arquivos: ela combina arquivos de texto, com imagens, com arquivos contendo código para o navegador de Internet (por exemplo, Mozilla Firefox, Google Chrome, Microsoft Edge e Microsoft Internet Explorer, Apple Safari, ou navegadores textuais, como Lynx e Links).

Arquivos armazenam bits. A ênfase é intencional. Tecnicamente, arquivos não armazenam texto, nem imagens, nem sons. Apenas bits. A palavra bit é uma contração de binary digit (dígito binário, em Português), pois um bit pode assumir apenas um entre dois valores. Por convenção, zero (0) e um (1). Assim, pode-se dizer que computadores armazenam apenas seqüências de valores zero e um. Todo o restante é resultado de codificações binárias.

Trabalhar com bits não é algo muito conciso, nem prático. Assim, por conveniência, utiliza-se bytes com mais freqüência que bits. Um byte corresponde a oito (8) bits. Por mais conveniência, é usual utilizar múltiplos de bytes, como kilobytes, megabytes, gigabytes, terabytes.

Discos são responsáveis por armazenar dados em memória persistente (secundária) em computadores. As opções mais comuns são conhecidas justamente como discos rígidos (hard disk drive ou simplesmente hard disk, abreviados, respectivamente, como HDD e HD) e solid slate drives (cuja sigla é SSD). O armazenamento em discos é contado em múltiplos de bytes. Discos comerciais modernos comumente podem armazenar gigabytes ou terabytes de dados.

Para se organizar arquivos, pode-se definir pastas, também conhecidas como diretórios. Diretório era o termo usual nos primeiros sistemas de arquivos, quando se navegava por pastas e arquivos usando-se exclusivamente a linha de comando. O termo ainda é usado para programas de linha de comando.

Sistemas de Arquivos

Sistemas de arquivos são, comumente, organizados usando-se uma estrutura de dados chamada de árvore. Toda árvore inicia-se de uma raiz. Em sistemas de arquivos, pastas (diretórios) definem subárvores. Arquivos definem folhas. Simplificadamente, subárvores são árvores; ou seja, diretórios podem conter arquivos ou outros subdiretórios. Arquivos, por outro lado, são elementos terminais.

Na prática, arquivos podem armazenar outros arquivos por meio de ferramentas de arquivação (que comumente incorporam funcionalidades de compressão). tar, zip, rar, gz e bz são exemplos tradicionais de extensões para formatos gerados por arquivação e/ou compressão. Para o sistema de arquivos, um arquivo gerado por ferramentas compatíveis com os formatos anteriores representa um único arquivo. De fato, sem uma ferramenta compatível, não é possível acessar o conteúdo original armazenado.

Caminhos Absolutos (Paths) de Diretórios e de Arquivos

Um conceito importante para uso de arquivos em programação é o de caminho (do inglês, path). Um caminho é uma seqüencia de diretórios que leva de uma origem (início) até um destino (fim). A origem sempre é um diretório. O destino pode ser um subdiretório (ou a própria origem) ou um arquivo em um subdiretório.

Todo arquivo possui um caminho chamado de caminho absoluto (absolute path), que serve como o endereço do arquivo em um sistema de arquivos. O caminho absoluto é único; cada arquivo e diretório em um sistema de arquivos possui um caminho absoluto distinto baseado nos nomes definidos até o destino.

Um caminho absoluto inicia-se da raiz do sistema de arquivos até chegar ao subdiretório ou arquivo desejado. Em sistemas operacionais Windows, a raiz mapeia uma unidade de disco por meio de um padrão da forma "letra:\". Por exemplo, o mais usual é C:\, normalmente utilizado pela instalação. Contas de usuário em sistemas Windows possuem caminho absoluto no formato C:\Users\Nome do Usuário\ -- por exemplo, C:\Users\Franco\, para uma conta de usuário chamada Franco. Para instalações com uma única conta, o nome é o escolhido durante a instalação ou primeiro uso do computador. Para usar um valor genérico para obter a conta do usuário atual, pode-se usar valores armazenados em variáveis de ambiente (por exemplo, USERPROFILE, acessada como %USERPROFILE%).

Um exemplo de caminho absoluto de arquivo na área de trabalho (que também é uma pasta) poderia ser algo como C:\Users\Franco\Desktop\Nome do arquivo.txt. Caso o mesmo arquivo estivesse em uma pasta chamada Minha Pasta na área de trabalho, o caminho seria C:\Users\Franco\Desktop\Minha Pasta\Nome do arquivo.txt. Em sistemas em português, os exemplos ficariam:

  1. C:\Usuários\Franco\Área de Trabalho\Nome do arquivo.txt;
  2. C:\Usuários\Franco\Área de Trabalho\Minha Pasta\Nome do arquivo.txt.

No Windows, cada unidade de disco possui sua própria letra, representando a raiz. Valores normalmente começam em C:\, seguidos por D:\, E:\, e assim por diante. Antigamente, A:\ e B:\ mapeavam unidades de disquetes. Também é possível associar caminhos com letras arbitrárias, usando o comando subst na linha de comando (entrada de manual; manuais são essenciais para o desenvolvimento de software).

Em sistemas baseados em Unix, como Linux, a raiz do sistema de arquivos chama-se /. Ao contrário do Windows, todos as unidades de disco iniciam-se da raiz, em diretórios escolhidos durante um processo de montagem (que utiliza o comando mount). O exemplo equivalente ao diretório de usuário seria /home/nome-do-usuario/ -- por exemplo, /home/franco/. Por conveniência, pode-se referenciar o diretório do usuário atual por meio de um til (~), uma variável de ambiente. Para o exemplo anterior, ~/ e /home/franco/ representariam o mesmo endereço absoluto, caso o usuário atual chamasse-se franco.

Para os exemplos de arquivo em caminho absoluto fornecidos para o Windows, os correspondentes seriam:

  1. Para Nome do arquivo.txt na área de trabalho: /home/franco/Desktop/Nome do arquivo.txt, que é equivalente a ~/Desktop/Nome do arquivo.txt;
  2. Para Nome do arquivo.txt no subdiretório Minha Pasta na área de trabalho: /home/franco/Desktop/Minha Pasta/Nome do arquivo.txt, que é equivalente a ~/Desktop/Minha Pasta/Nome do arquivo.txt.

De forma geral, as maiores diferenças entre sistemas referem-se à distinção de letras minúsculas e maiúsculas, ao nome da raiz, à direção das barras.

A primeira diferença (e a que requer mais atenção) é sobre o uso de letras minúsculas e maiúsculas. O Windows não faz distinção. Um arquivo chamado abc.txt pode ser chamado de ABC.txt, abc.TXT, AbC.tXt ou qualquer outra variação. Diz-se, assim, que o Windows não é sensível à caixa (case sensitive) para caminhos.

Sistemas baseados em Linux, entretanto, são sensíveis à caixa (case sensitive) para caminhos e, portanto, distingüem letras minúsculas de maiúsculas. abc.txt, ABC.txt, abc.TXT, AbC.tXt são considerados quatro arquivo distintos, cada qual acessado pelo seu caminho escrito rigorosamente como definido.

A questão de escolhe de barras nem sempre é um problema nos dias de hoje, mas é bom conhecer a distinção. Windows usa contra-barra, Unix utiliza barra. Contra-barras no Windows são uma herança dos tempos do sistema DOS, porque barras eram (e ainda são) usadas para a passagem de parâmetros para comandos na linha de comando do DOS (hoje Windows; o interpretador cmd para processamento batch, conhecido em Português como lotes). Versões mais modernas do Windows costumam aceitar barras ao invés de contra-barras para caminhos, mas existem exceções de suporte. Via de regras, em bibliotecas para programação modernas, pode-se quase sempre usar usar sempre a barra para frente. Contudo, convém conferir e testar antes de assumir. Ainda melhor, abstrair por meio de uma subrotina (como uma função ou procedimento).

A terceira diferença é que nomes em Windows costumam ter espaços, acentos e outros caracteres especiais. Nomes em sistemas derivados de Unix costumam evitar espaços, acentos e caracteres especiais, para conveniência de uso da linha de comando. Normalmente, utiliza-se hífens ou underlines (underscores) para substituir os espaços. Por exemplo, ao invés de Nome Sobrenome, usa-se Nome-Sobrenome, Nome_Sobrenome, NomeSobrenome. Mais comumente (e também por conveniência), as palavras utilizam apenas letras minúsculas (nome-sobrenome).

As escolhas podem parecer inconseqüentes, mas se mostram sábias durante o desenvolvimento de software. Várias bibliotecas usadas em programação assumem o uso de língua inglesa. Em outras palavras, caracteres especiais tendem a ser problemáticos. Espaços também podem ser problemáticos.

Em programação, é prudente minimizar riscos desnecessários e maximizar as chances de evitar problemas. Para diretórios e arquivos internos, evitar o uso de espaços, acentos, cedilhas e outros caracteres especiais (isto é, qualquer um que não faça parte da língua inglesa ou codificação American Standard Code for Information Interchange -- ASCII) tende a evitar problemas e perda de tempo. Criar convenções para nomenclatura de arquivos e de diretórios para caminhos é uma boa prática de programação.

Caminhos Relativos (Paths) de Diretórios e de Arquivos

Além de caminhos absolutos, arquivos e pastas podem ter caminhos relativos. Ao passo que caminhos absolutos sempre iniciam-se da raiz do sistema de arquivos, caminhos relativos iniciam-se de uma origem escolhida arbitrariamente.

Entender caminhos relativos é mais simples com exemplos. De forma genérica, pode-se pensar em um sistema de arquivos como:

  • Raiz
    • Diretório de Usuários
      • Diretório do Um Usuário
      • Diretório de Outro Usuário
    • Diretório de Programas
    • Diretório do Sistema Operacional
    • Outros Diretórios da Raiz

Em um sistema Windows, o esquema anterior seria algo como:

  • C:\
    • Users (ou Usuários em português, ou Documents and Settings em versões mais antigas do Windows)
      • Ana
      • Franco
    • Program Files (ou Arquivos de Programas)
    • Windows
    • ...

Em um sistema Linux, o esquema seria algo como:

  • /
    • home
      • ana
      • franco
    • bin
    • sys

Agora, pode-se voltar a atenção para o usuário franco. Pode-se supor que franco possua o seguinte diretório pessoal:

  • Franco / franco
    • Desktop / Área de Trabalho
      • a.txt
      • b.md
      • c.pdf
      • Imagens
        • 1.png
        • 2.jpg
        • 3.gif
      • Código
        • C
          • x.c
        • C++
          • y.cpp
        • Python
          • z.py

Para mapear caminhos absolutos de arquivos, basta percorrer uma seqüência da raiz até o arquivo ou diretório desejado. Alguns exemplos:

  1. Arquivo b.md:
    • Windows:
      • C:\Users\Franco\Desktop\b.md
      • %USERPROFILE%\Desktop\b.md
    • Linux:
      • /home/franco/Desktop/b.md
      • ~/Desktop/b.md
  2. Diretório Imagens.md:
    • Windows:
      • C:\Users\Franco\Desktop\Imagens\
      • %USERPROFILE%\Desktop\Imagens\
    • Linux:
      • /home/franco/Desktop/Imagens/
      • ~/Desktop/Imagens/
  3. Arquivo y.cpp:
    • Windows:
      • C:\Users\Franco\Desktop\Código\C++\y.cpp
      • %USERPROFILE%\Desktop\Código\C++\y.cpp
    • Linux:
      • /home/franco/Desktop/Código/C++/y.cpp
      • ~/Desktop/Código/C++/y.cpp

Para caminhos relativos, os valores dependem da origem escolhida. Por exemplo, caso se escolhesse a origem como C:\Users\Franco\ (/home/franco/), os exemplos anteriores ficariam:

  1. Arquivo b.md:
    • Windows:
      • .\Desktop\b.md
    • Linux:
      • .\Desktop/b.md
  2. Diretório Imagens.md:
    • Windows:
      • .\Desktop\Imagens\
    • Linux:
      • ./Desktop/Imagens/
  3. Arquivo y.cpp:
    • Windows:
      • .\Desktop\Código\C++\y.cpp
    • Linux:
      • ./Desktop/Código/C++/y.cpp

Quando se usa caminhos relativos, um ponto (.) representa o diretório atual. No início do endereço, ele substitui a origem. Assim, para o exemplo, . equivale a C:\Users\Franco\ no Windows e a /home/franco no Linux.

Caso se deseje, pode-se omitir o ponto do início. Os sistemas operacionais assumem que se trate de um caminho relativo, considerado a partir do endereço atual. Contudo, existe uma exceção: para arquivos que são programas e que se deseja executar, deve-se usar um ponto barra (./, como em ./nome-programa) para evitar conflitos com os valores de ambiente. Assim, posta a exceção, os exemplos a seguir são equivalentes aos anteriores:

  1. Arquivo b.md:
    • Windows:
      • Desktop\b.md
    • Linux:
      • Desktop/b.md
  2. Diretório Imagens.md:
    • Windows:
      • Desktop\Imagens\
    • Linux:
      • Desktop/Imagens/
  3. Arquivo y.cpp:
    • Windows:
      • Desktop\Código\C++\y.cpp
    • Linux:
      • Desktop/Código/C++/y.cpp

O endereço que o sistema operacional assume é chamado de diretório de trabalho (work directory ou work dir) ou diretório corrente de trabalho (current work dir). No Linux, o diretório de trabalho é armazenado na variável de ambiente PWD (para usá-la, $PWD/resto/caminho/arquivo.ext). No Windows, o valor pode ser obtido pelo comando cd (current directory ou diretório atual; no Windows, cd também permite trocar de diretórios; em Unix, cd apenas permite para trocar de diretórios -- change directory). Para usá-lo no Windows, deve-se escrever %cd%\resto\caminho\arquivo.ext.

Endereços relativos assumem diferentes valores quando a origem (agora chamada diretório de trabalho) muda. Por exemplo, assumindo, agora, a origem como o diretório C:\Users\Franco\Desktop\Código\ (Windows) ou /home/franco/Desktop/Código (Unix), os resultados seriam:

  1. Arquivo b.md:
    • Windows:
      • ./..\b.md
      • ..\b.md
    • Linux:
      • ./../b.md
      • ../b.md
  2. Diretório Imagens.md:
    • Windows:
      • ./../b.md
      • ..\Imagens\
    • Linux:
      • ./../Imagens/
      • ../Imagens/
  3. Arquivo y.cpp:
    • Windows:
      • ./C++\y.cpp
      • C++\y.cpp
    • Linux:
      • ./C++/y.cpp
      • C++/y.cpp

O exemplo apresenta o segundo valor especial em caminhos relativos, representado por dois pontos seguidos (..). Os pontos significam o diretório pai do diretório resultante até o momento.

No exemplo, como . representa C:\Users\Franco\Desktop\Código\ (/home/franco/Desktop/Código) no início do endereço, .. representa C:\Users\Franco\Desktop\ no Windows e /home/franco/Desktop/ no Linux.

Por fim, os valores de . e .. correspondem sempre ao valor obtido até o momento. Em outras palavras,

  • ././././ corresponde a ./;
  • .././././../ corresponde a ../../;
  • ./abc/./def/ghi/./ corresponde a abc/def/ghi/;
  • abc/def/ghi/.. corresponde a abc/def/.
  • abc/def/ghi/.././ corresponde a abc/def/.
  • abc/def/ghi/.././.. corresponde a abc/.

No início, caminhos absolutos e relativos podem ser confusos e complexos. Com um pouco de prática, o uso torna-se mais simples. Praticar com os outros arquivos e pastas definidos no início desta subseção pode ser conveniente. Pode ser ainda melhor praticar com arquivos e pastas existentes em seu computador.

Quando Usar Caminhos Absolutos? Quando Optar por Caminhos Relativos?

Usar caminhos relativos sempre que possível é uma boa prática de programação.

O uso de caminhos relativos, em particular, é útil em programação e automação, porque permite trabalhar com arquivos e pastas de forma genérica. Para que um caminho absoluto funcione, todo o endereço deve ser exatamente idêntico -- da raiz até a folha (seja ela arquivo ou pasta). Conseqüentemente, caso exista um nome de usuário ou máquina em qualquer parte do caminho, ele também deve ser o mesmo.

Para que um caminho relativo funcione, basta que a estrutura de diretórios e arquivos a partir do endereço inicial sejam as mesmas.

Quando caminhos absolutos forem inevitáveis, convém abstraí-los usando variáveis de ambiente fornecidas pelo sistema operacional -- ou definir as próprias e documentá-las.

Informações Adicionais e Curiosidades

Tamanhos de Arquivos: Bytes e Bibytes

Embora toda quantidade de bytes seja, tecnicamente, um múltiplo de dois (dado que bits possuem apenas dois valores), veiculações de marketing e propagandas comumente utilizam múltiplos de bytes em potências de dez (10) para descrever capacidades de armazenamento em memória. Para evitar imprecisões quando necessário, existe o também o termo bibyte, que sempre é definido como potência de two.

NomeSiglaValorPotência
bitb120
byteB823
kilobytekB100010001
megabyteMB100000010002
gigabyteGB100000000010003
terabyteTB100000000010004
petabytePB100000000000010005
exabyteEB100000000000000010006
zettabyteZB100000000000000000010007
yottabyteYB100000000000000000000010008
NomeSiglaValorPotência de b
bitb120
byteB823
kibibyteKiB1024210
mebibyteMiB1048576220
gibibyteGiB1073741824230
tebibyteTiB1099511627776240
pebibytePiB1125899906842624250
exabibyteEiB1152921504606846976260
zebibyteZiB1180591620717411303424270
yobibyteYiB1208925819614629174706176280

Codificação (Codificação, Decodificação e Transcodificação) de Dados e Extensões

Para o computador, nada existe além de zeros e uns. Letras, dígitos, imagens, sons, vídeos, código de computador -- e mesmo o sistema operacional -- são seqüências codificadas de bits.

Por exemplo, em codificação ASCII e em Unicode Transformation Format 8 (UTF-8), a letra a possui a representação binária 11000012, que requer um mínimo de oito bits de memória (um byte). O valor é lido como um, um, zero, zero, zero, zero, um e corresponde ao número decimal noventa e sete (9710).

Uma forma de obter o valor é escrevendo a seguinte linha em um interpretador de código da linguagem Python:

print("a = ", ord("a"))      # 97
print("a = ", bin(ord("a"))) # 0b1100001

Para executar o código, deve-se escrever o comando python (depois de instalá-lo) em um interpretador de linha de comando, escrever uma das linhas, pressionar enter e esperar alguns instantes para o resultado. O interpretador avaliará a primeira expressão e fornecerá a resposta como saída. O mesmo procedimento vale para a secunda linha. Não é necessário escrever o que está após o jogo da velha; trata-se de um comentário ilustrando a resposta esperada.

Em um navegador para desktop, pode-se obter o valor sem a instalação de nenhum programa adicional. Para isso, pode-se abrir as opções de desenvolvedor (pressionando-se a tecla F12 no Mozilla Firefox, Google Chrome e Microsoft Edge), escolhendo a aba Console e escrevendo o seguinte código JavaScript (tecnicamente, charCodeAt() fornece um valor para UTF-16):

console.log("a".charCodeAt(0))             // 97
console.log("a".charCodeAt(0).toString(2)) // 1100001

O processo de converter um valor para um código é chamado de codificação. O processo de converter o código para o valor original é chamado de decodificação. Finalmente, o processo de codificação seguido de decodificação é chamado de transcodificação.

Todas as letras do texto desta página são codificadas por seus respectivos valores em UTF-8. O navegador interpreta o valor e desenha o caractere correspondente na tela (ou um sintetizador de voz lê o caractere). Repete-se o processo para transformar sequências de caracteres codificados em binários como seqüências de imagens para se desenhar.

Imagens, sons, documentos, programas de computador e todos os outros arquivos possuem suas próprias codificações. Para o computador, nada existe além de zeros e uns. Tudo é código. O computador apenas faz o que o programa o comanda a fazer.

Cabe, então, a pergunta: como um computador sabe qual programa deve usar para abrir e ler um arquivo?

Existem três formas principais:

  1. Uma pessoa escolhe o programa que o computador deve usar;

  2. Extensões. Extensões são seqüências de caracteres prefixados ao final do nome de um arquivo, normalmente após um ponto (padrão: nome-do-arquivo.ext). Por exemplo, .txt, .doc, .docx, .pdf, .jpg, .png, .gif, .avi, .mpeg, .mp3 e .ogg são exemplos de extensões populares para documentos, imagens, vídeos e áudio. Extensões podem ter mais de três caracteres (por exemplo, .franco ou .FrAnCo-GaRcIa) ou menos (.f). Inclusive, um arquivo pode não ter extensão (por exemplo, só nome ou nome). Um arquivo sem extensão continua sendo um arquivo no formato de seus dados. A extensão é, pois, opcional.

    De qualquer forma, uma extensão serve como uma heurística (uma dica) de quais programas um computador pode escolher e usar para abrir o arquivo. Caso exista uma associação entre extensão e programa, o sistema operacional pode executar o programa adequado para abrir um arquivo com a extensão fornecida.

  3. Metadados em cabeçalho do arquivo. Muitos formatos de arquivo destinam os primeiros valores armazenados para descrever o conteúdo do arquivo. Assim, o sistema operacional pode lê-los para conhecer o formato e utilizar o programa adequado (caso exista associação) para abri-lo.

Uma quarta forma é tentar adivinhar o formato por meio da análise de conteúdo; algo nem sempre possível. Quando o computador não consegue, ele pergunta à usuária ou ao usuário como ela ou ele deseja fazê-lo.

Caso esta subseção seja nebulosa neste momento, não há com o que se preocupar. Trata-se de uma curiosidade sobre o funcionamento de computadores. Para o momento, o mais importante é saber operar com arquivos e pastas. O próximo tópico apresenta o básico.

  • Informática
  • Programação
  • Iniciante
  • Linux
  • Windows

Anterior:
Faça-se a Luz