Problema permissao para renomear arquivo

Galera,

Minha aplicação tem q renomear um arquivo, mas nao renomeia… já mexi na permissão da pasta e nada… to executando no Windows.

Alguma luz?

Tks

Frade,

No Windows é realmente dificil ter problemas com permissão, isso é mais comum no Linux.

Poste o seu código para darmos uma olhada.

Outra coisa, o sistema apresenta algum erro?

Vc esta utilizando a função renameTo() da classe File?

http://java.sun.com/j2se/1.4.2/docs/api/java/io/File.html

[quote=ramilani12]Vc esta utilizando a função renameTo() da classe File?

http://java.sun.com/j2se/1.4.2/docs/api/java/io/File.html[/quote]

To sim… o código é simples:

     public void RenomeiaArquivo(String nomeArquivo){
        File arquivo = new File("c:\teste\" + nomeArquivo);
        String renomeado = "c:\teste\" + nomeArquivo + ".lido";
        File arquivoRenomeado = new File(renomeado);
        boolean ok = arquivo.renameTo(arquivoRenomeado);
        if(ok){
            System.out.println("Arquivo renomeado com sucesso.");
        }
        else{
            System.out.println("Nao foi possivel renomear o arquivo.");
        }

    }

Coloque um bloco try {}catch{} nesse seu metodo para capturar a exceção que ele está lançando.

Coloquei e ele não lança nenhuma exception :shock:…

Na API diz:

Mas nem renomeia, nem lança exception :roll:…

Se o arquivo ainda estiver aberto por algum motivo, não poderá ser renomeado.

Tá fechado… criei um arquivo só pra testar e nada…

Fiz umas alterações pra testar, mudei de pasta, arquivo e nada… to ficando louco já… achei q seria tão simples :?

O seguinte programa funciona direitinho.

import java.io.*;
import java.util.*;

class TesteRename {
    public static void main(String[] args) throws IOException {
        // Estamos supondo que o diretório C:\TEMP exista.
        // Vamos criar um arquivo e então renomeá-lo.
        File f = new File ("C:\temp\teste.txt");
        File g = new File ("C:\temp\teste.txt.lido");
        
        OutputStream os = new FileOutputStream (f);
        os.write (new byte[10000]);
        os.close();
        System.out.println ("O arquivo " + f + (f.exists() ? " existe" : " não existe"));
        System.out.println ("Tentando renomear o arquivo para " + g);
        f.renameTo (g); 
        System.out.println ("O arquivo " + f + (f.exists() ? " existe" : " não existe"));
        System.out.println ("O arquivo " + g + (g.exists() ? " existe" : " não existe"));
    }
}

Cara, seu exemplo funcionou mesmo e acho q percebí minha mancada… Minha aplicação funciona assim: primeiro o arquivo é enviado por FTP, dae desconecto do FTP e depois renomeio. Será q mesmo assim o java considera q o arquivo está em uso e não deixa renomeá-lo? Segue o código:

public boolean FTPCliente(String arq) throws IOException {
        FTPClient ftp = new FTPClient();
        boolean resultado = true;
        try {
            ftp.connect( "192.168.1.107" );
            ftp.login( "login", "senha" );
            FileInputStream arqEnviar =
                    new FileInputStream("c:\semic\bilhetagem\" + arq);
            ftp.setFileType( FTPClient.ASCII_FILE_TYPE );
            if (ftp.storeFile(arq, arqEnviar)){
                resultado =  true;
            } else {
                resultado = false;
            }
           
        } catch (SocketException ex) {
            ex.printStackTrace();
            resultado = false;
        } catch (IOException ex) {
            ex.printStackTrace();
            resultado = false;
        }
        ftp.disconnect();  // [b]Aqui desconecto do FTP[/b]
        this.RenomeiaArquivo(arq); // [b]Aqui peço pra renomear[/b]
        return resultado;
    }

public void RenomeiaArquivo(String nomeArquivo){
        File f = new File("C:\Semic\bilhetagem\" + nomeArquivo);
        File g = new File("C:\Semic\bilhetagem\" + nomeArquivo + ".lido");
        try {
            System.out.println("O arquivo " + f + (f.exists() ? " existe" : " não existe"));
            System.out.println("Tentando renomear o arquivo para " + g);
            f.renameTo(g);
            System.out.println("O arquivo " + f + (f.exists() ? " existe" : " não existe"));
            System.out.println("O arquivo " + g + (g.exists() ? " existe" : " não existe"));
        } catch(Exception  e){
            System.err.println("Erro renomear: " + e.getMessage());
        }
    }

Se for isso, como saber q o arquivo não está mais em uso?

Na minha classe FTPCliente eu criava um FileInputStream e não fechava:

FileInputStream arqEnviar = new FileInputStream("c:\semic\bilhetagem\" + arq);

Fechando o FileInputStream com arqEnviar.close(); o arquivo pode ser renomeado normalmente… o thingol tinha falado isso, mas eu estava procurando na classe errada :shock:…

Tks

Pois é. Tudo que for aberto deve ser fechado :stuck_out_tongue:

É pena que não existe (ainda) em Java uma construção como o “using” do C#. Essa construção evitaria tais problemas. Veja como isso seria resolvido em Java se ele tivesse o “using”:

            using (FileInputStream arqEnviar =
                         new FileInputStream("c:\semic\bilhetagem\" + arq)) {
                 ftp.setFileType( FTPClient.ASCII_FILE_TYPE );
                 if (ftp.storeFile(arq, arqEnviar)){
                     resultado =  true;
                 } else {
                     resultado = false;
                 }
             }

No fechamento da chave “}” do “using”, seria chamado automaticamente o método “close” do objeto arqEnviar, e com um “try/catch” automático que “engoliria” a exceção IOException se houvesse problema no close.

O Gilad Bracha (Cadence Design Systems), Neal Gafter (Google), Peter von der Ahé (Sun), e James Gosling (Sun), estão propondo uma extensão ao JDK (para entrar na versão 7) que possibilitaria tais coisas - essa extensão faz parte da proposta de “closures”. Para mais informações: http://gafter.blogspot.com

Pessoal, eu queria aproveitar o tópico e tirar um dúvida com vocês. Eu estou aqui com um problema bem parecido. Eu faço uma conexão FTP e estou copiando os arquivos de um diretório (remoto) “x”. Até ai tudo certo. O problema é que logo depois que eu copiei esse arquivo do diretório eu quero renomear esse arquivo lá no diretório remoto e não estou conseguindo.

Pela documentação da apache eu achei um método pra isso, é o FTPClient.rename(String name, String newName). Esse método retorna true se conseguiu renomear e false caso contrário. A inhaca é que sempre ele retorna false, sem conseguir renomear o arquivo. Alguém sabe me dizer o que eu posso estar fazendo de errado ? =P

Desde já obrigado pela ajuda pessoal. Abaixo está o meu código

private void receiveFiles(String ip, int port) {
	
		FTPClient ftp = new FTPClient();
	
		try {
			ftp.setDefaultPort(port);
			ftp.setDefaultTimeout(Properties.TIMEOUT);
			ftp.connect(ip);
	
			if (FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
				ftp.login(Properties.FTP_LOGIN_ID, Properties.FTP_LOGIN_PW);
			} else {
				ftp.disconnect();
				return;
			}
	
			ftp.changeWorkingDirectory(Properties.RECEIVE_DIR);
			String[] fileNames = ftp.listNames();
			quantFiles = fileNames.length;
			
			ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
	
			for (int i = 0; i < 50 && i < fileNames.length; i++) {	
			
				//Faz a transferência do arquivo.
				OutputStream out = new FileOutputStream(Properties.LOGS_DIR + Properties.SYSTEM_DIR + fileNames[i]);
				if(ftp.retrieveFile(fileNames[i], out))
					System.out.println("Arquivo " + fileNames[i] + " transferido.");
				else
					System.out.println("Arquivo " + fileNames[i] + " não transferido.");
				out.close();
				
				//Renomeia o nome do arquivo para saber que foi transferido.
				if(ftp.rename(fileNames[i], fileNames[i] + "_tranferido"))
					System.out.println("Arquivo renomeado.");
				else
					System.out.println("Arquivo não renomeado.");
			}
			ftp.disconnect();
			
			//Atualiza dados de progresso e avisa os listeners que a transferencia terminou.
			resetControlFields();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}