无法从文件中读取用户名
Cannot read usernames from file
我正在尝试实现一个仅包含用户名密码和电子邮件的注册面板。我将所有用户名和密码放在一个文本文件中 "usernames.txt"。但是如果用户单击提交按钮并且用户名已经存在,我的问题将无法正常工作(它应该显示带有文本 "Username already exists!" 的 JOptionPane)。这是我的代码:
submitButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("usernames.txt"));
} catch (FileNotFoundException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
try {
String line = br.readLine();
StringBuilder sb = new StringBuilder();
Pattern usernameAndPasswordPattern = Pattern.compile("^(\S+) (\S+)$");
while (line != null) {
sb.append(line); //
sb.append(System.lineSeparator()); //
line = br.readLine();
}
String everything = sb.toString();
Matcher userNameAndPasswordMatcher = usernameAndPasswordPattern.matcher(everything);
//if username exists!
while (userNameAndPasswordMatcher.matches()) {
String username = userNameAndPasswordMatcher.group(1);
String password = userNameAndPasswordMatcher.group(2);
if (username.equals(usernameTextField.getText())) {
int result = JOptionPane.showConfirmDialog(null, "Username already exists!", "Registration incomplete", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE);
}
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} finally {
try {
br.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
});
在这里你可以看到我面板上的图片
您说文件中的行由用户名和密码组成。然而你正在测试这样的匹配:
boolean matches = Pattern.matches(""+usernameTextField.getText(), line);
以上问题。
match
动词 Pattern
或 Matcher
表示 "it matches the entire string"。
Pattern.matches(String, String)
的第一个参数应该是表示为字符串的正则表达式,而不仅仅是任何旧字符串。现在,如果您的用户名字母表受到适当限制,可能 可以使用该名称作为正则表达式。但这是个坏主意。
即使将 "match" 更改为 "find",您仍然可能让提供的用户名与密码或 部分 文件中的用户名。
断章取义(即忽略第 3 点),这样匹配会更好:
boolean matches = line.contains(""+usernameTextField.getText());
或者也许
boolean matches = Pattern.find(
Pattern.quote(""+usernameTextField.getText()), line);
但是,这仍然存在您可能会得到错误匹配的问题;例如匹配部分用户名...甚至密码。
因此,正确的解决方案是制作一个匹配文件中 整个 用户名字段的正则表达式,或者将这些行拆分为多个字段(例如 String.split
然后使用 String.equals
根据提供的用户名测试适当的字段。
虽然@StephenC 的回答适用于你的情况,但它非常具体,我认为可以更优雅地解决它。
既然你说了
,你定义一个将用户名和密码分成两组的 RegEx-Pattern 怎么样?
the usernames.txt are in the format {Username} {Password}
您可以使用 RegEx ^(\S+) (\S+)$
,这意味着第 1 组中的一组非空字符 space,后跟一个 space,然后是一个非空字符一组非白色space字符(在https://regex101.com/查看)
这里是用Java自带的库实现的
private static final Pattern usernameAndPasswordPattern = Pattern.compile("^(\S+) (\S+)$");
public static void checkInput(String input) throws IOException {
try(BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(new File("usernames.txt"))))) {
String line = br.readLine();
while(line != null) {
Matcher userNameAndPasswordMatcher = usernameAndPasswordPattern.matcher(line);
if(userNameAndPasswordMatcher.matches()) {
String username = userNameAndPasswordMatcher.group(1);
String password = userNameAndPasswordMatcher.group(2);
if(username.equals(input)) {
System.out.println("Username exists!");
System.out.println("Password is: " + password);
break;
}
}
line = br.readLine();
}
}
}
我用这个来测试它
public static void main(String[] args) throws IOException {
System.out.println("main > calling checkInput('Gary')..");
checkInput("Gary");
System.out.println("main > calling checkInput('Donald')..");
checkInput("Donald");
System.out.println("main > calling checkInput('Gordon')..");
checkInput("Gordon");
}
这是我的测试数据
Peter 123peter567
Gary newman
Gordon fr33m4n
和我的输出
main > calling checkInput('Gary')..
Username exists!
Password is: newman
main > calling checkInput('Donald')..
main > calling checkInput('Gordon')..
Username exists!
Password is: fr33m4n
我正在尝试实现一个仅包含用户名密码和电子邮件的注册面板。我将所有用户名和密码放在一个文本文件中 "usernames.txt"。但是如果用户单击提交按钮并且用户名已经存在,我的问题将无法正常工作(它应该显示带有文本 "Username already exists!" 的 JOptionPane)。这是我的代码:
submitButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("usernames.txt"));
} catch (FileNotFoundException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
try {
String line = br.readLine();
StringBuilder sb = new StringBuilder();
Pattern usernameAndPasswordPattern = Pattern.compile("^(\S+) (\S+)$");
while (line != null) {
sb.append(line); //
sb.append(System.lineSeparator()); //
line = br.readLine();
}
String everything = sb.toString();
Matcher userNameAndPasswordMatcher = usernameAndPasswordPattern.matcher(everything);
//if username exists!
while (userNameAndPasswordMatcher.matches()) {
String username = userNameAndPasswordMatcher.group(1);
String password = userNameAndPasswordMatcher.group(2);
if (username.equals(usernameTextField.getText())) {
int result = JOptionPane.showConfirmDialog(null, "Username already exists!", "Registration incomplete", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE);
}
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} finally {
try {
br.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
});
在这里你可以看到我面板上的图片
您说文件中的行由用户名和密码组成。然而你正在测试这样的匹配:
boolean matches = Pattern.matches(""+usernameTextField.getText(), line);
以上问题。
match
动词Pattern
或Matcher
表示 "it matches the entire string"。Pattern.matches(String, String)
的第一个参数应该是表示为字符串的正则表达式,而不仅仅是任何旧字符串。现在,如果您的用户名字母表受到适当限制,可能 可以使用该名称作为正则表达式。但这是个坏主意。即使将 "match" 更改为 "find",您仍然可能让提供的用户名与密码或 部分 文件中的用户名。
断章取义(即忽略第 3 点),这样匹配会更好:
boolean matches = line.contains(""+usernameTextField.getText());
或者也许
boolean matches = Pattern.find(
Pattern.quote(""+usernameTextField.getText()), line);
但是,这仍然存在您可能会得到错误匹配的问题;例如匹配部分用户名...甚至密码。
因此,正确的解决方案是制作一个匹配文件中 整个 用户名字段的正则表达式,或者将这些行拆分为多个字段(例如 String.split
然后使用 String.equals
根据提供的用户名测试适当的字段。
虽然@StephenC 的回答适用于你的情况,但它非常具体,我认为可以更优雅地解决它。
既然你说了
,你定义一个将用户名和密码分成两组的 RegEx-Pattern 怎么样?the usernames.txt are in the format {Username} {Password}
您可以使用 RegEx ^(\S+) (\S+)$
,这意味着第 1 组中的一组非空字符 space,后跟一个 space,然后是一个非空字符一组非白色space字符(在https://regex101.com/查看)
这里是用Java自带的库实现的
private static final Pattern usernameAndPasswordPattern = Pattern.compile("^(\S+) (\S+)$");
public static void checkInput(String input) throws IOException {
try(BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(new File("usernames.txt"))))) {
String line = br.readLine();
while(line != null) {
Matcher userNameAndPasswordMatcher = usernameAndPasswordPattern.matcher(line);
if(userNameAndPasswordMatcher.matches()) {
String username = userNameAndPasswordMatcher.group(1);
String password = userNameAndPasswordMatcher.group(2);
if(username.equals(input)) {
System.out.println("Username exists!");
System.out.println("Password is: " + password);
break;
}
}
line = br.readLine();
}
}
}
我用这个来测试它
public static void main(String[] args) throws IOException {
System.out.println("main > calling checkInput('Gary')..");
checkInput("Gary");
System.out.println("main > calling checkInput('Donald')..");
checkInput("Donald");
System.out.println("main > calling checkInput('Gordon')..");
checkInput("Gordon");
}
这是我的测试数据
Peter 123peter567
Gary newman
Gordon fr33m4n
和我的输出
main > calling checkInput('Gary')..
Username exists!
Password is: newman
main > calling checkInput('Donald')..
main > calling checkInput('Gordon')..
Username exists!
Password is: fr33m4n