【问题标题】:Incorrect file interpretation/ population文件解释/填充不正确
【发布时间】:2019-01-17 22:21:00
【问题描述】:

我刚刚学会了如何编码,我正在尝试创建一个具有注册和登录功能的应用程序。下面的代码将用户名和密码添加到工作正常的文本文件中。

但是,当我尝试使用用户名和密码登录时,verifyLogin 方法不起作用。如果我手动将密码和用户名添加到文本文件中,那么它将正常工作。我最好的猜测是有一些转换错误,但我不确定。

这是在文件中添加用户名和密码的代码:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    String user = User.getSelectedItem().toString();
    String username = Username.getText();
    String password = Password.getText();
    String passwordConfirm = Password2.getText();

    if (user.trim().isEmpty() ||password.trim().isEmpty() || passwordConfirm.trim().isEmpty()){
        JOptionPane.showMessageDialog(rootPane, "Please fill out all fields");
    }
    else if(User.getSelectedItem().equals("Please Select")){
        JOptionPane.showMessageDialog(rootPane, "Please select wether you are a student ot a teacher");
    }
    else if(!password.equals(passwordConfirm)){
        JOptionPane.showMessageDialog(rootPane, "Please ensure the passwords you enter match");
    }
    else{
        if(User.getSelectedItem().equals("Student")){
            try{
                FileWriter writer = new FileWriter("Students.txt", true);
                writer.write(System.getProperty("line.separator"));
                writer.write(username);
                writer.write(",");
                writer.write(password);
                writer.close();
                JOptionPane.showMessageDialog(rootPane, "Success. You now have a students account");
                MainGUI  x = new MainGUI();
                x.setVisible(true);
                this.dispose();
            }
            catch(HeadlessException | IOException e){
                JOptionPane.showMessageDialog(rootPane, "Error");
            }
        }
        else{
            try{
                FileWriter writer = new FileWriter("Teachers.txt", true);
                writer.write(System.getProperty("line.separator"));
                writer.write(username);
                writer.write(",");
                writer.write(password);
                writer.close();
                JOptionPane.showMessageDialog(rootPane, "Success. You now have a teacher account");
                MainGUI  x = new MainGUI();
                x.setVisible(true);
                this.dispose();
            }
            catch(HeadlessException | IOException e){
                JOptionPane.showMessageDialog(rootPane, "Error");
            }  
        }
    }
}      

这是教师登录的代码:

public static void verifyLogin(String username, String password){
    boolean found = false;
    String tempUsername = "";
    String tempPassword = "";

    java.io.File file = new java.io.File("Teachers.txt");
    try{
        Scanner input = new Scanner(file);
        input.useDelimiter("[,\n]");

        while(input.hasNext() && !found){
            tempUsername = input.next();
            tempPassword = input.next();

            if (tempUsername.trim().equals(username.trim()) && tempPassword.trim().equals(password.trim())){
                found = true;
                TeacherOption  x = new TeacherOption();
                x.setVisible(true);
                this.dispose();
            }
            else{
                TeacherLoginError  x = new TeacherLoginError();
                x.setVisible(true);
                this.dispose();
            }
        }
        input.close();

    }
    catch(FileNotFoundException e){
        System.err.format("File does not exist \n");
    }
} 

【问题讨论】:

  • 您的代码将密码写入文件后,您是否查看了该文件?它看起来像您想要的那样吗,尤其是在您显示空白字符的情况下?问题之一是,在写作时您使用的是line.separator,而在阅读时,您假设行分隔符是\n。请注意,这些可能不是一回事,因此您的分隔符可能无法正常工作,即 Windows 通常将 \r\n 作为行分隔符,因此您的密码可能以 \r 结尾。 (顺便说一句,请注意这样做是非常不安全的,所以只需将其用于练习。)
  • 刚刚检查过,trim() 应该为您摆脱 \r(回车)。您是否使用调试器单步调试代码(例如,直接从 IDE 运行代码时)并检查从文件中读取的值?
  • @Thomas trim() 去掉了 \r,但它不会阻止 \r 将第一行作为标记。虽然我猜可能还有其他问题。应该逐行读取文件并使用 split() 分隔用户名和密码。

标签: java file binary


【解决方案1】:

在文件的开头创建一个 换行符 会导致问题。假设您正在输入 3 usernamepassword

//empty line
Test1,TestPass1
Test2,TestPass2
Test3,TestPass3

您的数据在扫描仪中是这样读取的,

user-1:

pass-1:Test1
user-2:TestPass1

pass-2:Test2
user-3:TestPass1

pass-3:Test3
user-4:TestPass3

pass-4:Test4
user-5:TestPass4
pass-5:

因此造成了麻烦。

以下更改应该可以解决您的问题,

FileWriter writer = new FileWriter("Students.txt", true);
writer.write(username);
writer.write(",");
writer.write(password);
writer.write(System.getProperty("line.separator"));//add the new line after writing your user credentials
writer.close();

另外我建议每行读取数据(以避免逻辑错误和更清晰的数据拾取)并尝试以加密格式存储 密码

input.useDelimiter("\n");//take input per line
while(input.hasNext() && !found){
    String userDetails=input.next().trim();
    String credentialInfo[]=userDetails.split(",");
    if(!userDetails.isEmpty() 
            && credentialInfo.length==2) {//validate your input
        tempUsername = credentialInfo[0];
        tempPassword = credentialInfo[1];
        if (tempUsername.trim().equals(username.trim()) 
                && tempPassword.trim().equals(password.trim())){
              //rest of your code...

【讨论】:

    【解决方案2】:

    我刚刚又查看了您的代码,我不敢相信我没有看到这一点:在您的 while 循环中,只要一组用户名和密码与输入不匹配,您就会显示 TeacherLoginError

    问题?如果您有一个在匹配之前不匹配的集合(这是更常见的情况),即使稍后的迭代会找到正确的集合,您也会显示错误。所以首先迭代并寻找匹配的用户名和密码,循环之后,您根据是否找到某些内容来决定显示什么。

    我的意思是:

    假设您的文件包含以下内容:

    user1,password1
    user2,password2
    

    现在我输入“user2”和“password2”。您的代码(我们假设它正确读取数据)首先根据user1,password1 进行检查,由于不匹配,您调用 else-branch:

    TeacherLoginError  x = new TeacherLoginError();
    x.setVisible(true);
    this.dispose();
    

    您需要做的事情(重用您的代码):

    //first look for a match only
    boolean found = false;
    while(input.hasNext() && !found){
      tempUsername = input.next();
      tempPassword = input.next();
    
      if (tempUsername.trim().equals(username.trim()) && tempPassword.trim().equals(password.trim())){
         found = true;
         break; //end the loop, you've already found a match
      }
    }
    
    //after the loop you act based on whether you found a match or not
    if(found) {
      TeacherOption  x = new TeacherOption();
      x.setVisible(true);
    } else {
      TeacherLoginError  x = new TeacherLoginError();
      x.setVisible(true);
    }
    
    this.dispose(); //this is called anyways so no need to have it twice
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-18
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      • 2015-10-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多