File handling: Loop through text file and continually compare parameters - java

I'm looping through text file and need to compare the contents of the text file to parameters being submitted by a user. The code I've written so far will only compare the last value in the text file.
Question: How would I continually loop and check the contents V parameters passed, stopping when there's a match between the two?
Here's what I have so far:
public boolean isAuthenticated(String username, String password) throws FileNotFoundException{
boolean status = true;
File file = new File("C:\\" "\\" "\\login.txt");
Scanner scan = new Scanner(file);
List<Login> login = new ArrayList<Login>();
while(scan.hasNextLine()){
String line = scan.nextLine();
String [] details = line.split(":");
String storedUsername = details[0];
String storedPassword = details[1];
Login l = new Login(username, password);
if(storedUsername.equals(username)&& storedPassword.equals(password)){
status = true;
}else{
status = false;
}
}
return status;
}
Thanks! Query6273

Your code does compare every line of the file to the username and password. But at each iteration, you replace the previous value of status with the status of the current line.
So you end up returning the status of the last line.
You need to break out of the loop as soon as you found the user you were looking for. For example:
while (scan.hasNextLine()) {
...
if (storedUsername.equals(username) && storedPassword.equals(password)) {
return true;
}
}
or
// we haven't found the user yet, so status is false
boolean status = false;
while (scan.hasNextLine() && !status) {
...
if (storedUsername.equals(username) && storedPassword.equals(password)) {
status = true;
}
}
return status;
Note that the Scanner should be closed properly. You should use try-with-resources.

Related

How do I delete a row or amend an element in a CSV file using Java?

I'm trying to create a csv file with names and ID numbers in order to create individual users. It is also used to identify whether an user has admin status or not (boolean). If I accidentally input a user as an admin when they are not, how can I delete that user or edit his status? I am using an array list. Thanks.
I've included my load method for any clarification needed. I'm new to Stack Overflow so please excuse any formatting errors.
public static void load() throws IOException
{
System.out.println("<<< Loading users >>>");
File userFile = new File("user.csv");
if (!userFile.exists())
{
userFile.createNewFile();
System.out.println("Data file not found.");
add(); // or go and add an item -->addItem()
}
FileReader fr = new FileReader(userFile);
BufferedReader in = new BufferedReader(fr); //read mode
String newfirstName = "";
int newSchool_ID = 0;
String admin = "Y";
String isAdmin = "";
boolean newisAdmin = false;
String temp;
users.clear();
temp = in.readLine(); // read the heading and ignore it
while (in.ready()) // read lines while file has content
{
newisAdmin = false;
temp = in.readLine();
String[] line = temp.split(",");
newfirstName = line[0];
newSchool_ID = Integer.parseInt(line[1]);
if(admin.equals(line[2])){
isAdmin = "Admin";
newisAdmin = true;
}
User newUser = new User(newfirstName, newSchool_ID, newisAdmin);
users.add(newUser);
}
in.close();
System.out.println("User loaded.");
}

Java GUI Search Word From File Then Continue

I have a GUI for user login.
First the user creates his account, and that information is stored in a .txt file. I use PrintWriter to append details in that file.
The details are stored using a separator. I can easily read every detail of a user from the file.
In the login UI, I have 2 JTtextField components in a JFrame the first one for the user name and the second onw for the password.
I get the values using the getText method:
String user = user.getText();
String password = password.getText();
I tried using BufferedReader but I can't get it to work:
if(user.equals(br.readline))
What i want to do is scan the file and if anything in the file is equal to the username (The getText from user on Frame) then I want to use SetVisible to go to Next Frame
My problem is that even on wrong password and user it go to new frame
How can I fix that?
Code to Check for User and Password, found online on StackOverflow still now working.
Scanner sc = new Scanner(new File("Details.txt"));
while(sc.hasNextLine()) {
int val =0;
String line = sc.nextLine();
if(line.indexOf(user) !=-1 && line.indexOf(pass) !=-1) {
JOptionPane.showMessageDialog(null,"Login");
val = 1;
vf.setVisible(true);
break;
} else {
JOptionPane.showMessageDialog(null,"Invalid");
val = 0;
break;
}
}
Another Code which is used in for , while even in do while loop , still not working.
File file = new File("Details.txt");
BufferedReader br = new BufferedReader(new FileReader("Details.txt"));
String Line;
do{
if(user.equals(br.readLine()) && pass.equals(br.readLine())){
vf.setVisible(true);
} else {
JOptionPane.showMessageDialog(null,"Invalid");
}
}while((Line=br.readLine()) !=null )
This is how Users Details are Stored in My File.
=======================
=======================
First Name = Ahmed Ali
Last Name = Qazi
Address = Al-Abbass Colony pHase 2
Phone Number = +92032329301
Email Address = ahmedrider56#gmail.com
UserName = ahmedfirst67
Password = dangerd = 2hg
=======================
=======================
=======================
=======================
First Name = Ahm345
Last Name = Qa345
Address = Al-asfafs
Phone Number = +92032329301
Email Address = ahmgsdg
UserName = ahmegg
Password = dagg
It is not straightforward given your file structure but you can do it this way:
Scan the file until you find the username.
Once you found the user name, keep scanning until you reach the password line.
Read this password and exit the scanning loop.
Then compare the given password with the one you found in the file.
Here is the code:
private static boolean checkCredentials(String user, String pass) throws IOException {
Scanner sc = new Scanner(new File("Details.txt"));
boolean userFound = false;
String correctPassword = null;
String line;
while(sc.hasNextLine()) {
line = sc.nextLine();
// find the user
if(!userFound) {
userFound = line.contains("UserName = "+user);
} else {
// find the password
if(line.contains("Password = ")) {
correctPassword = line.substring(line.indexOf("=") + 2);
break;
}
}
}
return correctPassword!=null && correctPassword.equals(pass);
}
public static void main(String[] args) throws IOException {
System.out.println(checkCredentials("Bob", "dagg"));
System.out.println(checkCredentials("ahmegg", "daggy"));
System.out.println(checkCredentials("ahmegg", "dagg"));
}
This prints:
false
false
true
Stick it in your code like this:
val = 0;
String message = "Invalid";
if(checkCredentials(user, pass)) {
message = "Login";
val = 1;
vf.setVisible(true);
}
JOptionPane.showMessageDialog(null, message);
NOTE:
It would be lot easier if you stored the details on one line this way:
Ahmed Ali|Qazi|Al-Abbass Colony pHase 2|+92032329301|ahmedrider56#gmail.com|ahmedfirst67|dangerd = 2hg
Ahm345|Qa345|Al-asfafs|+92032329301|ahmgsdg|ahmegg|dagg
You could use the String.split method to parse each line and get user and password at the same time.
NOTE 2:
Also it is very bad practice to store password unencrypted. If this is a school exercise it is fine, but if it is for a real life project, you might want to look at encrypting the passwords in the file.

Reading from a text file and Matching user input to certain field columns in the text file. Columns are delimited

I'm creating a menu based console application using Java. I have a class that allows the user to sign up by inputting their information. This information is written to a file that is appended each time a new user is entered.
I would like to have a login function, but I'm having trouble figuring out how to read the file and only match the user input to the first two columns ID;Password.
Once they match the user input, I'll be able to continue to the next menu.
My text file looks like this:
ID;Password;FirstName;LastName;Email
admin;1234;adminFirst;adminLast;adminMail#admin.com
Here's my Login class as well. I created an array for user input, just in case that would be useful:
public class Log_In extends Main_Menu {
public void logging_in(){
Scanner in = new Scanner(System.in);
System.out.println("Please enter your login information!");
String [] log_in_array = new String[2];
String ID, password;
System.out.print("ID: ");
ID = in.next();
System.out.print("Password: ");
password = in.next();
//Stores the ID and PASSWORD to the array. Now we will compare the array to the txt file to find a match
//Must match FIELD_ONE;FIELD_TWO
log_in_array [0] = ID;
log_in_array [1] = password;
in.close();
}
}
you can write helper method to read your text file and compare id and password provided by user, like following.
// The name of the file to open.
static String fileName = "myTextFliel.txt";
public static boolean myHelper(String id, String password) {
// This will reference one line at a time
String line = null;
boolean retVal= false;
try {
// FileReader reads text files in the default encoding.
FileReader fileReader =
new FileReader(fileName);
// Always wrap FileReader in BufferedReader.
BufferedReader bufferedReader =
new BufferedReader(fileReader);
while((line = bufferedReader.readLine()) != null) {
//create a token based on
String [] token=line.split(";");
// because you know first and second word of each line in
// given file is id and password
if (token[0].equals(id) && token[1].equals(password)){
retVal=true;
return retVal;
}
}
// Always close files.
bufferedReader.close();
}
catch(FileNotFoundException ex) {
System.out.println(
"Unable to open file '" +
fileName + "'");
}
catch(IOException ex) {
System.out.println(
"Error reading file '"
+ fileName + "'");
// Or we could just do this:
// ex.printStackTrace();
}
return retVal;
}
public void logging_in(){
Scanner in = new Scanner(System.in);
System.out.println("Please enter your login information!");
String [] log_in_array = new String[2];
String ID, password;
System.out.print("ID: ");
ID = in.next();
System.out.print("Password: ");
password = in.next();
//Stores the ID and PASSWORD to the array. Now we will compare the array to the txt file to find a match
//Must match FIELD_ONE;FIELD_TWO
log_in_array [0] = ID;
log_in_array [1] = password;
// Here you can call your helper method.
boolean foundMe =myHelper(log_in_array [0],log_in_array [1])
if (foundMe==true){
//do whatever u want to do
}
in.close();
}
With little bit of more work you can ignore header line.
If the structure of the file is something like this
username pass data data
username pass data data
username pass data data... and so on
you can read the file into an ArrayList, but skip everything that isn't a user name or pass like so
ArrayList<String> userinfo = new ArrayList();
while (input.hasNext()){ //input is a Scanner object that is your file
userinfo.add(input.next());//username
userinfo.add(input.next());//pass
input.next();//skip
input.next();//skip
}
every username and password will be in pairs like this within the
ArrayList
(username, pass, username, pass, username, pass,...)
Then to see if a username and password matches
int index = userinfo.indexOf(ID);
if (userinfo.get(index+1).equals(password))//the password comes right after the username in the list
return true;
I'm assuming this is for practice, you would typically use a database of some sort for user name and passwords

Create simple login based on txt file

Cannot understand why following code doesn't work properly. Firstly, system getting input from the user. Then system reads all data from .txt file and compare with the user input. But the system never finds similar username and password.
The idea is to create simple login that based on the stored username and password in .txt file. Could someone help?
private static void login() {
String record = null;
FileReader in = null;
try {
in = new FileReader("adminlogin.txt");
BufferedReader br = new BufferedReader(in);
Scanner keyboard = new Scanner(System.in);
System.out.print("Username: ");
String user = keyboard.nextLine();
System.out.print("Password: ");
String pass = keyboard.nextLine();
while ((record = br.readLine()) !=null) {
if (user.equals(record) && pass.equals(record)) {
Mainemenu menu = new Mainemenu();
menu.AdminMenu();
} else {
System.out.println("________----Error----________\n press 'Enter' to continue...");
keyboard.nextLine();
checkInput();
}
}
} catch (IOException e) {
e.getCause();
}
}
Your problem is the loop and its comparison:
while ((record = br.readLine()) !=null) {
if (user.equals(record) && pass.equals(record)) {
//...
}
//...
}
You read a whole line from your file, which is in record, but then you compare both user and pass with this line. This will never work, except user is equal to pass.
Either you have stored the user name and password in a line in your file - then you have to split the line into user name and password - or you have the name and password stored in two separate lines - then you need to reads in the loop for each user.
Moreover, you do throw an error after you checked only the first user and you do not exit the loop, if you actually found the user.
Solutions
I suppose your records in the file are like "username password", then do:
Mainemenu menu = null;
while ((record = br.readLine()) !=null) {
// Split line by a whitespace character
// split[0] <- username
// split[1] <- password
String[] split = record.split("\\s");
if (user.equals(split[0]) && pass.equals(split[1])) {
menu = new Mainemenu();
menu.AdminMenu();
// You found the user, exit the loop
break;
}
// Delete else branch
}
if (menu == null) {
// User not found
}
Of course you can use any other delimiter character or sequence for your records by adopting the delimiter string in split.

Reading input in a predefined order

I want to read input from a text file in the following order
Read in a url into a String variable, Read in all words after that url into an ArrayList variable. The next time I encounter a url, I want to call a method to perform operations on what I read in so far, before setting the new url into the original String variable and so on.
What I have done so far is
public void read() throws IOException {
PerformCheck pc = new PerformCheck();
Scanner sc = new Scanner(new File("input.txt"));
sc.useDelimiter(",");
String url ="";
String res ="";
ArrayList tmp = new ArrayList();
while (sc.hasNext()) {
String s = sc.next().trim();
if (s.contains("http")){
url = s;
}
else {
tmp.add(s);
if (sc.next().contains("http")){ //getting error here
result= pc.perform(url,tmp);
url= "";
tmp= null;
}
}
}
sc.close();
}
The comment in the code - is where I think I am getting error. Basically, I am trying to look ahead to see if the next token is a url, how can I do this right?
my input file looks like this
url, word1,word2,word3 url2, word1,word2,word3
You could save the first time the url and at the second url you check without a lock:
Looks like that:
public void read() throws IOException {
PerformCheck pc = new PerformCheck();
Scanner sc = new Scanner(new File("input.txt"));
sc.useDelimiter(",");
String url = "";
String res = "";
boolean lock = true;
ArrayList<String> tmp = new ArrayList<String>();
while (sc.hasNext()) {
String s = sc.next().trim();
boolean isHttp=s.contains("http");
if (isHttp && lock) {
url = s;
lock=false;
}
else if (isHttp){
result= pc.perform(url,tmp);
url= s;
tmp= new ArrayList<String>();
// Perform check here
// url=s
//tmp=new ArrayList<String>();
}else {
tmp.add(s);
}
}
if (tmp.size()>0){
result=pc.perform(url,tmp);
}
sc.close();
}
The lock is only for the first time where you find a url.
The problem is that there is no "looking ahead" in a scanner. Once you use next() it actually attempts to read the next item. And if it hit the end of the file by then, then there won't be a next item, and you'll get an error.
That's why one must always check hasNext(), and always perform just one next() per hasNext() (no matter if it's next(), nextInt(), nextDouble() or whatever).
The usual way to deal with such requirements is keep whatever you have read so far, and look at the current item that you have read. If it's a URL, you know you should use whatever you collected so far. In pseudo-code:
put null in url
put null in list
open the scanner
while there is a next item in the scanner
set temp to the next item
if temp is a URL
if url has a value
process url and list
end if
put temp in url
create an empty list
else
add temp to list
end if
end while
process the url and list
The part that says "if url has a value" means that this is not the first URL that we are reading. That is, url != null.
So when you encounter a URL, there are things you do only if there is a previous URL (process the previous data), and there are things you always do (assign the new URL, prepare a new list. If you don't prepare a new list you'll also get an error!).
And if you don't encounter a URL, you know that you already have a prepared list, and you add the item to it.
This way, there is no looking ahead - only looking back.
But it means that after the loop you have a URL and a list that were not processed yet, so that's why you need to perform the "process" operation again.
public void read() throws IOException {
PerformCheck pc = new PerformCheck();
Scanner sc = new Scanner(new File("input.txt"));
sc.useDelimiter(",");
String url ="";
String res ="";
boolean firstURLFound = false;
List<String> tmp = new ArrayList<String>();
while (sc.hasNext()) {
String s = sc.next().trim();
if (firstURLFound && s.contains("http")){
result= pc.perform(url,tmp);
url= "";
tmp= new ArrayList<String>();
firstURLFound = false;
}
if (s.contains("http")){
firstURLFound =true;
url = s;
}
else {
tmp.add(s);
}
}
sc.close();
}

Categories