Instanciar um objeto File a partir de um array de bytes sem gerar o arquivo físico na máquina?

6 respostas
X

Boa noite colegas.

É possível instanciar um objeto File a partir de um array de bytes sem gerar o arquivo físico na máquina ?

Estou perguntando isso porque estou fazendo manutenção em um sistema e nele existe uma rotina que gostaria de aproveitá-la, e essa rotina recebe como parâmetro de entrada um objeto File. No meu caso teria apenas o array de bytes do arquivo disponível. Entendo que teria que convertê-lo em um objeto do tipo File, por exemplo

File arquivo = new File(“c:\exemplo.pdf”)

A questão é que não gostaria de gerar um arquivo físico na máquina.

6 Respostas

D

Leia por si próprio

G

A primeira frase já diz tudo:

An abstract representation of file and directory pathnames.

Ou seja, o objeto File é simplesmente a representação de um CAMINHO no sistema de arquivos; pode parecer estranho, mas ele não tem a ver com dados ou conteúdo. Não são a mesma coisa, por isso não dá para fazer dessa maneira que você está pensando.

[color=red]O que não significa que você não pode (e deve!) reaproveitar a rotina existente, mas vai precisar de algumas pequenas modificações.[/color]

X

gomesrod, obrigado por seu interesse em responder, mas gostaria de uma “luz” para resolver esse problema.
Que tipo de modificações poderia fazer para passar esse array de bytes que representa o arquivo para a rotina ? Pelo que vi vc deve ter bastante experiencia e antes de postar pesquisei e li bastante sobre as funçoes que envolvem manipulação de arquivos e não consegui descobrir uma maneira.

G

As modificações dependem de como essa rotina está feita. O que precisa é modifica-la para receber uma entrada de dados independente, ao invés de objeto File que só permite utilizá-la com dados gravados em arquivos físicos.

Vou dar um exemplo:

Suponha que a rotina seja algo assim:

void fazAlgumaCoisa(File f) {
        // ... faz alguma coisa ...

        // Instancia um stream para leitura do arquivo
        InputStream input = new FileInputStream(f);

        // ...

        while (/*..alguma condiçao...*/) {
             // Le o arquivo atraves do input stream
             variavel = input.read();

             // ..... Faz alguma coisa com os bytes lidos .....
        }

        // Fecha o arquivo
        input.close();
}

O que se quer é que essa rotina não dependa de arquivo físico. Como fazer isso? Passando uma fonte de dados independente, que pode vir de qualquer lugar, de um arquivo, de um socket na rede, ou de um array de bytes que já tenho carregado.
Então nada melhor que passar o próprio InputStream, pois é uma interface que pode ser conectada a qualquer tipo de origem de dados.

void fazAlgumaCoisa(InputStream input) {
        // ... faz alguma coisa ...

        // O Stream  foi passado pronto, então é  ler!

        while (/*..alguma condiçao...*/) {
             // Le o arquivo atraves do input stream
             variavel = input.read();

             // ..... Faz alguma coisa com os bytes lidos .....
        }

        // Fecha o arquivo
        input.close();
}
Então você chama a função assim:
byte[] meuArray = ...// Obtenho o array da forma que está funcionando hoje.
InputStream input = new ByteArrayInputStream(meuArray); // Esse é um inputStream que está conectado ao array de bytes, ou seja, serve para ler seu conteúdo
fazAlgumaCoisa(input); // Chamo a rotina anterior

Mas quando fiz isso começou a dar pau em um monte de lugares onde essa rotina era chamada antes, passando um File como parâmetro! :shock:
Essa parte é fácil de resolver, é só criar um outro método para atender a funcionalidade já existente, mas sem duplicar o código. Ele seria assim:

void fazAlgumaCoisa(File f) {
        InputStream input = new FileInputStream(f);  // Cria um inputStream a partir do arquivo
        fazAlgumaCoisa(input);       // Chama a função anterior, reaproveitando todo o código sem duplicá-lo.
}
Funcionalmente esse método é idêntico àquele primeiro, mas a diferença é que agora existe também a outra forma de chama-lo, que é mais genérica permitindo o uso de outras origens de dados.

-------------------------------------------
Concluindo:
Usei aqui um exemplo em que a refatoração a ser feita era razoavelmente óbvia, a alteração específica no seu caso depende do que a rotina faz, mas já serve para dar uma direção sobre como analisar o caso!

X

obrigado pelo direcionamento gomesrod.
é com pessoas como vc que compartilham suas experiências que aprendemos e quem sabe um dia chegar a seu nível e tb poder ajudar outras pessoas que estão começando.

G

Fiquei vermelho kkkk

Depois posta a conclusão do caso , isso faz parte do aprendizado das próximas pessoas que visitarem o tópico!

Criado 14 de novembro de 2012
Ultima resposta 21 de nov. de 2012
Respostas 6
Participantes 3