Search code examples
javaio

File copier is printing out my whole excerpt, I want it to do it line by line with user input between


I need my program to print this file line by line, waiting for the user to press enter between each one. My code keeps printing the whole excerpt. What do I need to change?

import java.io.*;
import java.util.*;
public class NoteCopier {
    public static void main(String[] args) throws IOException {
    System.out.println("Hello! I copy an excerpt to the screen line for line"
                        + " just press enter when you want a new line!");
    try {
        File file = new File("excerpt.txt");
        FileInputStream fis = new FileInputStream(file);
        InputStreamReader inreader = new InputStreamReader(fis);
        BufferedReader reader = new BufferedReader(inreader);
        String line = reader.readLine();
        Scanner scan = new Scanner(System.in);
        
        while(true) {
                String scanString = scan.nextLine();
                if(line != null) {
                if(scanString.isEmpty()){
                    System.out.println(line);
                    line = reader.readLine();
                }
                else {
                    scanString = null;
                    break;
                }
            
            }
        }
    }
        
    catch(IOException e) {
        e.printStackTrace();
    }
    }
}

Solution

  • If line is null you'll loop forever; the nested if statements.

    I did it in the new Stream style, without the ubiquitous but needless Scanner on System.in.

    private void dump(String file) {
        Path path = Paths.get(file);
        BufferedReader con = new BufferedReader(new InputStreamReader(System.in));
        try (Stream<String> in = Files.lines(path, Charset.defaultCharset())) {
            AtomicInteger lineCounter = new AtomicInteger();
            in.forEach(line -> {
                System.out.println(line);
    
                if (lineCounter.get() == 0) {
                    String input = null;
                    try {
                        input = con.readLine();
                    } catch (IOException e) {
                    }
                    if (input == null) {
                        throw new IndexOutOfBoundsException();
                    } else if (input.equals(" ")) {
                        lineCounter.set(10);
                    }
                } else {
                    lineCounter.decrementAndGet();
                }
            });
        } catch (IndexOutOfBoundsException e) {
            System.out.println("< Stopped.");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    

    With CtrlD you can exit on Windows I believe. I have added that a line with a Space will dump the next 10 lines.

    The ugly thing are the user input lines.


    With java.io.Console one can ask input with a String prompt, which then can be used to print the file's line as prompt.

    private void dump(String file) {
        Path path = Paths.get(file);
        Console con = System.console();
        try (Stream<String> in = Files.lines(path, Charset.defaultCharset())) {
            AtomicInteger lineCounter = new AtomicInteger();
            in.forEach(line -> {
                if (lineCounter.get() == 0) {
                    //String input = con.readLine("%s |", line);
                    String input = new String(con.readPassword("%s", line));
                    if (input == null) {
                        throw new IndexOutOfBoundsException();
                    } else if (input.equals(" ")) {
                        lineCounter.set(10);
                    }
                } else {
                    System.out.println(line);
                    lineCounter.decrementAndGet();
                }
            });
        } catch (IndexOutOfBoundsException e) {
            System.out.println("< Stopped.");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    

    Using a prompt with the file's line, and asking a non-echoed "password" will be sufficient okay. You still need the Enter.

    There is one problem: you must run this as real command line. The "console" in the IDE uses System.setIn which will cause a null Console. I simply create a .bat/.sh file. Otherwise System.out.print(line); System.out.flush(); might work on some operating system.