Pular para o conteúdo principal

Manipulação de Arquivos e Pastas

Introdução

No código de backend poliglota da plataforma Netuno, podemos manipular qualquer arquivo ou pasta.

A manipulação consiste em poder criar, renomear e deletar os arquivos e pastas, alterar o conteúdo de arquivos e listar o conteúdo de pastas. No geral são estas as operações que normalmente precisamos fazer programaticamente.

Na plataforma Netuno há recursos de programação low-code que permite manipular as pastas e os arquivos internos da aplicação, mas também quaisquer arquivos e pastas do sistema no geral, isto é fora da aplicação.

É útil quando precisamos automatizar algum processo que precisa mexer em algum arquivo qualquer, vamos ver como.

Os recurso de programação poliglota low-code que permite manipular arquivos, são:

Através destes recursos temos os métodos para:

  • .file - Arquivo existente.
  • .folder - Pasta existente.
  • .path - Caminho genérico, tanto pode ser um arquivo como uma pasta, que existe ou que não existe.

Com estes métodos obtemos um objeto do tipo File, que fornece todos os meios para manipulações de arquivos, pastas e caminhos no geral, o que permite realizar operações como:

  • Criar arquivos e pastas.
  • Apagar arquivos e pastas.
  • Listar o conteúdo das pastas.
  • Renomear arquivos e pastas.
  • Ler e escrever dados em arquivos.
  • Eliminar pastas e as suas respectivas subpastas e arquivos recursivamente.

Aplicação

Para realizar as operações principais de manipulação de arquivos e pastas dentro da estrutura da aplicação, utilizamos o recurso _app:

Pastas na Aplicação

Garante que é obtida uma pasta que existe, por exemplo:

const minhaPasta = _app.folder("minha/pasta")

Arquivos na Aplicação

Garante que é obtido um arquivo que existe, por exemplo:

const meuArquivo = _app.file("minha/pasta/arquivo.txt")

Caminhos na Aplicação

Obtém um caminho de arquivo ou pasta, independente se existe ou não, por exemplo:

const novoArquivo = _app.path("minha/pasta/novo-arquivo.txt")

Storage

Para realizar as operações principais de manipulação de arquivos e pastas dentro da pasta 📁 storage da aplicação, utilizamos o recurso _storage:

Pastas no Storage

Garante que é obtida uma pasta que existe, por exemplo:

// O caminho real da pasta será:
// storage/filesystem/server/minha/pasta
const storageMinhaPasta = _storage.filesystem("server", "minha/pasta")
const minhaPasta = storageMinhaPasta.folder()

Arquivos no Storage

Garante que é obtido um arquivo que existe, por exemplo:

// O caminho real do arquivo será:
// storage/filesystem/server/minha/pasta/arquivo.txt
const storageArquivo = _storage.filesystem("server", "minha/pasta", "arquivo.txt")
const arquivo = storageArquivo.file()

Caminhos no Storage

Obtém um caminho de arquivo ou pasta, independente se existe ou não, por exemplo:

// O caminho real do arquivo será:
// storage/filesystem/server/minha/nova-pasta
const storagePasta = _storage.filesystem("server", "minha/nova-pasta")
const pasta = storagePasta.path()

// O caminho real do arquivo será:
// storage/filesystem/server/minha/pasta/novo-arquivo.txt
const storageArquivo = _storage.filesystem("server", "minha/pasta", "novo-arquivo.txt")
const arquivo = storageArquivo.path()

Sistema Operacional

Para realizar as operações principais de manipulação de arquivos e pastas em qualquer lugar no sistema operacional, utilizamos o recurso _os:

Pastas no Sistema Operacional

Garante que é obtida uma pasta que existe, por exemplo:

const minhaPasta = _os.folder("/tmp/minha/pasta")

Arquivos no Sistema Operacional

Garante que é obtido um arquivo que existe, por exemplo:

const meuArquivo = _os.file("/tmp/minha/pasta/arquivo.txt")

Caminhos no Sistema Operacional

Obtém um caminho de arquivo ou pasta, independente se existe ou não, por exemplo:

const novoArquivo = _os.path("/tmp/minha/pasta/novo-arquivo.txt")

Criar Pastas

O método mkdir cria uma pasta específica na raíz da aplicação:

const pasta = _app.path("temp")
pasta.mkdir()

Para criar uma subpasta pasta basta indicar a seguir a /:

const pasta = _app.path("temp/outra")
pasta.mkdir()

Já o mkdirs, cria as pastas anteriores e/ou as subpastas caso não existam, então permite criar uma estrutura de pastas na aplicação, por exemplo:

const pastas = _app.path("temp/a/b/c")
pastas.mkdirs()

O recurso _storage tem o método ensurePath que verifica se o caminho existe, caso não exista então cria:

const arquivo = _storage.filesystem(
"public",
"temp/subpasta",
"arquivo.txt"
)
// Cria a estrutura de pastas caso não exista:
arquivo.ensurePath()

Portanto o ensurePath garante que a estrutura de pastas exista.

Eliminar Arquivos e Pastas

Com o método delete podemos tanto remover pastas como arquivos, sendo que as pastas devem estar vazias, veja o exemplo:

// Remove uma pasta vazia:
const pastaVazia = _app.folder("pasta/vazia")
pastaVazia.delete()

// Remove um caminho:
const arquivo = _app.file("pasta/arquivo.txt")
arquivo.delete()

// Remove um caminho, pasta vazia ou arquivo:
const caminho = _app.path("pasta1/arquivo-ou-pasta-vazia")
caminho.delete()

Com o deleteAll permite eliminar tudo, ou seja, todos os arquivos, pastas e subpastas recursivamente:

// Remove a pasta e todo o conteúdo recursivamente:
const pastaVazia = _app.folder("pasta/exemplo")
pastaVazia.deleteAll()

// Remove o caminho de uma pasta e todo o seu conteúdo interno,
// incluindo subpastas e arquivos:
const caminho = _app.path("caminho/pasta")
caminho.deleteAll()

Para eliminar apenas os arquivos dentro da pasta e não apagar nada nas subpastas, temos o deleteFiles, que permite receber uma extensão caso queira remover apenas arquivos com uma extensão específica:

// Remove os arquivos apenas dentro da pasta:
const pasta = _app.folder("pasta/exemplo")
pasta.deleteFiles()

// Remove os arquivos com a extensão JPG apenas dentro da pasta:
const caminho = _app.path("caminho/pasta")
caminho.deleteFiles("jpg")

Para eliminar apenas os arquivos recursivamente e manter a estrutura de pastas, temos o deleteAllFiles, que também permite receber uma extensão caso queira remover apenas um tipo de arquivo específico, veja estes dois exemplos:

// Remove todos os arquivos dentro da pasta e subpastas:
const pasta = _app.folder("pasta/exemplo")
pasta.deleteAllFiles()

// Remove todos os arquivos com a extensão JPG dentro da pasta e subpastas:
const caminho = _app.path("caminho/pasta")
caminho.deleteAllFiles("jpg")

Renomear ou Mover

Para mover uma pasta, é o mesmo que renomeá-la:

const folder = _app.folder("temp")
folder.renameTo("test")

Para renomear uma pasta e mudá-la de nível na hierarquia de pastas, é o mesmo que mover a pasta:

const folder = _app.folder("temp/a/b")
folder.renameTo("test/z")

E para mover uma subpasta sem mudar o seu nome, basta indicar o novo caminho no método renameTo:

const folder = _app.folder("test/outra")
folder.renameTo("outra")

Salvar Conteúdos em Arquivos

A geração de conteúdos em arquivos é feita através do método output que fornece um objeto do tipo OutputStream.

Para escrever os dados no output utilizamos o método printAndClose, que imprime o conteúdo no arquivo e fecha o arquivo salvando o conteúdo.

Escrever Arquivo de Texto

Veja o exemplo de como criar um arquivo com conteúdo de texto:

_app.path("temp").mkdir()
const escrita = _app.path("temp/arquivo.txt").output()
escrita.printAndClose("Meu texto aqui...")

Sempre que utilizamos o output é gerado um novo arquivo, portanto se executar o código novamente o arquivo será recriado.

Escrever arquivo JSON

Veja como podemos salvar dados JSON em arquivos:

_app.path("temp").mkdir()
const escrita = _app.path("temp/cliente.json").output()
escrita.printAndClose(
_val.map()
.set("nome", "Maria Joaquina")
.set(
"registros",
_val.list()
.add(1).add(2).add(3)
)
.toJSON()
)

Para gerar o JSON indentado, ou seja, formatado em várias linhas e tabulado, podemos passar o número de espaços que será feita a tabulação por exemplo .toJSON(4).

Mais detalhes sobre o método toJSON em Values.

Ler Conteúdos em Arquivos

A obtenção de conteúdos em arquivos é feita através do método input que fornece um objeto do tipo InputStream.

Para ler os dados no input utilizamos o método readAllAndClose, que processa a leitura do conteúdo no arquivo e fecha o arquivo.

Ler Arquivo de Texto

Veja o exemplo de como ler um arquivo e obter o conteúdo de texto:

const arquivo = _app.file("temp/arquivo.txt")
const leitura = arquivo.input()
_log.info(leitura.readAllAndClose())

Ler arquivo JSON

Veja como podemos processar dados JSON obtidos em arquivos:

const arquivo = _app.file("temp/arquivo.txt")
const leitura = arquivo.input()
const dados = _val.fromJSON(leitura.readAllAndClose())
_log.info("Dados do Arquivo:", dados)

Mais detalhes sobre o método fromJSON do recurso Val.

Particularidades do Storage

O recurso storage tem alguns métodos para utilização direta.

Por exemplo, podemos aceder através do storage:

Isto quer dizer que não precisamos obter o file ou path para trabalhar com o input ou output.

Escrever Arquivo de Texto no Storage

Ao iniciar um storage para um arquivo podemos realizar a escrita utilizando o método output, que obtém uma instância do objeto OutputStream que permite processar e ler os dados.

Então com o OutputStream o método printAndClose, faz a escrita de texto (string) no arquivo e fecha-o.

Veja este exemplo:

const txt = _storage.filesystem("server", "temp", "arquivo.txt")
txt.ensurePath()
txt.output().printAndClose("Meu texto aqui...")

Ler Arquivo de Texto no Storage

Ao iniciar um storage para um arquivo podemos realizar a leitura utilizando o método input, que obtém uma instância do objeto InputStream que permite processar e ler os dados.

Então com o InputStream o método readAllAndClose, faz a leitura de todo arquivo e fecha-o, retornando os dados como texto (string).

Veja este exemplo:

const txt = _storage.filesystem("server", "temp", "arquivo.txt")
_log.info(txt.input().readAllAndClose())

Criar arquivo aleatório no Storage

O recurso _storage permite gerar nomes de arquivos aleatórios, com o método newRandomFile.

Deve iniciar um storage para o caminho de uma pasta, e ao executar o método newRandomFile é passado a extensão do arquivo pretendido.

O método retorna uma nova instância do storge para o arquivo randômico gerado automaticamente para ser utilizado na pasta inicial.

Veja como gerar um arquivo com extensão TXT com nome randômico:

const pasta = _storage.filesystem("server", "temp")
const arquivo = pasta.newRandomFile("txt")
arquivo.output().printAndClose("Meu texto aqui...")

Conclusão

Com a framework low-code poliglota do Netuno podemos realizar todas as principais operações de pastas e arquivos diretamente.

Ao utilizar os recursos específicos para manipular arquivos e pastas na:

  • _app - Aplicação
  • _storage - Storage da Aplicação
  • _os - Sistema Operacional

Por questões de boas práticas e organização devemos priorizar a utilização do storage, as exceções devem ser apenas casos pontuais e estritamente necessários.

O Netuno processa o fecho automático dos inputs e outputs no fim do processamento dos serviços, mas por boas práticas devemos tentar fechá-los sempre.