如何在字符串中插入新行字符以便于PrintStream打印,然后使用Scanner重新读取文件。

10
我有几个类设计用于模拟图书目录。我有一个Book类(isbn、title等),一个BookNode类,一个BookCatalog类,其是一个书籍的LinkedList和一个驱动程序类(gui)。我的问题在于,我在BookCatalog中使用了toString()方法,它应该返回所有书籍的字符串表示形式。Book类还覆盖了toString()。我需要让每个书籍字段都由“制表符”分隔,每个书籍都由“新行”分隔。当我尝试将书籍目录使用PrintStream打印到.txt文件时,\n无法被识别。
我尝试将它更改为System.getProperty(line.separator),这样可以正确显示bookcatalog。但现在我有一个问题,Scanner无法正确读取文件,并抛出“NoSuchElementException”。我如何使scanner忽略line.separator或使printStream使用\n?
Book.java
public String toString(){
        return isbn+"\t"+lastName+"\t"+firstName+"\t"+title+"\t"+year+"\t"+
            String.format("%.2f",price);

BookCatalog.java

public String toString() {
        BookNode current = front;
        String s="";
        System.out.println(s);
        while (current!=null){
            //each book is listed on separate line
            s+=current.getData().toString()+"\n ";//System.getProperty("line.separator")
            current = current.getNext();
        }
        return s;
    }

Driver.java

public void loadDirectory() throws FileNotFoundException {
        if (f.exists()){
            Scanner input = new Scanner(f);
            while (input.hasNextLine()){
                String bookLine = input.nextLine();
                processBookLine(bookLine);
            }
        }
    }

public void processBookLine(String line){
        Scanner input = new Scanner(line);
        String isbn = input.next();
        String lastName = input.next();
        String firstName = input.next();

        String title = input.next();
        while (input.hasNext() && !input.hasNextInt()){//while next token is not an integer
            title += " "+input.next();
        }
        int year = input.nextInt();
        double price = input.nextDouble();
        Book book = Book.createBook(isbn, lastName, firstName, title, year, price);
        if (book!=null){
            catalog.add(book);
        }
    }

如果你声称 PrintStream 抑制了 \r,那么你是错的。你问题的其余部分不够清晰。 - user207421
我使用了System.getProperty("line.separator")而不是\n,所以当我打开新创建的文件(来自PrintStream)并尝试重新读取它(scanner)时,它将无法处理该行。我认为"line.separator"是原因,所以我尝试将字符保存在另一个变量中来绕过它,但也没有成功。 - Sara
1个回答

31
<\p>在某些操作系统(如Windows中的“\r\n”)中,换行字符\n不是行分隔符。我的建议是您改用\r\n,这样它将同时接受只有\n\r\n的换行符。我一直使用它,从未遇到过任何问题。

此外,在BookCatalog.toString()的while循环中连接String非常低效,您应该考虑使用StringBuilder代替。例如:

public String toString() {
        BookNode current = front;
        StringBuilder sb = new StringBuilder();
        while (current!=null){
            sb.append(current.getData().toString()+"\r\n ");
            current = current.getNext();
        }
        return sb.toString();
}

我看不出来为什么这会有任何影响。Scanner已经处理了\n、\r和\r\n作为行终止符,还有其他几个也是。 - user207421
@EJP 扫描器是可以的,但如果你在Windows上用记事本打开一个只有 \n 的 .txt 文件,它将不会被识别。 - ddmps
@ddmps 在末尾插入了一行额外的内容!请建议如何处理! - AVA
2
@AVA 我不认为“额外”的那一行有问题。请参考https://dev59.com/b3RB5IYBdhLWcg3wET1J#729795。 - ddmps
@ddmps 感谢您提供的参考,让事情更加明确! - AVA
使用“\r\n”代替“\n”对我来说完全没问题。非常感谢你,已经点赞了! - iamjoshua

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接