Como saber se o File foi fechado depois de tê-lo aberto com getDesktop().open(file)?[RESOLVIDO]

Esse é o meu código:

[code]File file = new File(“C:\Arquivo Temporario”+extensaofile);

    BufferedOutputStream bos = null;
    try {
        bos = new BufferedOutputStream(new FileOutputStream(file));
        bos.write(anexo); 
        bos.close(); 
    } catch (FileNotFoundException ex) {
    } catch (IOException ex) {
        
    }
   
    try {
        
        Desktop.getDesktop().open(file);
        
    } catch (Exception ex) {
        JOptionPane.showMessageDialog(null, "Erro no Desktop: " + ex);
    }[/code]

Após abrir o arquivo, eu preciso saber quando ele será fechado para que eu possa excluí-lo. Como posso fazer isso?

A resposta simples é “não há como”. Isso é porque Desktop.open chama um programa externo sobre o qual você não tem controle, e ainda por cima o programa roda “em paralelo” com o seu programa - open não espera o programa externo ser fechado.

Existe uma outra maneira para que isso seja possível?

Explique o que você quer fazer.
Provavelmente, para o que você quer fazer, pode-se fazer de uma outra maneira que não envolva Desktop.open (você deve ter visto na documentação que Desktop.open simplesmente dispara a aplicação adequada e passa o nome do arquivo para essa aplicação, para que ela abra o arquivo.

[quote=entanglement]Explique o que você quer fazer.
Provavelmente, para o que você quer fazer, pode-se fazer de uma outra maneira que não envolva Desktop.open (você deve ter visto na documentação que Desktop.open simplesmente dispara a aplicação adequada e passa o nome do arquivo para essa aplicação, para que ela abra o arquivo.
[/quote]

o usuário clica em um botão para ver o arquivo anexado àquele registro, como o arquivo está salvo no banco de dados como byte, eu preciso criá-lo temporariamente, estou usando o FileOutputStream, depois que ele fechar o arquivo, eu preciso deletá-lo, por que ele é temporário, pois já está no banco.

Tenho uma idéia que talvez ajude.
Cria um loop que fica tentando deletar o arquivo. Se ele estiver aberto em outro programa, provavelmente vai gerar uma exceção. Quando conseguir deletar sem erro termina o loop.
Não tenho certeza se dá certo, pois não testei, mas tenta aí, pode funcionar.

[quote=juno.rr]Tenho uma idéia que talvez ajude.
Cria um loop que fica tentando deletar o arquivo. Se ele estiver aberto em outro programa, provavelmente vai gerar uma exceção. Quando conseguir deletar sem erro termina o loop.
Não tenho certeza se dá certo, pois não testei, mas tenta aí, pode funcionar.[/quote]

Então seria assim:

[code]File file = new File(“C:\Arquivo Temporario - Registro " + Valor(“cod_selo”) + " - Cadastr. Veíc. IASP” + extensaofile); //Criamos um nome para o arquivo

    BufferedOutputStream bos = null;
    try {
        bos = new BufferedOutputStream(new FileOutputStream(file)); 
        bos.write(anexo); 
        bos.close(); 

    } catch (FileNotFoundException ex) {
        Logger.getLogger(CadastroVeiculos.class.getName()).log(Level.SEVERE, null, ex);
        JOptionPane.showMessageDialog(null, "Arquivo Não Encontrado!");

    } catch (IOException ex) {
        Logger.getLogger(CadastroVeiculos.class.getName()).log(Level.SEVERE, null, ex);
    }
    try {
        Desktop.getDesktop().open(file);
    } catch (Exception ex) {
        JOptionPane.showMessageDialog(null, "Erro no Desktop: " + ex);
    }

    while(file.exists()){
           file.delete();
       
    }[/code]

Só que desse jeito, antes do arquivo terminar de abrir, ele já deletou o arquivo, e emite uma mensagem no programa que abre o arquivo que houve um erro e ele não abre, mas aí eu mudei uma coisinha:

[code]try {

        Desktop.getDesktop().open(file);
        file.wait();

    } catch (Exception ex) {
        JOptionPane.showMessageDialog(null, "Erro no Desktop: " + ex);
    }
       
    while(file.exists()){
           file.delete();
       
    }

[/code]
Inseri o file.wait(), e até funcionou, o único problema é que ele cai na Exception.

Acabei de testar uma outra coisa, e na verdade o file.wait() não funcionou.
O que fez com que ‘funcionasse’ foi o fato de ter emitido uma mensagem (JOptionPane.showMessageDialog(null, "Erro no Desktop: " + ex)), isso deu tempo para o arquivo ser aberto e não permitir que ele fosse deletado até que eu o fechasse.
O problema então é que não há tempo suficiente para abrir o arquivo antes de deletar… :confused:

Coloca um Thread.sleep(1000) antes do loop. Não é muito elegante, mas considerando que não tem outro jeito…

Bom, acabei fazendo na marra mesmo, e deu certo. rs
eu fiz assim… gravei o caminho dos arquivos que foram abertos em um vetor, e caso eu já o tenha aberto antes, ele não repete no vetor… quando eu fecho o Jframe, eu deleto os arquivos guardados no vetor.
Eu achei legal e funcionou direitinho.
Se alguém precisar… :

o contador e o vetor devem ser declarados no inicio da classe:


public class testeAnexo extends javax.swing.JFrame{
    int countFiles;
    String[] files = new String[999];

}

esse é o código do botão que vai abrir o arquivo.

[code]

String fileAtual = "";
String fileAtualVetor = "";

if ("".equals(txtanexo.getText())) {
    JOptionPane.showMessageDialog(null, "Não existe anexo!", "OPS!", JOptionPane.WARNING_MESSAGE);
        
} else {

    File file = new File("C:\\ Arquivo Temporario - "+ codigo +" "  + extensaofile); //Criamos um nome para o arquivo com o codigo do registro  

    //este for() é para verificar se já existe este arquivo no vetor
    for (int i = 0; i <= countFiles; i++) {
        //se o vetor ainda não foi preenchido, ou seja, se for o primeiro índice, 
        //eu adiciono o primeiro file no vetor e somo o contador de files(que é o índice do vetor) e quebro o for()
        if (files[0] == null) {
            files[0] = file.toString();
            countFiles++;
            break;

        } else {
            fileAtual = file.toString();  //atribuo o file atual à variável
            fileAtualVetor = files[i];   // atribuo o file i do vetor à varivel

            //se a posição atual no vetor estiver vazia, 
            //atribui-se vazio em string, para que não dê erro na comparação em seguida
            if (fileAtualVetor == null) {
                fileAtualVetor = "";
            }
            // se o arquivo atual que está no vetor for igual ao file que está sendo aberto no momento, 
            //quebra o laço, pois se inserir um file igual a um existente no vetor, dará erro na hora de excluir.
            if (fileAtualVetor.equals(fileAtual)) {
                break;

                // depois de todas as comparações para verificar se o arquivo já não foi aberto e inserido no vetor, 
                // se não tiver sido inserido e for a ultima posição do vetor, insere-se o arquivo no vetor
            } else if (i == countFiles) {
                files[countFiles] = file.toString();
                countFiles++;
                break;
            }
        }

    }
  
    //esta parte cria o arquivo
    BufferedOutputStream bos = null;
    try {
        bos = new BufferedOutputStream(new FileOutputStream(file)); //Criamos o arquivo
        bos.write(anexo); //Gravamos os bytes lá
        bos.close(); //Fechamos o stream. 
    } catch (FileNotFoundException ex) {
       JOptionPane.showMessageDialog(null, "Arquivo não encontrado", "OPS!", JOptionPane.WARNING_MESSAGE);
        
    }



    try {

        Desktop.getDesktop().open(file); // abre o arquivo
        

    } catch (Exception ex) {
        JOptionPane.showMessageDialog(null, "Erro no Desktop: " + ex);
    }
    

}[/code]

e agora é só deletar na hora de fechar o Jframe:

[code]
for (int i = 0; i < countFiles; i++) {
File fileexclusao = new File(files[i]);
fileexclusao.delete();

    }[/code]

Espero ter ajudado alguém, e a quem me ajudou, valeu! :slight_smile: