Modo de abertura de arquivo em Ruby/Python e etc
No momento que escrevo esse post estou ensinando os meus alunos a trabalhar com os arquivos e isso é muito legal, porque quando você compreende como funciona a abertura de arquivos e a manipulação desses dados pela linguagem alvo, você compreende a teoria da computação que tudo é uma string com diversos escaping que lhe permitirá converter para diversos tipos de arquivo, como csv, json, xml e etc, você vai escolher.
Vamos por parte, primeiro é importante compreendermos uma tabela com os modos de abertura e depois eu retorno código para você.
Modo | Descrição | Ruby | Python | Go | C | Java | Node.js |
---|---|---|---|---|---|---|---|
r |
Abre o arquivo apenas para leitura. | ✔️ | ✔️ | ✔️ | ✔️ | FileInputStream | fs.openSync/readFileSync |
w |
Abre o arquivo para escrita, truncando o arquivo existente. | ✔️ | ✔️ | ✔️ | ✔️ | FileOutputStream | fs.openSync/writeFileSync |
a |
Abre o arquivo para escrita, adicionando ao final sem truncar. | ✔️ | ✔️ | ✔️ | ✔️ | FileOutputStream (Append) | fs.appendFileSync |
r+ |
Abre o arquivo para leitura e escrita, sem truncar. | ✔️ | ✔️ | ❌ | ✔️ | RandomAccessFile | fs.openSync |
w+ |
Abre o arquivo para leitura e escrita, truncando o existente. | ✔️ | ✔️ | ❌ | ✔️ | RandomAccessFile | fs.openSync |
a+ |
Abre o arquivo para leitura e escrita, adicionando ao final. | ✔️ | ✔️ | ❌ | ✔️ | RandomAccessFile | fs.openSync |
Diferenças e Particularidades
-
Ruby e Python:
- Ambas as linguagens possuem suporte completo para os modos listados, utilizando bibliotecas padrão (
csv
em Ruby eopen
em Python). - Utilizam sintaxes e APIs similares para manipulação de arquivos, facilitando operações como leitura, escrita e anexação.
- Ambas as linguagens possuem suporte completo para os modos listados, utilizando bibliotecas padrão (
-
Go:
- Não possui um equivalente direto para os modos
r+
,w+
,a+
como operações únicas. Utiliza diferentes funções para abertura e manipulação de arquivos (os.Open
,os.Create
). - Foco em performance e segurança, com tratamento explícito de erros.
- Não possui um equivalente direto para os modos
-
C:
- Oferece funções como
fopen
,fread
,fwrite
com suporte aos modos via strings ("r", "w", "a" etc.). - Exige gerenciamento manual de recursos, como fechar arquivos explicitamente.
- Oferece funções como
-
Java:
- Não usa os mesmos modos de string; em vez disso, utiliza classes específicas como
FileInputStream
,FileOutputStream
eRandomAccessFile
para diferentes operações. RandomAccessFile
permite leitura e escrita com acesso direto, semelhante aos modosr+
,w+
,a+
.
- Não usa os mesmos modos de string; em vez disso, utiliza classes específicas como
-
Node.js:
- Utiliza funções do módulo
fs
comofs.openSync
,fs.readFileSync
para operações sincronizadas. - Modos como
r+
,w+
,a+
são especificados como strings em chamadas de função.
- Utiliza funções do módulo
Dito isso, você precisará sempre compreender o seu problema e o como irá solucionar-ló. Perceba que os modos dirá se seu arquivo será alterado, será truncado, truncado no contexto de arquivos, estamos dizendo que será removido todo o conteúdo do arquivo atual e será alterado para um dado novo.
Quer codificar um pouco comigo? jaja, vamos lá, em Ruby:
require 'csv'
def add_entry_to_large_csv(file_path, id, name, email)
CSV.open(file_path, 'a') do |csv|
csv << [id, name, email]
end
end
# Exemplo de uso
file_path = 'large_data.csv'
add_entry_to_large_csv(file_path, "004", "Jane Doe", "[email protected]")
Lendo a nossa tabela, com o modo a
, poderemos adicionar ao final da última linha e inserir um dado de maneira segura, sem truncar (remover) os dados anteriores.
Exemplo em python:
import csv
def add_entry_to_large_csv(file_path, id, name, email):
with open(file_path, mode='a', newline='') as file:
writer = csv.writer(file)
writer.writerow([id, name, email])
# Exemplo de uso
file_path = 'large_data.csv'
add_entry_to_large_csv(file_path, "004", "Jane Doe", "[email protected]")
Exemplo em Go:
package main
import (
"encoding/csv"
"os"
)
func addEntryToLargeCSV(filePath, id, name, email string) {
file, err := os.OpenFile(filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
panic(err)
}
defer file.Close()
writer := csv.NewWriter(file)
defer writer.Flush()
if err := writer.Write([]string{id, name, email}); err != nil {
panic(err)
}
}
func main() {
filePath := "large_data.csv"
addEntryToLargeCSV(filePath, "004", "Jane Doe", "[email protected]")
}
Na linguagem Go especifica as permissões do arquivo e é baseado no sistema de permissões Unix. Essas permissões determinam quem pode ler, escrever ou executar o arquivo e são definidas usando um sistema de codificação octal. No código, onde você verifica: 0644, é a representação das permissões. Aqui está como as permissões são atribuídas e o que cada número representa:
Permissões no Sistema Unix
- 0: Nenhuma permissão
- 1: Permissão de execução
- 2: Permissão de escrita
- 4: Permissão de leitura
Em Node por exemplo:
const fs = require('fs');
const csvWriter = require('csv-write-stream');
function addEntryToLargeCSV(filePath, id, name, email) {
const writer = csvWriter({ sendHeaders: false });
writer.pipe(fs.createWriteStream(filePath, { flags: 'a' }));
writer.write({ id, name, email });
writer.end();
}
// Exemplo de uso
const filePath = 'large_data.csv';
addEntryToLargeCSV(filePath, "004", "Jane Doe", "[email protected]");
De modo geral, eu desejei mostrar que as linguagens sempre precisam dessa segurança e que elas fazem com que possamos criar regras de negócios que proteja nosso arquivo de ações indesejadas como excluir o conteúdo durante uma inserção.