Exception: Nao existem recursos de sistema suficientes para concluir o serviço solicitado

24 respostas
J

Pessoal, to com um problema em uma classe responsável por fazer a cópia de arquivos.
Aí na exception ele me retorna essa mensagem: Nao existem recursos de sistema sucifientes para concluir o serviço solicitado.

O JAVA está se referindo a recursos de sistema como memória, espaço em disco e etc?

Espaço em disco há até de sobra para copiar o arquivo.

O tamanho total do arquivo é de cerca de 800MB.

Segue o código que estou utilizando:

public static void main(String[] args) {
        System.out.println("Backup da base de dados...");
        FileChannel oriChannel = null;
        String DIR_DESTINO = "";
        try {
            oriChannel = new FileInputStream("\\\\x.x.x.x\\dir_backup$\\BASE.ZIP").getChannel();
        } catch (Exception e) {
            System.out.println("Nao foi possivel iniciar a copia: " + e.getLocalizedMessage());
            System.exit(0);
        }
        Calendar dia = Calendar.getInstance();
        String[] diaSem = {"Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sab"};
        DIR_DESTINO = "\\\\x.x.x.x\\dir_backup$\\" + diaSem[dia.get(Calendar.DAY_OF_WEEK) - 1];
        File dir = new File(DIR_DESTINO);

        if (!dir.exists()) {
            dir.mkdir();
        } else {
            String[] arqs = dir.list();
            if (arqs.length > 0) {
                for (String arq : arqs) {
                    File arquivo = new File(dir, arq);
                    arquivo.delete();
                }
            }
        }
        System.out.println("Iniciando copia de arquivo...");
        FileChannel destChannel = null;
        try {
            destChannel = new FileOutputStream(DIR_DESTINO + "\\BASE.ZIP").getChannel();
        } catch (Exception e) {
            System.out.println("Nao foi possivel criar o arquivo de destino: " + e.getLocalizedMessage()); 
            System.exit(0);
        }
        try {
            destChannel.transferFrom(oriChannel, 0, oriChannel.size());
        } catch (IOException e) {
            System.out.println("Nao foi possivel realizar o backup: " + e.getLocalizedMessage());//ESSA É A EXCEÇÃO EXIBIDA.
            System.exit(0);
        }
        System.out.println("Copia concluída com sucesso.");

        // Fecha channels
        try {
            oriChannel.close();
            destChannel.close();
            
        } catch (Exception e) {
        } finally {
            System.exit(0);
        }
    }

Explicando melhor o código.
Um sistema que temos gera um arquivo compactado como backup de sua base de dados.
Porém ele gera sempre com o nome BASE.ZIP
Dessa forma temos apenas o backup de um dia.

O código acima copia esse arquivo para um outro servidor de backups, colocando o mesmo na pasta do dia da semana correspondente, dessa forma teremos o backup de até 7 dias atrás.

Porém estou com esse erro.
Agradeço a quem puder ajudar.

Vlw.

24 Respostas

G

Cara coloca um printStackTrace() dentro dos seus catch e posta ai o resultado.

J

Ok, coloquei o printStackTrace() naquele catch.

Segue o resultado:

Backup da base de dados...
Iniciando copia de arquivo...
java.io.IOException: N?o existem recursos de sistema suficientes para concluir o serviço solicitado
Copia concluída com sucesso.
        at sun.nio.ch.FileDispatcher.pwrite0(Native Method)
        at sun.nio.ch.FileDispatcher.pwrite(FileDispatcher.java:51)
        at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:68)
        at sun.nio.ch.IOUtil.write(IOUtil.java:28)
        at sun.nio.ch.FileChannelImpl.write(FileChannelImpl.java:638)
        at sun.nio.ch.FileChannelImpl.transferFromFileChannel(FileChannelImpl.java:529)
        at sun.nio.ch.FileChannelImpl.transferFrom(FileChannelImpl.java:590)
        at backupsh.Main.main(Main.java:60)
CONSTRUÍDO COM SUCESSO (tempo total: 0 segundos)

Vlw pela ajuda.

J

Pessoal, uma coisa que notei.

O erro ocorre quando quero copiar o arquivo para o servidor.

Fiz um teste copiando o mesmo para minha máquina local, c:\pasta… e copiou normalmente.

O compartilhamento do servidor é protegido por senha. Porém acessando via explorer eu consigo acessar, pois a senha já está armazenada no usuário do Windows.

Pode ser isso?

Se sim, há alguma forma de informar o usuário/senha do servidor antes da cópia?

Obrigado.

J

Pessoal, alguém tem alguma idéia?

O estranho é que copiando para minha máquina o código funciona.

O método para copiar arquivos pela rede é o mesmo do que copiar para um diretório local?

Se alguém tiver alguma idéia, to precisando mesmo, rsrs.

Vlw.

J

Bom, agora estou entendendo menos, rsrs.
Pois não entendo como o erro possa ser recursos de sistema insificientes.

Outro teste que fiz.

Como eu consegui rodar o código copiando para a minha máquina, no C:/…, fiz o seguinte:

Compartilhei a pasta e tentei copiar o arquivo para \127.0.0.1\compartilhamento

E ocorreu o mesmo problema de recursos insuficientes. Porém, é a mesma pasta que eu copiei ao utilizar C:/pasta…

Acredito que possa ser uma limitação no método…

Então, para “tapear” isso, existe a possibilidade de chamar o comando copy do DOS?

Como o programa irá rodar somente sob linha de comando mesmo, chamando o copy funcionaria também.

Aí eu passaria o comando para o DOS.

Obrigado.

S

Opa,

você pode chamar comandos do windows sim:

Runtime.getRuntime().exec()

OBS: parece que você está com algum problema na rede…

J

sergiom:
Opa,

você pode chamar comandos do windows sim:

Runtime.getRuntime().exec()

OBS: parece que você está com algum problema na rede…

Opa.

Mas que tipo de problema pode ser?

Porque o arquivo já está na rede, eu consigo acessá-lo. O problema eh pra copiar para outro local da rede.

Mas por momento vou tentar algo com esse comando, pra ver se consigo algo.

Vlw.

S

O arquivo está em uma máquina da rede e você tenta copiá-lo para a sua máquina ou para outra da rede diretamente?

Pelo windows funciona legal?

J

sergiom:
O arquivo está em uma máquina da rede e você tenta copiá-lo para a sua máquina ou para outra da rede diretamente?

Pelo windows funciona legal?

Sim, pelo windows funciona blza.

Se eu copiar o arquivo para minha máquina funciona normal. O problema é copiar para essa outra máquina da rede.

Tipo, se eu copiar para c:\pasta funciona. Mas fiz um teste tentando copiar para \127.0.0.1\pasta (compartilhei a pasta com o nome pasta) e não consegui. Apresentou o erro de recursos insuficientes, que não consigo entender o porque.

O stackTrace está ali nos posts tambem.

Faz alguma idéia?

Obrigado

S

Sinceramente não sei, nunca tentei copiar diretamente arquivos sem passar pelo computador local.

Uma opção seria copiar ele para o C:\ e depois repassar para o outro pc.

J

sergiom:
Sinceramente não sei, nunca tentei copiar diretamente arquivos sem passar pelo computador local.

Uma opção seria copiar ele para o C:\ e depois repassar para o outro pc.

Pois é, eu tentei isso também, mas sem sucesso.

A exception continua.

O problema acontece sempre quando o endereço de destino é um diretório de rede.

Por momento, acho que vou usar uma chamada ao copy do DOS mesmo.

Mas ainda quero achar uma solução, rsrs.

Mas vlw pelas dicas aew.

S

Só por curiosidade, muda alguma coisa se você alterar de transferFrom para transferTo (sei que não deveria, mas não custa tentar hehe), mudando também a variável que vai fazer o processo ?

J

cara, acho que estamos chegando lá.

Alterei para TransferTo e agora ele não exibe mais o erro.

O problema é que o arquivo não é copiado.

É um arquivo .ZIP.
Após a execução do código ele mostra o arquivo no destino, porém com 0 bytes.

Veja como ficou o novo código:

public class Main2 {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IOException{
        System.out.println("Backup da base de dados...");
        FileChannel oriChannel = null;
        String DIR_ORIGEM;
        String DIR_DESTINO;
        DIR_ORIGEM = "\\\\x.x.x.x\\bkp$\\BASE.ZIP";
        try {
            oriChannel = new FileInputStream(DIR_ORIGEM).getChannel();
        } catch (Exception e) {
            System.out.println("Nao foi possivel iniciar a copia: " + e.getLocalizedMessage());
            System.exit(0);
        }
        
        Calendar dia = Calendar.getInstance();
        String[] diaSem = {"Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sab"};
        DIR_DESTINO = "\\\\x.x.x.x\\bkp$\\" + diaSem[dia.get(Calendar.DAY_OF_WEEK) - 1];
        File dir = new File(DIR_DESTINO);

        if (!dir.exists()) {
            dir.mkdir();
        } else {
            String[] arqs = dir.list();
            if (arqs.length > 0) {
                for (String arq : arqs) {
                    File arquivo = new File(dir, arq);
                    arquivo.delete();
                }
            }
        }
        System.out.println("Iniciando copia de arquivo...");
        FileChannel destChannel = null;
        try {
            destChannel = new FileOutputStream(DIR_DESTINO + "\\BASE.ZIP").getChannel();
        } catch (Exception e) {
            System.out.println("Nao foi possivel criar o arquivo de destino: " + e.getLocalizedMessage());
            System.exit(0);

        }
        try {
            //destChannel.transferFrom(oriChannel, 0, oriChannel.size()); ESSA LINHA COMENTADA ERA A AÇÃO ANTERIOR
            oriChannel.transferTo(0, destChannel.size(), destChannel);
        } catch (IOException e) {
            e.printStackTrace();
        }
    
        System.out.println("Copia concluída com sucesso.");

        // Fecha channels
        try {
            oriChannel.close();
            destChannel.close();
            
        } catch (Exception e) {
        } finally {
            System.exit(0);
        }
        
    }
}

Acho que deve ser só um detalhe no transferTo.
Faz idéia?

Obrigado pela ajuda aew.

S
destChannel.size()

Acho que aqui está o detalhe. Seria oriChannel.size(), né?

J

sergiom:
destChannel.size()

Acho que aqui está o detalhe. Seria oriChannel.size(), né?

ops, sim realmente é oriChannel.size() mesmo.

Porém, ao alterar isso e rodar o código, o erro voltou…

Tah me dando nos nervos já esse código, rsrsrs.

S

É amigo, temos um bug:

http://stackoverflow.com/questions/2859530/what-does-insufficient-system-resources-error-mean

S

Aqui mostra a solução, copiando por partes o arquivo:
http://stackoverflow.com/questions/4444210/how-to-copy-a-large-file-in-windows-xp

M

eu ja tive um problema assim no passado também… acho que tinha tentado inclusive mapear uma unidade de rede no windows para a pasta e nem assim consegui transmitir o arquivo para outro lugar na rede…

J

sergiom:
É amigo, temos um bug:

http://stackoverflow.com/questions/2859530/what-does-insufficient-system-resources-error-mean

não é fácil essa vida de gaudério, rsrs.

Mas enfim, por momento acho que consigo dar um jeito chamando o copy por DOS.
Vou ver se consigo implementar assim.

Depois vejo o que faço.

Ms vlw mesmo pela força cara.

Até.

J

Pessoal, seguindo a saga… rsrs.

Consegui implementar com uma chamada ao comando copy do Windows.

Porém, ali no meu código eu tenho uma linha informando “Cópia concluída com sucesso” após esse comando.

O caso é que ela é exibida e o programa continua rodando, até finalizar a cópia.

Como posso fazer para “pausar” o andamento do código JAVA, dando sequencia somente quando o processo chamado pelo Runtime finalizar?

Segue o código:

public static void main(String[] args) throws IOException {
        System.out.println("Backup da base de dados...");

        String DIR_ORIGEM;
        String DIR_DESTINO;

        DIR_ORIGEM = "\\\\x.x.x.x\\bkp$\\BASE.ZIP";
        Calendar dia = Calendar.getInstance();
        String[] diaSem = {"Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sab"};
        DIR_DESTINO = "\\\\x.x.x.x\\bkp$\\" + diaSem[dia.get(Calendar.DAY_OF_WEEK) - 1];
        File dir = new File(DIR_DESTINO);

        if (!dir.exists()) {
            dir.mkdir();
        } else {
            String[] arqs = dir.list();
            if (arqs.length > 0) {
                for (String arq : arqs) {
                    File arquivo = new File(dir, arq);
                    arquivo.delete();
                }
            }
        }
        System.out.println("Iniciando copia de arquivo...");
        Runtime.getRuntime().exec("cmd.exe /ccopy " + DIR_ORIGEM + " " + DIR_DESTINO + "\\BASE.ZIP");

        System.out.println("Copia concluída com sucesso."); //essa linha só deve ser executada após o processo acima finalizar.

    }

Obrigado.

J

sergiom:
Aqui mostra a solução, copiando por partes o arquivo:
http://stackoverflow.com/questions/4444210/how-to-copy-a-large-file-in-windows-xp

cara, não havia visto esse seu post.

Olhei lá e vou tentar implementar.

Mas por momento, algúem sabe me dizer como “trancar” a execução do JAVA, como mencionei acima?

Obrigado.

S

http://www.guj.com.br/java/246324-exception-nao-existem-recursos-de-sistema-suficientes-para-concluir-o-servico-solicitado

J

Cara, esse link é desse mesmo tópico, rsrs.

Mas enfim, consegui “trancar” a execução do JAVA durante a cópia.

Utilizei o método waitFor().

ficou beleza.

Flw.

S

Oops. O link era pra ser: http://www.guj.com.br/java/245856-problema-com-waitfor–pdftohtml-no-linux

Criado 1 de julho de 2011
Ultima resposta 11 de jul. de 2011
Respostas 24
Participantes 4