Почему моя программа не записывает информацию в файл?

Мне нужно создать программу, которая считывает имена и идентификационные номера из двух файлов, которые уже находятся в алфавитном порядке, и объединяет их в третьем файле полностью в алфавитном порядке. Файлы организованы так...

фамилия, идентификатор имени (например, rbb091020) фамилия, идентификатор имени

По какой-то причине мой файл читает два файла и создает третий, но ничего не записывает в третий файл.

Вот мой код...

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

public class Combine_Files
{
public static void main(String[]args) throws IOException
{
    String filename1 = "";
    String filename2 = "";
    String combinedFileName = "";
    String response = "";
    String nextName1 = "";
    String nextName2 = "";
    String nextIDNumber1 = "";
    String nextIDNumber2 = "";
    boolean okToOverwrite = false;
    Scanner keyboard = new Scanner(System.in);

    System.out.println("What is the name of the first file?");
    filename1 = keyboard.nextLine();

    File file1 = new File(filename1);

    if (!file1.exists())
    {
        System.out.println(file1 + " does not exist.\nTerminating Program.");
        System.exit(0);
    }

    System.out.println("What is the name of the second file?");
    filename2 = keyboard.nextLine();

    File file2 = new File (filename2);
    if (!file2.exists())
    {
        System.out.println(file2 + " does not exist.\nTerminating Program.");
        System.exit(0);
    }   

    System.out.println("What is the name of the file that you wish to create?");
    combinedFileName = keyboard.nextLine();
    File combinedFile = new File (combinedFileName);

    while (combinedFile.exists() && !okToOverwrite)
    {
        System.out.println("\nError, a file named " +
            combinedFileName + " already exists." +
            "\nWould you like to overwrite this file?" +  
            "\nEnter Y for Yes or N for No.");
        response = keyboard.nextLine();

        // Add input validation on response

        if (response.equalsIgnoreCase("Y"))
        {
            okToOverwrite = true;
        }
        else 
        {
            System.out.println("Enter a new filename.");
            combinedFileName = keyboard.nextLine();
            combinedFile = new File(combinedFileName);
        }
    }

    if (file1.exists() && file2.exists())
    {

        Scanner list1 = new Scanner(file1);
        Scanner list2 = new Scanner(file2);
        PrintWriter outputFile = new PrintWriter(combinedFile);

            while (list1.hasNext() && list2.hasNext())
            {
                nextName1 = list1.nextLine();
                nextName2 = list2.nextLine();

                if(nextName1.compareToIgnoreCase(nextName2) <0)
                {
                    outputFile.print(nextName1);
                    nextName1 = list1.nextLine();
                    outputFile.print(nextName1);
                }
                else if(nextName1.compareToIgnoreCase(nextName2) >0)
                {
                    outputFile.println(nextName2);
                    nextName2 = list2.nextLine();
                    outputFile.println(nextName2);
                }
                else
                {
                    outputFile.println(nextName1);
                    nextName1 = list1.nextLine();
                    outputFile.println(nextName1);
                    outputFile.println(nextName2);
                    nextName2 = list2.nextLine();
                    outputFile.println(nextName2);
                }       
            }

            while (list1.hasNext() && !list2.hasNext())
            {
                outputFile.println(nextName1);
            }

            while (list2.hasNext() && !list1.hasNext())
            {
                outputFile.println(nextName2);
            }       
    }
}   
}           

person rahme24    schedule 07.04.2012    source источник


Ответы (2)


Когда вы используете класс записи, такой как PrintWriter, вам нужно убедиться, что вы вызываете метод flush() каждый раз, когда хотите что-то напечатать в STDOUT или в файл. Таким образом, в основном всякий раз, когда вы вызываете любой из методов печати PrintWriter, он записывает во внутренний буфер, вызов flush() отправляет буфер в соответствующий выходной поток.

        while (list1.hasNext() && list2.hasNext())
        {
            nextName1 = list1.nextLine();
            nextName2 = list2.nextLine();

            if(nextName1.compareToIgnoreCase(nextName2) <0)
            {
                outputFile.print(nextName1);
                nextName1 = list1.nextLine();
                outputFile.print(nextName1);
            }
            else if(nextName1.compareToIgnoreCase(nextName2) >0)
            {
                outputFile.println(nextName2);
                nextName2 = list2.nextLine();
                outputFile.println(nextName2);
            }
            else
            {
                outputFile.println(nextName1);
                nextName1 = list1.nextLine();
                outputFile.println(nextName1);
                outputFile.println(nextName2);
                nextName2 = list2.nextLine();
                outputFile.println(nextName2);
            }
            outputFile.flush(); // <--- flush added here       
        }

        while (list1.hasNext() && !list2.hasNext())
        {
            outputFile.println(nextName1);
            outputFile.flush(); // <--- flush added here 
        }

        while (list2.hasNext() && !list1.hasNext())
        {
            outputFile.println(nextName2);
            outputFile.flush(); // <--- flush added here 
        }       

Эти вызовы flush() должны записывать в файл.

person Hunter McMillen    schedule 07.04.2012
comment
или просто сделайте это autoFlush при вызове конструктора PrintWriter(OutputStream out, boolean autoFlush) - person Eng.Fouad; 07.04.2012
comment
Проблемы со сбросом были моим первым подозрением, но даже в этом случае файл должен быть очищен, когда дескриптор закрыт и виртуальная машина выходит. у этой программы другие проблемы. - person aaron; 07.04.2012
comment
@Eng.Fouad Eng.Fouad Согласно документам, опция автоматической очистки работает только для println, printf и format. Плакат использует print() вперемешку с println, поэтому я выбрал вызовы flush() вручную. - person Hunter McMillen; 07.04.2012
comment
@HunterMcMillen Это странно! Однако close()ing поток в конце буферизует данные в приемник. - person Eng.Fouad; 07.04.2012
comment
Мы еще не узнали о flush(), и мы не должны использовать что-то другое, кроме того, что мы узнали. Но мы узнали, что вещи застревают в буфере клавиатуры. Будет использование keyboard.nextLine(); работать, чтобы смыть его? Нет ли другого способа смыть его? - person rahme24; 07.04.2012

В этой программе есть логические ошибки. Когда я тестирую файлы разной длины, он застревает в бесконечном цикле в одном из двух последних циклов while и действительно записывает в выходной файл до тех пор, пока программа не будет принудительно завершена. Если файлы имеют одинаковую длину, то сканер не может прочитать строку в одном из предложений if/else.

person aaron    schedule 07.04.2012
comment
Кроме того, как вы заставили его писать в третий файл? По какой-то причине он записывает только пустой файл в мой третий файл. - person rahme24; 07.04.2012
comment
Я не знаю, почему он не сразу записывает в выходной файл, но поведение, вероятно, зависит от ввода. Мои два файла просто содержали b c и d e f соответственно, каждый в строке, конечно. Вам необходимо отладить эту программу либо путем вывода вывода (System.err.println(Запись xxxx в файл yyy)) либо с помощью пошагового отладчика, чтобы вы понимали, что делает программа. - person aaron; 10.04.2012