Conceitos de Arquivos
O que é um Arquivo?
Um arquivo é a abstração do SO para dados persistentes. Enquanto processos e memória são efêmeros (desaparecem quando o computador desliga), arquivos persistem. O SO esconde a complexidade do hardware de armazenamento (setores, trilhas, blocos) por trás de uma interface simples: nome, conteúdo, metadados.
No Unix, a filosofia é levada ao extremo: "tudo é arquivo". Dispositivos, pipes, sockets, e até informações do kernel (/proc) são expostos como arquivos.
Atributos de um Arquivo
# stat mostra todos os atributos (metadados)
$ stat /etc/hostname
File: /etc/hostname
Size: 12 Blocks: 8 IO Block: 4096 regular file
Device: 8,1 Inode: 262146 Links: 1
Access: (0644/-rw-r--r--) Uid: (0/root) Gid: (0/root)
Access: 2026-05-08 10:00:00 # último acesso (atime)
Modify: 2026-01-15 08:30:00 # última modificação do conteúdo (mtime)
Change: 2026-01-15 08:30:00 # última modificação de metadados (ctime)
Birth: 2025-06-01 12:00:00 # criação (btime, nem todos FS suportam)
# Atributos principais:
# - Nome: hostname
# - Tipo: regular file (pode ser directory, symlink, device, etc.)
# - Tamanho: 12 bytes
# - Inode: 262146 (identificador único no filesystem)
# - Permissões: 0644 (rw-r--r--)
# - Dono: root:root (UID:GID)
# - Timestamps: atime, mtime, ctime
Operações sobre Arquivos
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main() {
// CREATE + OPEN: retorna file descriptor (int)
int fd = open("teste.txt", O_CREAT | O_WRONLY | O_TRUNC, 0644);
// O_CREAT: cria se não existe
// O_WRONLY: somente escrita
// O_TRUNC: trunca se já existe
// 0644: permissões rw-r--r--
// WRITE: escreve bytes
char *msg = "Hello, OS!\n";
write(fd, msg, strlen(msg));
// SEEK: move o ponteiro de leitura/escrita
lseek(fd, 0, SEEK_SET); // volta ao início
// CLOSE: libera o file descriptor
close(fd);
// OPEN para leitura
fd = open("teste.txt", O_RDONLY);
// READ: lê bytes
char buf[256];
ssize_t n = read(fd, buf, sizeof(buf) - 1);
buf[n] = '\0';
printf("Lido: %s", buf);
close(fd);
// DELETE
unlink("teste.txt");
return 0;
}
Métodos de Acesso
Acesso Sequencial:
Leitura/escrita avança automaticamente.
read() lê os próximos N bytes, ponteiro avança.
Ideal para: logs, streams, processamento de texto.
|--->|--->|--->|--->|--->| (sempre para frente)
Acesso Direto (Random):
Pode ler/escrever qualquer posição com lseek().
Ideal para: bancos de dados, arquivos indexados.
| | | | | |
^ ^ ^ (qualquer posição)
lseek(5) lseek(15)
Acesso Indexado:
Um índice separado aponta para posições no arquivo.
O SO lê o índice primeiro, depois vai direto ao dado.
Ideal para: grandes bancos de dados, arquivos ISAM.
Índice: Arquivo:
[chave:pos] [ dados ]
["ana": 0] --> [dados_ana|dados_bob|dados_carlos]
["bob": 100] --> ^
["carlos":200] |
lseek(100)
0 (stdin), 1 (stdout), 2 (stderr). O open() retorna o próximo FD livre. Como "tudo é arquivo", sockets de rede, pipes, e devices também são FDs.
Tipos de Arquivo no Unix
$ ls -la /dev/ /tmp/ /etc/ | head -20
# Tipo indicado pelo primeiro caractere de ls -l:
# - arquivo regular (texto, binário, imagem)
# d diretório (contém referências a outros arquivos)
# l symbolic link (ponteiro para outro arquivo)
# c character device (/dev/tty, /dev/null)
# b block device (/dev/sda, /dev/nvme0n1)
# p named pipe (FIFO) (comunicação entre processos)
# s socket (comunicação de rede local)
# Exemplos práticos:
$ file /bin/ls # ELF 64-bit executable
$ file /etc/hostname # ASCII text
$ file /dev/null # character special
$ file /dev/sda # block special
No harness.os
O Scale 1 do harness.os é literalmente um sistema de arquivos. A estrutura de diretórios de um projeto é o harness mais básico:
Scale 1 Harness = Filesystem Design
====================================
projeto/
+-- CLAUDE.md = /etc/init.d (config de boot)
| Lido no início de cada sessão.
|
+-- .claude/
| +-- settings.json = /etc/sysctl.conf (config do kernel)
|
+-- rules/ = /etc/rules.d/ (regras de comportamento)
| +-- commit-hygiene.md = regra específica
| +-- testing.md = regra específica
|
+-- knowledge/ = /usr/share/doc/ (dados de referência)
| +-- architecture.md = documentação carregável
| +-- api-reference.md = documentação carregável
|
+-- workflows/ = /usr/bin/ (scripts executáveis)
+-- deploy.md = processo passo-a-passo
+-- qa-gate.md = processo passo-a-passo
Operações de arquivo no harness:
open() = start_session() lê CLAUDE.md
read() = get_knowledge() lê um arquivo de knowledge
write() = log_learning() cria/atualiza um arquivo
stat() = list_knowledge() lista metadados
unlink()= (raro) remover knowledge obsoleto
Método de acesso:
Scale 1 = acesso sequencial (agente lê CLAUDE.md inteiro)
Scale 2 = acesso indexado (MCP query por concern/domain)
import os
class HarnessFS:
"""Scale 1 harness como operações de filesystem."""
def __init__(self, project_root):
self.root = project_root
def open_config(self):
"""open() + read() do CLAUDE.md"""
path = os.path.join(self.root, "CLAUDE.md")
with open(path) as f:
return f.read()
def list_knowledge(self):
"""readdir() do diretório knowledge/"""
kdir = os.path.join(self.root, "knowledge")
return os.listdir(kdir) if os.path.exists(kdir) else []
def read_knowledge(self, name):
"""open() + read() de um knowledge chunk"""
path = os.path.join(self.root, "knowledge", name)
with open(path) as f:
return f.read()
def write_learning(self, name, content):
"""open() + write() para um novo learning"""
path = os.path.join(self.root, "knowledge", name)
with open(path, "w") as f:
f.write(content)
A transição de Scale 1 (arquivos) para Scale 2 (MCP + banco) é equivalente à transição de acesso sequencial para acesso indexado. No Scale 1, o agente lê o CLAUDE.md inteiro (sequencial). No Scale 2, consulta por concern ou domain (indexado, muito mais eficiente).
Homework
- Escreva um programa em C que cria um arquivo, escreve 100 bytes, faz
lseek()para a posição 50, lê 10 bytes, e imprime. Observe a diferença entre acesso sequencial e random. - Liste todos os tipos de arquivo em
/dev/da sua máquina usandols -la /dev/ | cut -c1 | sort | uniq -c. - No harness.os, desenhe a estrutura de diretórios ideal para um novo projeto usando Scale 1 (apenas arquivos, sem banco). Que arquivos você criaria em
rules/,knowledge/, eworkflows/?
Resumo
- Arquivo = abstração do SO para dados persistentes
- Atributos: nome, tipo, tamanho, permissões, timestamps, inode
- Operações: open, read, write, seek, close, unlink
- Métodos de acesso: sequencial, direto (random), indexado
- Unix: "tudo é arquivo" — devices, pipes, sockets são FDs
Verifique seu entendimento
Quais são os três file descriptors que todo processo Unix herda automaticamente ao nascer?