1
resposta

Escrever no final do arquivo, inves de sobreescreve-lo

Pessoal, fiz um programa onde o usuario cria o arquivo com o nome que le deseja. Depois ele escreve nesse arquivo o texto, baseado no que foi digitado no console pelo usuario. O final é quando o usuario aperta o enter. É possivel ler o conteudo do arquivo para o console depois. E é possível deletar linha (nesse caso, pesquisando no GUJ vi que nao é possivel fazer isso diretamente. Eu devo criar um outro arquivo, copiar odo conteudo nele, menos a linha que quero remover) Beleza. Não me parece muito desempenho ficar copiando um arquivo novo toda vez que eu quiser deletar uma linha, MAS, fiz, implementei e deu certo a logica.

Agora eu quero que o usuario abra o arquivo ja existente e insira mais linhas, mas nao quero que ele SOBREESCREVA o arquivo. Quero que ele adicione linhas no final. Ou seja, abra o arquivo, coloque o ponteiro na linha apos o final, e comece a escrever a partir dali.

Segue meu codigo, se alguem puder me ajudar, pois estou travado. Toda hora ele sobreescreve o arquivo inves de adicionar linhas novas. Nao estou sabendo colocar o ponteiro no end of file. Engraçado que estou usando a mesma metodologia da remoção de linha, copiando tudo em um arquivo novo e teoricamente adicionando as linhas novas nesse arquivo novo. Entretanto, no caso da adição ele sobreescreve,

Vou colocar os 2 metodos. O de escrita que nao esta funcionando

E o de de remoção, que funciona.

Escrita nova: Para escrever linhas novas sem sobreposição.

public void escreveArquivo(String nomeArquivo) throws Exception {

        if(verificaExiste(nomeArquivo)) {
            PrintWriter pw = new PrintWriter(nomeArquivo, "UTF-8");
            InputStreamReader ist = new InputStreamReader(System.in);
            BufferedReader conteudoArquivo = new BufferedReader(ist);

            //FileReader fr = new FileReader(nomeArquivo);
            //BufferedReader ca = new BufferedReader(fr);

            Scanner bw = new Scanner(new File(nomeArquivo),"UTF-8");

            //teste, e todos retornam null. O programa esta novamente criando o arquivo.
            System.out.println(bw.nextLine().equals(""));
            System.out.println(bw.hasNext());
            System.out.println(bw.equals(null));


            if (bw.equals(null)) {
                System.out.println("Digite o conteudo do arquivo: ");
                String linhas = conteudoArquivo.readLine();
                while(!linhas.equals("")) {
                    pw.println(linhas);
                    linhas = conteudoArquivo.readLine();
                }
                pw.close();    
                bw.close();
            } else {
                File novoArquivo = new File("novot.txt");
                novoArquivo.createNewFile();
                PrintWriter escritorArquivo = new PrintWriter(novoArquivo,"UTF-8");
                Scanner leitorArquivo = new Scanner(new File(nomeArquivo),"UTF8");
                InputStreamReader ist2 = new InputStreamReader(System.in);
                BufferedReader conteudoArquivo2 = new BufferedReader(ist2);
                while (leitorArquivo.hasNextLine()) {
                    escritorArquivo.println(leitorArquivo.nextLine());
                }
                System.out.println("Digite o conteudo do arquivo: ");
                String linhas2 = conteudoArquivo2.readLine();
                while(!linhas2.equals("")) {
                    escritorArquivo.println(linhas2);
                    linhas2 = conteudoArquivo2.readLine();
                }
                leitorArquivo.close();
                escritorArquivo.close();
            }
        } else {
            throw new ArquivoInexistenteException();
        }

    }

Remoação de linha, funciona estranhamente com a mesma logica de programação. O arquivo não é sobreposto.

public void deletaLinha(String nomeArquivo, int linhaDeletada) throws Exception {

        int contadorLinha = 1;
        if(verificaExiste(nomeArquivo)) {
            Scanner nomeNovoArquivo = new Scanner(System.in,"UTF-8");
            System.out.println("Nome do novo arquivo: ");
            String nomeNovoArq = nomeNovoArquivo.nextLine();
            File novoArquivo = new File(nomeNovoArq);
            novoArquivo.createNewFile();
            PrintWriter escritorArquivo = new PrintWriter(novoArquivo,"UTF-8");
            Scanner leitorArquivo = new Scanner(new File(nomeArquivo),"UTF-8");
            while (leitorArquivo.hasNextLine()) {
                if (contadorLinha != linhaDeletada) {
                    escritorArquivo.println(leitorArquivo.nextLine());
                    contadorLinha++;
                } else {
                    leitorArquivo.nextLine();
                    escritorArquivo.println();
                    contadorLinha++;
                }
            }
            leitorArquivo.close();
            escritorArquivo.close();
        } else {
            throw new ArquivoInexistenteException();
        }

    }

Aproveito e peço 2 feedbacks: 1- Em Java realmente tenho que criar uma cópia do arquivo para deletar linhas ou escrever mais? Nao parece muito alto nível e alto desempenho essa solução. Porem, na net, tipo GUJ era o orientado.

2- Em termos de pensar na lógica de O.O meu código esta aceitavel?

1 resposta

No caso da escrita de linhas adicionais em um arquivo existente, você precisa utilizar um construtor FileWriter que aceite um parâmetro booleano indicando se você deseja anexar ao final do arquivo ou sobrescrevê-lo. Para isso, você pode utilizar o construtor FileWriter(String fileName, boolean append). No seu código, você está usando o construtor PrintWriter(String fileName, String charsetName), que não possui a opção de anexar ao final do arquivo.

Exemplo:

public void escreveArquivo(String nomeArquivo) throws Exception {
    if (verificaExiste(nomeArquivo)) {
        InputStreamReader ist = new InputStreamReader(System.in);
        BufferedReader conteudoArquivo = new BufferedReader(ist);

        PrintWriter pw = new PrintWriter(new FileWriter(nomeArquivo, true), true);

        System.out.println("Digite o conteudo do arquivo: ");
        String linhas = conteudoArquivo.readLine();
        while (!linhas.equals("")) {
            pw.println(linhas);
            linhas = conteudoArquivo.readLine();
        }

        pw.close();
        conteudoArquivo.close();
    } else {
        throw new ArquivoInexistenteException();
    }
}

No código acima, foi utilizado o construtor FileWriter(String fileName, boolean append) com o valor true para o parâmetro append, indicando que você deseja anexar ao final do arquivo existente. Além disso, foi removido o uso do Scanner para leitura do arquivo, pois não é necessário nesse caso.

Agora, em relação às suas perguntas:

  1. Em Java, para remover ou adicionar linhas em um arquivo, uma abordagem comum é criar um novo arquivo e copiar o conteúdo do arquivo original, excluindo ou adicionando as linhas necessárias. Essa abordagem é necessária porque a estrutura do arquivo não permite inserção ou remoção direta em uma posição específica. Embora possa parecer menos eficiente em termos de desempenho, é uma abordagem segura e geralmente não causa problemas em arquivos pequenos ou em operações ocasionais. Se você estiver trabalhando com arquivos grandes e/ou com operações frequentes de adição/remoção, pode ser necessário considerar outras soluções, como a utilização de bancos de dados ou sistemas de armazenamento mais adequados.

  2. Em termos de O.O, o seu código parece estar seguindo os princípios básicos da programação orientada a objetos. No entanto, é sempre bom avaliar se você está separando corretamente as responsabilidades em diferentes classes e métodos, aplicando encapsulamento, reutilização de código e outros conceitos fundamentais da O.O. Seu código parece estar mais focado em operações de manipulação de arquivos do que em um design orientado a objetos complexo, o que é compreensível considerando a natureza específica da tarefa em questão. No geral, é importante continuar estudando e praticando os princípios da O.O para aprimorar suas habilidades de design de software.