LISP - Arquivo I / O

Discutimos sobre como a entrada e a saída padrão são tratadas pelo LISP comum. Todas essas funções funcionam para ler e escrever em arquivos de texto e binários também. A única diferença é, neste caso, o fluxo que usamos não é uma entrada ou saída padrão, mas um fluxo criado com o propósito específico de escrever ou ler arquivos.

Neste capítulo, veremos como o LISP pode criar, abrir, fechar texto ou arquivos binários para seu armazenamento de dados.

Um arquivo representa uma seqüência de bytes, não importa se é um arquivo de texto ou binário. Este capítulo o levará através de funções / macros importantes para o gerenciamento de arquivos.

Abrindo arquivos

Você pode usar o openfunção para criar um novo arquivo ou para abrir um arquivo existente. É a função mais básica para abrir um arquivo. No entanto, owith-open-file geralmente é mais conveniente e mais comumente usado, como veremos mais adiante nesta seção.

Quando um arquivo é aberto, um objeto de fluxo é construído para representá-lo no ambiente LISP. Todas as operações no stream são basicamente equivalentes às operações no arquivo.

Sintaxe para o open função é -

open filename &key :direction :element-type :if-exists :if-does-not-exist :external-format

Onde,

  • O argumento filename é o nome do arquivo a ser aberto ou criado.

  • Os argumentos de palavra-chave especificam o tipo de fluxo e as formas de tratamento de erros.

  • o :direction palavra-chave especifica se o fluxo deve lidar com entrada, saída ou ambos, leva os seguintes valores -

    • : entrada - para fluxos de entrada (valor padrão)

    • : saída - para fluxos de saída

    • : io - para fluxos bidirecionais

    • : probe - para apenas verificar a existência de arquivos; o fluxo é aberto e depois fechado.

  • o :element-type especifica o tipo da unidade de transação do fluxo.

  • o :if-existsargumento especifica a ação a ser tomada se: direction for: output ou: io e um arquivo com o nome especificado já existir. Se a direção for: input ou: probe, este argumento é ignorado. Leva os seguintes valores -

    • : erro - sinaliza um erro.

    • : nova versão - cria um novo arquivo com o mesmo nome, mas com um número de versão maior.

    • : renomear - renomeia o arquivo existente.

    • : renomear e excluir - renomeia o arquivo existente e depois o exclui.

    • : anexar - anexa ao arquivo existente.

    • : substitui - substitui o arquivo existente.

    • nil - não cria um arquivo ou mesmo um fluxo apenas retorna nil para indicar falha.

  • o :if-does-not-existargumento especifica a ação a ser executada se um arquivo com o nome especificado ainda não existir. Leva os seguintes valores -

    • : erro - sinaliza um erro.

    • : create - cria um arquivo vazio com o nome especificado e o usa.

    • nil - ele não cria um arquivo ou mesmo um fluxo, mas simplesmente retorna nil para indicar falha.

  • o :external-format argumento especifica um esquema reconhecido pela implementação para representar caracteres em arquivos.

Por exemplo, você pode abrir um arquivo chamado myfile.txt armazenado na pasta / tmp como -

(open "/tmp/myfile.txt")

Gravando e lendo de arquivos

o with-open-filepermite a leitura ou gravação em um arquivo, usando a variável stream associada à transação de leitura / gravação. Assim que o trabalho for concluído, ele fecha automaticamente o arquivo. É extremamente conveniente de usar.

Possui a seguinte sintaxe -

with-open-file (stream filename {options}*)
   {declaration}* {form}*
  • filename é o nome do arquivo a ser aberto; pode ser uma string, um nome de caminho ou um fluxo.

  • As opções são iguais aos argumentos de palavra-chave para a função aberta.

Exemplo 1

Crie um novo arquivo de código-fonte denominado main.lisp e digite o seguinte código nele.

(with-open-file (stream "/tmp/myfile.txt" :direction :output)
   (format stream "Welcome to Tutorials Point!")
   (terpri stream)
   (format stream "This is a tutorials database")
   (terpri stream)
   (format stream "Submit your Tutorials, White Papers and Articles into our Tutorials   Directory.")
)

Observe que todas as funções de entrada-saída discutidas no capítulo anterior, como terpri e formato, estão funcionando para escrever no arquivo que criamos aqui.

Quando você executa o código, ele não retorna nada; no entanto, nossos dados são gravados no arquivo. o:direction :output palavras-chave nos permitem fazer isso.

No entanto, podemos ler este arquivo usando o read-line função.

Exemplo 2

Crie um novo arquivo de código-fonte denominado main.lisp e digite o seguinte código nele.

(let ((in (open "/tmp/myfile.txt" :if-does-not-exist nil)))
   (when in
      (loop for line = (read-line in nil)
      
      while line do (format t "~a~%" line))
      (close in)
   )
)

Quando você executa o código, ele retorna o seguinte resultado -

Welcome to Tutorials Point!
This is a tutorials database
Submit your Tutorials, White Papers and Articles into our Tutorials Directory.

Fechando Arquivo

o close função fecha um fluxo.