Программа только записывает в файл, если я закрываю его вручную? - PullRequest
1 голос
/ 02 октября 2019

Файл KnockKnockServer

Запускает сервер

public static void main(String[] args) {
        /* Create new Server object
         * Call run() on new Server object
         */
        KnockKnockServer kks = new KnockKnockServer();
        kks.run();

    }

Запускает новые темы и открывает файл журнала.

 private void run(){
        try {
            File logfile = new File("prog1b.log");
            FileOutputStream fos = new FileOutputStream(logfile);
            PrintWriter out = new PrintWriter(fos, true);
            ServerSocket serverSocket = new ServerSocket(5520);
            while(true){
                try {
                    Socket serverClient = serverSocket.accept();
                    KnockKnockServerThread kkst = new KnockKnockServerThread(serverClient, out);
                    kkst.start();
                } catch (IOException evt) {
                    System.out.println("Error");
                }
            }
        } catch (IOException evt) {
            System.out.println("error");
        }
    }

KnockKnockThread file

public KnockKnockServerThread(Socket clientSocket, PrintWriter logfile) {
            serverClient = clientSocket;
            lOut = logfile;
        }

Это делает запись в файл и отвечает клиенту.

public void run() {
            try {
                sOut = new PrintWriter(serverClient.getOutputStream(), true);
                lOut.write(formatter.format(date) + ": Client connected from " + serverClient.getRemoteSocketAddress() + " on port # " + serverClient.getPort() + ".\n");
                in = new BufferedReader(new InputStreamReader(serverClient.getInputStream()));

                String clientMessage = "", serverMessage = "";

                while (!clientMessage.equals("quit")) {
                    clientMessage = in.readLine();
                    if(!clientMessage.equals("quit")) {
                        serverMessage = encrypt(clientMessage);
                        sOut.println(serverMessage);
                        lOut.write(formatter.format(date) + " Client " + serverClient.getPort() + ": " + clientMessage + "\n");
                        lOut.write(formatter.format(date) + " Server: " + serverMessage + "\n");
                    }
                    else if(clientMessage.equals("quit")){
                        sOut.println("Good Bye!\n");
                        lOut.write(formatter.format(date) + ": Connection closed on port " + serverClient.getPort() + ".\n");
                    }
                }
                sOut.close();
                in.close();
                serverClient.close();
            } catch (IOException e) {
                System.out.println("Error");

            }
        }

Общая суть программы

По какой-либо причине я могу видеть текст в файле журнала только при закрытии файла вручную. В противном случае это совершенно пусто. Я не могу найти в Интернете ничего, чтобы помочь. Я подумал, что, возможно, он возвращается к первому запуску () и создает новый файл, который будет очищать текст, но я помещал операторы печати везде, но это было не так. Я полностью сбит с толку. Я не могу закрыть файл, так как сервер должен быть готов к записи в файл журнала из других потоков.

Ответы [ 4 ]

5 голосов
/ 02 октября 2019

Если вы хотите записать данные в файл раньше, вам нужно вызвать flush () в потоке. Это связано с тем, что данные обычно буферизуются для производительности ввода-вывода. Из документов метода flush:

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

2 голосов
/ 02 октября 2019

Обычно файловый ввод / вывод буферизуется. Что вам нужно сделать, это очистить файл (что происходит автоматически при закрытии файла, но это также можно сделать самостоятельно, вызвав соответствующий метод).

0 голосов
/ 03 октября 2019

Если вы немного углубитесь в Unix, файловый ввод / вывод буферизуется. Когда вы, например, записываете в файл, вы используете системный вызов:

write(file_descriptor,user_space_buffer,count).

Вы записываете из буфера в файл (который находится на диске). write(...) делает то, что он копирует данные из буфера в пользовательском пространстве в буфер ядра и сразу же возвращается. Это сделано для того, чтобы вызов не занимал много времени (так как дисковый ввод-вывод дорог).

Закрытие файла приведет к освобождению дескриптора файла и очистке буфера.

Примечание: Вы также можете выполнять прямой ввод-вывод, минуя буфер уровня ядра.

0 голосов
/ 02 октября 2019

Вы можете использовать попытку с ресурсами и посмотреть, решит ли это вашу проблему: https://www.baeldung.com/java-try-with-resources

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...