In case of PrintWriter why should I flush in the l

2019-06-25 05:47发布

问题:

I have a Server and Client in my little demo program, where I send some string data from the Client to the Server, and after that resending this data for the Client, which also writes it out to the console. I was confused by PrtintWriter's flush method, which is - according to the JAVA documentation, - flushes the stream. After some researching I'm getting familiar with the concept of autoflash: when the autoFlash parameter is true println, printf, or format methods will flush the output buffer. The only thing what I don't understand here is why should I use the PrintWriter's flush method in the loop and not after the loop. (In my case I use PrintWriter in the Server side.) Autoflash does the same because the println() method is in the loop too. When I use flush after the loop my string data does not appear on the console. Thank you for your guidance and help in advance!

The Client:

public class ClientDemo {
public static void main(String[] args) throws IOException {

    final String CLIENTNAME = "<CLIENT>:";
    final String SERVERADDRESS = "localhost";
    final int PORT = 12312;

    try {
        Socket socket = new Socket(SERVERADDRESS, PORT);
        PrintWriter out =
          new PrintWriter(socket.getOutputStream(), true);                   
        Scanner scanner = new Scanner(socket.getInputStream());

        System.out.println(CLIENTNAME + "Client starts");
        List<String> lista = getList();

        for(String userInput : lista){
            out.println(userInput);
            System.out.println("echo: " + scanner.nextLine());
        }

    } catch(IOException e) {
        System.out.println(CLIENTNAME + "Error connecting to the server:" + e.getMessage());
    }
}

  private static List<String> getList(){
        List<String> result = new ArrayList<>();
        result.add("egy");
        result.add("ketto");
        result.add("harom");
        result.add("negy");

        result.add("ot");
        result.add("hat");
        result.add("het");
        result.add("nyolc");
        result.add("kilenc");
        result.add("tiz");

        return result;
    }
}

The Server:

public class ServerDemo {
public static void main(String args[]) throws IOException {

    final int PORT = 12312;
    final String SERVERNAME ="<SERVER>:";

    try {
        ServerSocket serverSocket = new ServerSocket(PORT);
        Socket socket = serverSocket.accept();
        PrintWriter printWriter = new PrintWriter(socket.getOutputStream());
        Scanner scanner = new Scanner(socket.getInputStream());

        System.out.println(SERVERNAME + "Server starts...");

        String inputLine;
        while(scanner.hasNext()) {
            inputLine = scanner.nextLine();
            printWriter.println(inputLine);
            printWriter.flush();
        }

    } catch (IOException e) {
        System.out.println(SERVERNAME + "Error handleing client...");
    } 
   }
}

回答1:

You don't have to call flush after writing every line. You are blocking the I/O by doing that. By calling flush you are ensuring that every line you are writing to the socket is actually written and not just buffered (to be written later). Buffering improves the I/O performance. But here it seems that for some reasons, you are not leveraging the advantages the buffering gives. You are blocking until the write is completely done.