为了账号安全,请及时绑定邮箱和手机立即绑定

“异常:扫描仪已关闭”如何在(while..循环)内重新打开它

“异常:扫描仪已关闭”如何在(while..循环)内重新打开它

呼如林 2023-11-01 21:56:08
我是编码新手,正在尝试学习 JAVA,并使用不同的方法来完成简单的任务。我想制作一个简单的通讯录,具有“添加联系人、按号码搜索、按姓名搜索等”功能。我的大多数方法都有效,但以下两种方法有问题。当我调用时modify Contact,即使我尝试替换名称,代码也会在文件中创建一个新行。然后我调用delete By Name删除未修改的行,并且收到以下错误。(我知道错误的原因,但我找不到有效的解决方案......)  public static void modifyContact(String namee){        Scanner sca =new Scanner(System.in);        String newName = sca.nextLine();        try  {            String[] s;            boolean foundPerson = false;            Scanner sc = new Scanner(new File("addressBook.txt"));            while (sc.hasNextLine()) {                s = sc.nextLine().split(",");                if (s[0].equals(namee)) {                    s[0]=s[0].replace(s[0],newName);                    System.out.println("Name is " + namee + " phone number is " + s[1] + " ,address is " + s[3] + " and email is " + s[2]);                    foundPerson = true;                    deleteByName(namee);                File file =new File("addressBook.txt");                FileWriter pw = new FileWriter(file,true);                pw.write(s[0]+","+s[1]+","+s[2]+","+s[3]);                pw.close();                }            }            sc.close();            deleteByName(namee);            if (!foundPerson) {                System.out.println("No contact found with " + namee);                }            }             catch (IOException ex) {           //System.out.println(ex.getMessage());                }    }    public static void deleteByName(String na){        try{            File inputFile = new File("addressBook.txt");   // Your file            File tempFile = new File("TempFile.txt");// temp file        BufferedReader reader = new BufferedReader(new FileReader(inputFile));        BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile));        String currentLine;        while((currentLine = reader.readLine()) != null) {            if(currentLine.contains(na))                   continue;            writer.write(currentLine);            writer.newLine();        }
查看完整描述

5 回答

?
三国纷争

TA贡献1804条经验 获得超7个赞

有两种解决方案:

  • 不要关闭扫描仪。保持其打开状态,直到不需要为止。换句话说,在循环之后关闭它。

  • 通过调用 重新创建扫描仪sc = new Scanner(new File("addressBook.txt"));。但是,由于这将创建一个新的扫描仪,因此它将再次从第一行开始读取。


查看完整回答
反对 回复 2023-11-01
?
天涯尽头无女友

TA贡献1831条经验 获得超9个赞

sc.close();您应该在 while 循环之后调用,而不是在其中调用。按照您的逻辑,扫描仪从循环本身的第二次迭代开始就无法使用。



查看完整回答
反对 回复 2023-11-01
?
12345678_0001

TA贡献1802条经验 获得超5个赞

您的主要问题是您deleteByName()在循环内调用删除原始文件然后重用Scanner.

你应该这样做:

  1. 找到所有name

  2. 呼叫deleteByName()与所有发现names

public final class AddressBookManager {


    private final File file;


    public AddressBookManager(File file) {

        this.file = file;

    }


    public void modifyContact(String oldName, String newName) throws IOException {

        if (isContactExists(oldName))

            updateContactName(oldName, newName);

    }


    private boolean isContactExists(String name) throws FileNotFoundException {

        try (Scanner scan = new Scanner(file)) {

            while (scan.hasNextLine()) {

                String str = scan.nextLine();


                if (str.startsWith(name + ',')) {

                    String[] parts = str.split(",");

                    System.out.format("Contact found. Name '%s', phone number '%s', address '%s', email '%s'\n", parts[0], parts[1], parts[2],

                            parts[3]);

                    return true;

                }

            }


            System.out.println("No contact found with name '" + name + '\'');

            return false;

        }

    }


    private void updateContactName(String curName, String newName) throws IOException {

        File tmp = new File(file.getParent(), "TempFile.txt");


        try (BufferedReader in = new BufferedReader(new FileReader(file));

             BufferedWriter out = new BufferedWriter(new FileWriter(tmp))) {

            String str;


            while ((str = in.readLine()) != null) {

                if (str.startsWith(curName))

                    str = newName + str.substring(str.indexOf(','));


                out.write(str);

                out.newLine();

            }

        }


        System.out.println("remove old file: " + file.delete());

        System.out.println("rename temp file: " + tmp.renameTo(file));

    }


    public static void main(String... args) throws IOException {

        AddressBookManager addressBookManager = new AddressBookManager(new File("d:/addressBook.txt"));


        String curName = "oleg";

        String newName = getNewName(curName);

        addressBookManager.modifyContact(curName, newName);

    }


    private static String getNewName(String curName) {

        try (Scanner scan = new Scanner(System.in)) {

            System.out.print("Enter new name for (" + curName + "): ");

            return scan.nextLine();

        }

    }


}


查看完整回答
反对 回复 2023-11-01
?
海绵宝宝撒

TA贡献1809条经验 获得超8个赞

问题是当您使用系统关闭扫描仪时。来自系统的输入流也被关闭。因此,即使您使用 System.in 创建一个新的扫描仪,您也将无法重用该扫描仪。如果您使用的是 java 7,您可以使用 try 和资源来通过 Java 本身关闭所有 autocCleasable 资源。这将解决该问题。


    public static void modifyContact(String namee) {


        File file = new File("addressBook.txt");        

        try (Scanner sca = new Scanner(System.in);

            Scanner sc = new Scanner(file); 

            FileWriter pw = new FileWriter(file, true);) {

            String[] s;

            boolean foundPerson = false;

            String newName = sca.nextLine();

            while (sc.hasNextLine()) {

                s = sc.nextLine().split(",");

                if (s[0].equals(namee)) {

                    s[0] = s[0].replace(s[0], newName);

                    System.out.println("Name is " + namee + " phone number is " + s[1] + " ,address is " + s[3]

                            + " and email is " + s[2]);

                    foundPerson = true;

                    deleteByName(namee);

                    pw.write(s[0] + "," + s[1] + "," + s[2] + "," + s[3]);

                }

            }

            if (!foundPerson) {

                System.out.println("No contact found with " + namee);

            }

        } catch (IOException ex) {

            // System.out.println(ex.getMessage());

        }

    }


查看完整回答
反对 回复 2023-11-01
?
森栏

TA贡献1810条经验 获得超5个赞

我在循环后添加

sc.close();
deleteByName(namee);

看起来效果很好。谢谢大家的帮助。


查看完整回答
反对 回复 2023-11-01
  • 5 回答
  • 0 关注
  • 167 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信