Cópia de arquivo via java

19 respostas
Renato_Teixeira

Pessoal,

Boa Tarde,

Estou com uma dúvida, existe alguma maneira de eu copiar um arquivo de um diretório para outro via código?

O cenário é o seguinte, preciso criar uma aplicação que pegue determinado arquivo de um diretório (EX.: C:) e copie ele para outro diretório (Ex.: D:) alguém poderia me ajudar?

Muito Obrigado.

Abs

19 Respostas

M

pesquise sobre InputStream e OutputStream.

Rush x)

Felagund

Pesquise pelo NIO, FileChannel e afins, é uma API muito melhor em performance que a API padrão de IO com seus InputStreams

Jose111

Ótimo link sobre o assunto : http://www.exampledepot.com/egs/java.io/pkg.html

ViniGodoy
public static void copyFile(File source, File destination) throws IOException {
        if (destination.exists())
            destination.delete();

        FileChannel sourceChannel = null;
        FileChannel destinationChannel = null;

        try {
            sourceChannel = new FileInputStream(source).getChannel();
            destinationChannel = new FileOutputStream(destination).getChannel();
            sourceChannel.transferTo(0, sourceChannel.size(),
                    destinationChannel);
        } finally {
            if (sourceChannel != null && sourceChannel.isOpen())
                sourceChannel.close();
            if (destinationChannel != null && destinationChannel.isOpen())
                destinationChannel.close();
       }
   }
Renato_Teixeira

Obrigado a todos pelas respostas, vamos a alguns comentários:

Jose111: Seu link é fantástico consegui utilizar várias coisas dele, mas no que eu realmente preciso no caso deste post deu alguns probleminhas...

void copy(File src, File dst) throws IOException {
        InputStream in = new FileInputStream(src);
        OutputStream out = new FileOutputStream(dst);

        // Transfer bytes from in to out
        byte[] buf = new byte[1024];
        int len;
        while ((len = in.read(buf)) > 0) {
            out.write(buf, 0, len);
        }
        in.close();
        out.close();
    }

Quando ele chega na linha: OutputStream out = new FileOutputStream(dst); ele ao invés de pular para a próxima ele volta para a classe que a chamou ...

segue o código que chama este método:

File src = new File("c:/UP.rar");
        File dst = new File("g:/");
        try{
            CL_Copia Copia = new CL_Copia();
            Copia.copy(src, dst);
        }
        catch(IOException e){
        }

ViniGodoy: no seu código aconteceu o seguinte, eu copiei e colei seu código mas deu alguns probleminhas:

public static void copyFile(File source, File destination) throws IOException {   
     if (destination.exists())   
         destination.delete();   
  
     FileChannel sourceChannel = null;   
     FileChannel destinationChannel = null;   
  
     try {   
         sourceChannel = new FileInputStream(source).getChannel();   
         destinationChannel = new FileOutputStream(destination).getChannel();   
         sourceChannel.transferTo(0, sourceChannel.size(),   
                 destinationChannel);   
     } finally {   
         if (sourceChannel != null && sourceChannel.isOpen())   
             sourceChannel.close();   
         if (destinationChannel != null && destinationChannel.isOpen())   
             destinationChannel.close();   
    }   
}

Ele esta dando uma mensagem para as linhas:

FileChannel sourceChannel = null;
FileChannel destinationChannel = null;

Alguém pode me ajudar?

Abs

ViniGodoy

Que erro deu?

Esse é exatamente o método que eu uso! Eu simplesmente recortei e colei o código do meu projeto!

Você deu
impot java.nio.channels.FileChannel;

No início do seu módulo?

Renato_Teixeira

ViniGodoy:

Deu certo não tava importando mesmo…mas agora to com este erro:

<blockquote>debug:

java.io.FileNotFoundException: c:\teste (Acesso negado)

at java.io.FileOutputStream.open(Native Method)

at java.io.FileOutputStream.(FileOutputStream.java:179)

at java.io.FileOutputStream.(FileOutputStream.java:131)

at tcm_redeso

at tcm_redesocial.CL_Copia.copyFile(CL_Copia.java:61)

at tcm_redesocial.IC_Login.btnOkActionPerformed(IC_Login.java:186)

at tcm_redesocial.IC_Login.access$000(IC_Login.java:12)

at tcm_redesocial.IC_Login$1.actionPerformed(IC_Login.java:94)

at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)

at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)

at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)

at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)

at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)

at java.awt.Component.processMouseEvent(Component.java:6216)

at javax.swing.JComponent.processMouseEvent(JComponent.java:3265)

at java.awt.Component.processEvent(Component.java:5981)

at java.awt.Container.processEvent(Container.java:2041)

at java.awt.Component.dispatchEventImpl(Component.java:4583)

at java.awt.Container.dispatchEventImpl(Container.java:2099)

at java.awt.Component.dispatchEvent(Component.java:4413)

at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4556)

at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4220)

at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4150)

at java.awt.Container.dispatchEventImpl(Container.java:2085)

at java.awt.Component.dispatchEvent(Component.java:4413)

at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)

at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)

at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)

at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)

at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)

at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)

at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

</blockquote>

Pode me ajudar?

Abs

ViniGodoy

Esse erro veio do sistema operacional, e disse que o acesso ao arquivo foi negado.

Verifique se o arquivo não estava em uso, se o diretório é acessível, se o arquivo existe mesmo, etc.

Renato_Teixeira

ViniGodoy,

Consegui fazer copiar, eu estava no source setando o caminho do arquivo, mas no destino eu só colocava a pasta ae dava erro, agora junto a pasta eu coloco também o nome do arquivo, de uma olhada:

File src = new File("c:/UP.rar"); File dst = new File("c:/teste/UP.rar");

Agora tenho uma dúvida, onde ele pesquisa para saber se o arquivo já existe? pois eu queria colocar uma mensagem se caso existisse que não pode copiar… você consegue me ajudar?

Abs.

ViniGodoy
if (!src.exists()) {
    System.out.println("O arquivo não existe!");
    return;
}
romuloff

ViniGodoy:
Esse erro veio do sistema operacional, e disse que o acesso ao arquivo foi negado.

Verifique se o arquivo não estava em uso, se o diretório é acessível, se o arquivo existe mesmo, etc.

Olá Vini;

Como seria essa parte de verificar se o arquivo não está em uso por outro processo que não seja o java ?
Estou precisando disso pra ontem e já estou procurando algo há algumas horas; sem sucesso.

romuloff

[size=18][color=blue]VERIFICAÇÃO DE ARQUIVO EM USO RESOLVIDA [ resolvido ][/color][/size]

Fiz assim (solução a ser aprimorada futuramente):
/**
     * Test the lock and release of file
     * 
     * @param file the file to test
     * 
     * @return true if lock and release succeeds; false if the file doesnt exist or is locked by another proccess
     */
    public static boolean lockFile(File file) {

        FileChannel channel = null;

        try {

            channel = new RandomAccessFile(file, "rw").getChannel();

            // This method blocks until it can retrieve the lock.
            FileLock lock = channel.lock();

            // Try acquiring the lock without blocking. This method returns
            // null or throws an exception if the file is already locked.
            try {
                lock = channel.tryLock();
            }
            catch (OverlappingFileLockException e) {
                // File is already locked in this thread or virtual machine
                LOGGER.info("File is locked as expected");
            }

            lock.release();

        }
        catch (FileNotFoundException fnfe) {
            LOGGER.error(fnfe.toString());
        }
        catch (Exception e) {
            LOGGER.error(e.toString());
        }
        finally {
            if (channel == null) {
                LOGGER.warn("Arquivo não existe ou esta em uso por outro processo !");
                return false;
            }
            else {
                LOGGER.info("Closing FileChannel");
                try {
                    channel.close();
                }
                catch (IOException ioe) {
                    LOGGER.error(ioe.toString());
                }
            }
        }
        return true;
    }

baseei-me aqui . ++

ks: java unlock file ; java verify use file ; java check "in use" file ; java "being used" file ; FileHandler ; arquivo "em uso" ; arquivo "sendo usado" ; java.nio ; file lock

romuloff
aew. uma solução melhorzinha que aprimorei de acordo com o comportamento da jvm.
/**
     * Test if file is being used by another process
     * 
     * @param file the file to test
     * 
     * @return boolean
     * @author romuloff
     */
    public static boolean isFileInUse(File file) {

        boolean verificadorEspecifico = false;
        FileChannel channel = null;
        try {
            channel = new RandomAccessFile(file, "rw").getChannel();
        }
        catch (FileNotFoundException fnfe) {
            LOGGER.error(fnfe.toString());
            if (!file.exists()) {
                LOGGER.warn("Arquivo " + file.getName() + " não existe");
            }
            else {
                LOGGER.warn("Arquivo " + file.getName() + " esta em uso por outro processo !");
                verificadorEspecifico = true;
            }
        }
        catch (Exception e) {
            LOGGER.error(e.toString());
        }
        finally {
            if (channel == null) {
                return verificadorEspecifico;
            }
            if (channel != null) {
                try {
                    channel.close();
                }
                catch (IOException ioe) {
                    LOGGER.error(ioe.toString());
                }
            }
        }
        return false;
    }
M

No meu caso eu preciso copiar não só um arquivo mas 7 arquivos.

Como faço para copiar esses 7 arquivos específicos para outra pasta?

Além disso acredito que precisarei enviá-los e renomeá-los com a data que irei passar.

No código acima não compreendi onde defino os endereços dos arquivos.

M

EU tenho um bat onde o usuário entra lá no cmd e faz a chamado desse bat passando uma data. (O usuário não faz idéia do que tá fazendo).

Preciso substituir o bat abaixo pelo java.

PTOTRF.BAT

@echo off
cls
cd\PGRW206
copy RELREC01+RELREC02+RELREC03+RELREC04+RELREC05+RELREC06+RELREC08
\FORPONTO\CAPTU%1
copy relrec01+relrec02+relrec03+relrec04+relrec05+relrec06+relrec08 %1
copy RELREC07 \FORPONTO\CAPTU%1R
copy relrec07 %1R
copy relrec01 \relrec
copy relrec02 \relrec
copy relrec03 \relrec
copy relrec04 \relrec
copy relrec05 \relrec
copy relrec06 \relrec
copy relrec07 \relrec
copy relrec08 \relrec
del relrec??

G

tentei usar o metodo para copias nao deu erro nem copiou nada.

G

alguem sabe pq

Andre_Fonseca

oi,

tire o echo off do bat e rode ele por linha de comando

deve sair algum erro…

abs

dsacheti

Valeu pessoal, este tópico também me ajudou, estava com o problema de AccessDenied. Acrescentar o nome do arquivo no destino ajudou.
Estou usando um exemplo com JFileChooser.

Criado 3 de junho de 2009
Ultima resposta 16 de mar. de 2013
Respostas 19
Participantes 10