Java How To Read A Specific Line - java

I want help myself, I made a file that would create a user file, because I plan on making a game. It has a login that writes the Login name, the Display name, and the Password. It writes it out to a file named after the Login Name.
Now I wish to make a login script as well, using java. I want to know, specifically, how to read the line and the already entered password.
I have it so that when it creates the file, it saves the password twice, once as "playerPass" and once as "currPass" so that, if one planned to change the password (which I will use from the login script), then the currPass would be read as the correct password using the playerPass variable. Anyway, I would like for it to use BufferedReader and FileReader to read the line indicating the password and the current password so that one may log in.
Can someone help me out a lot with this? I am still, to a point, novice.
PS. I can tweak code, I just need a little explanation on HOW TO code it lol.
Variables:
playerLogName
playerName
playerPass
currPass
File names:
Login.java
CharacterFileCreator.java
MADE AN ADDITION, got it half working, but it locks up (using Dr. Java) after I enter password, regardless of what I do, incorrect or correct, and the System.out.println() never executes, even if the password is incorrect. Check it:
import java.util.Scanner;
import java.io.BufferedWriter;
import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.FileReader;
import java.io.IOException;
import java.io.FileNotFoundException;
class Login {
public static void LogIn(){
boolean loggedIn = false;
loggedIn = true;
System.out.println("You are now logged in!");
}
public static void main(String[] args) {
System.out.println("What is your login name?");
Scanner charLogName = new Scanner(System.in);
String playerLogName = charLogName.nextLine();
boolean charFileFound = false;
BufferedReader characterfile = null;
try {
characterfile = new BufferedReader(new FileReader("./game/characters/" + playerLogName + ".txt"));
charFileFound = true;
}
catch (FileNotFoundException fileex1) {}
if(charFileFound == false){
System.out.println("Login name does not exist!");
}
else
{
System.out.println(playerLogName + ": is your username, what is your password?");
Scanner charPassword = new Scanner(System.in);
String playerPass = charPassword.nextLine();
String line = "";
String token = "";
String token2 = "";
int ReadMode = 0;
try {
line = characterfile.readLine();
} catch (IOException ioexception) {
System.out.println(playerLogName + ": error loading file.");
}
while (line != null) {
line = line.trim();
int spot = line.indexOf("=");
if (spot > -1) {
token = line.substring(0, spot);
token = token.trim();
token2 = line.substring(spot + 1);
token2 = token2.trim();
switch (ReadMode) {
case 1:
if (token.equals("character-password")) {
if (playerPass.equals(token2)) {
LogIn();
} else {
System.out.println("You entered an incorrect password!");
}
break;
}
}
} else {
if(line.equals("[ACCOUNT]")) {
ReadMode = 1;
}
else if(line.equals("[EOF]")) {
try {
characterfile.close();
} catch (IOException ioexception) {
}
}
}
}
}
}
}
EDIT:
SAMPLE FILE:
[ACCOUNT]
character-loginname = SampleFile
character-password = samplepassword
[EOF]

It would probably be easier to use a properties file! You can still give it any file extension you want and even encrypt it if you so wish, but by using the Properties object you can get or set any property regardless of the line number!
Look here for an example: http://www.exampledepot.com/egs/java.util/Props.html
UPDATE: I have spotted your problem - you are never reading the next line of the file in your while loop, so you would probably find that if you put System.out.println(line); somewhere inside of the loop it would just keep displaying "[ACCOUNT]" - the first line of your file!
To solve this problem, I may be inclined to put the entire loop in a try catch statement and change the condition to while((line = characterfile.readLine()) != null). That way, every loop uses the next line, but it could be problematic in terms of catching exceptions, depending on the situation.
Alternatively, you could add line = characterfile.readLine(); after you set ReadMode to 1 in your if(line.equals("[ACCOUNT]")) statement, and as an else statement when testing if (token.equals("character-password"))....
However, if you do follow my advice and use the Properties file you will not be required to do any looping to get the character data as you can just call something like password = propertyObject.getyProperty("password") as the example link shows.
HTH

Related

How to pull information from a text document then print it out

I would like to ask how I can pull information from a txt document ( my txt document contains like
Baggins, Bilbo, < bilbobaggins#bagend.com >, Y
Baggins, Frodo, < frodobaggins#bagend.com >, N
I have tried some stuff. I would also like to know how to store each part in a variable so i can edit them in a string builder/ use.trim to get rid of white spaces.
This is what i tried:
import java.io.FileNotFoundException;
import java.lang.SecurityException;
import java.util.Formatter;
import java.util.FormatterClosedException;
import java.util.NoSuchElementException;
import java.util.Scanner;
/**
*
*
*/
public class pullingEmails {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
// open contacts.txt, output data to the file then close contacts.txt
try (Formatter output = new Formatter("contacts.txt")) {
while (input.hasNext()) { // loop until end-of-file indicator
try {
// output new record to file; assumes valid input
output.format("%s %s %s %s", input.next(),
input.next(), input.next(), input.next());
}
catch (NoSuchElementException elementException) {
System.err.println("No email address: " );
input.nextLine(); // discard input so user can try again
}
}
}
catch (SecurityException | FileNotFoundException |
FormatterClosedException e) {
e.printStackTrace();
System.exit(1); // terminate the program
}
}
}
I am not the best at Java and this is a new concept. I basically need it to print out what is in the file
Gamgee, Samwise, donleaveimsamwise#theShire.com,Y
// every email has < > around them I will remove once i know how to pull the information correctly)
Baggins,Drogo,drogobagginstheshire.com,N
Erling,,erling#theshire.com,Y
Fortinbrass, Took,,Y
example of if statement for exception (not 100 percent sure how to format this):
if No email address
system.err.println("No email address: Chester, Steve,, N");
if (!email.contains("#"))
system.err.println("Invalid email address: "<simon#gmail.com>". Missing # symbol.");
if invalid character //(only capital, lowercase, and # symbol aloud)
system.err.println ("Invalid character '%' at position 4 in last name: "Robe%tson")
My current output does not work. I tried to follow an example i had but that one was asking for information to put in the file at first. not sure how to read what is in a file already, print it out then be able to store each part in a variables like firstName, lastName, Email, Sub etc.
See this question for how to read files in Java.
As each line seems to consist of comma separated values, you can just use split to get the individual values as array. Using streams (or alternatively a for-each loop) you can clean those values, e.g. using strip to remove whitespaces and replaceAll to remove the brackets.
For converting the array back into a line, you could use join. You can collect the lines using a String or better a StringBuilder.
Here is an example:
StringBuilder sb = new StringBuilder();
try {
Files.lines(Path.of("test.txt")).forEach(x -> {
String[] split = x.split(",");
split = stream(split).map(y -> {
String cleaned = y.strip().replaceAll(">$|^<", "").strip();
return cleaned;
}).toArray(String[]::new);
String email = split[2];
// TODO: other data
if (email.isBlank()) {
System.err.println("No email address");
}
// TODO: other checks
sb.append(String.join(", ", split));
sb.append(System.lineSeparator());
});
} catch (IOException e) {
e.printStackTrace();
}
String result = sb.toString();

Java split ignoring white space [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
so, let's say that i have this code
String some = ("my name|username|password");
String[] split = some.split("|");
i want to have a string like this
split[0] = "my name";
split[1] = "username";
split[0] = "password";
here is my code
String record = null;
FileReader in = null;
MainMenu menu = null;
public void checkLogin() throws FileNotFoundException, IOException, ArrayIndexOutOfBoundsException {
in = new FileReader("D:\\Login.txt");
BufferedReader br = new BufferedReader(in);
String username = txfUsername.getText();
String password = new String(txfPassword.getPassword());
while ((record = br.readLine()) != null) {
String[] split = record.split("-");
if (username.equals(split[1]) && password.equals(split[2])) {
JFrame frame = new JFrame();
menu = new MainMenu(split[0]);
this.setVisible(false);
menu.setVisible(true);
break;
}
}
if (menu == null) {
JOptionPane.showMessageDialog(null, "Username or Password wrong.");
}
}
and here is login.txt
my name-user-pass
when i run the program it will throw arrayindexoutofbound exception
how to get rid of that?
In my opinion, when dealing with a text file you want to always make sure you are actually processing a data line especially if your app is not responsible for creating the text file. You should also always be aware of the fact that the data line may not contain all the required data so as to eliminate the possibility of encountering a ArrayIndexOutOfBoundsException when utilizing the String.split() method.
You may also want to allow for a mechanism to handle comment lines within the text file so that some can be added. These lines would of course be ignored as would blank lines. In this case the text file path and file name is hard coded within the method but if the file was to be User selectable via a JFileChooser (or whatever) it would be good if the very first line of the file was a comment line indicating what the file is for, for example:
;MyAppName Login Data
;Real Name, Login Name, Password
John Doe, johnnyboy, cGFzczEyMzQ
Bill Smith, BoperBill, U3VwZXJDb29sMQ
Tracey Johnson, tracey, NzcyMzQ2Ng
Fred Flinstone, PebblesDaddy, V2lsbWEnc19EdWRl
In the example file layout above, lines that start with a semi-colon (;) are considered comment lines. The very first comment is the File Descriptor. When the file is read then this line is checked and if it states what is expected then you know for a fact that it is most likely a correct text file to process otherwise the User supplied or selected a wrong text file.
You will notice that the passwords are encrypted. Not even you should know what they are. Passwords are private to the User only. A simple Base64 Encryption is used here (Java 8+ required) but only for example purposes. It may be good enough for a some applications but definitely not for all, but still, something is better than nothing at all.
To encrypt a password in Base64 in your case you might use (import java.util.Base64 required):
String password = Base64.getEncoder().withoutPadding().
encodeToString(String.valueOf(txfPassword.
getPassword()).getBytes());
Do this before saving the User Password to file.
Here is how your checkLogin() method might look:
public void checkLogin() throws FileNotFoundException, IOException {
// Try with Resources...This will auto-close the BufferReader.
try (BufferedReader br = new BufferedReader(new FileReader("D:\\Login.txt"))) {
// Install code here to validate that txfUsername and txfPassword
// text boxes actually contain something. Exit method if not.
// ................................
String userName = txfUsername.getText();
// Encrypt supplied password and compare to what is in file
String password = Base64.getEncoder().withoutPadding().encodeToString(String.valueOf(txfPassword.getPassword()).getBytes());
if (userName.equals("") || password.equals("")) {
return;
}
String line;
int lineCounter = 0;
boolean loginSuccess = false;
while ((line = br.readLine().trim()) != null) {
lineCounter++;
// Is this the right data file?
if (lineCounter == 1 && !line.equals(";MyAppName Login Data")) {
JOptionPane.showMessageDialog(this, "Wrong Text File Supplied!",
"Invalid Data File", JOptionPane.WARNING_MESSAGE);
return;
}
// Skip blank and comment lines...
if (line.equals("") || line.startsWith(";")) { continue; }
// Split the comma/space delimited data line (", ")
String[] lineSplit = line.split(",\\s+"); // \\s+ means 1 or more spaces
// make sure we have three array elements
if (lineSplit.length == 3 && userName.equals(lineSplit[1]) && password.equals(lineSplit[2])) {
loginSuccess = true;
JFrame frame = new JFrame();
menu = new MainMenu(lineSplit[0]);
this.setVisible(false);
menu.setVisible(true);
break;
}
}
// Can't find login name or password in file.
if (!loginSuccess) {
JOptionPane.showMessageDialog(this, "Invalid User Name or Password!",
"Invalid Login", JOptionPane.WARNING_MESSAGE);
}
}
}

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.

Problems writing to and reading from a file

I am new to programming (Sorry if I ask an easy question) and I have a problem with my program dealing with writing to and reading from a file. To start off I ask the user what they want their username and password to be. Then to simply check if what I was doing was correct, I tried to read the file and then print out the same information. Here is my code:
public void createAccount()
{
try
{
FileWriter doc = new FileWriter("Username.ctxt", true);
System.out.print("Enter your desired Username: ");
myUsername = keyboard.next();
System.out.println();
System.out.print("Enter your desired Password: ");
myPassword = keyboard.next();
System.out.println();
String doc2 = myUsername + " " + myPassword + "\n";
doc.write(doc2, 0, doc2.length());
doc.close();
}
catch(IOException e)
{
System.out.println("Error: " + e.getMessage());
}
retrieveAccount();
}
public void retrieveAccount()
{
try
{
BufferedReader reader = new BufferedReader(new FileReader("Username.ctxt"));//
String user = new String("");//username
String pass = new String("");//password
int stop;
String line = null;
System.out.print("Enter your username: ");//allows computer to search through file and find username
username = keyboard.next();
while ((line = reader.readLine()) != null)
{
scan = reader.readLine();
stop = scan.indexOf(" ");
user = scan.substring(0, stop);
System.out.println(user);
pass = scan.substring(stop + 1);
System.out.println(pass);
if(user.equals(myUsername))
{
System.out.println("Your password is: " + pass);
break;
}
}
}
catch(IOException a)
{
System.out.println("Error: " + a.getMessage());
}
}
So what I want to happen is:
Enter desired username: jake101
Enter desired password: coolKid
Enter your username: jake101
your password is: coolKid
But what actually happens is, is and out of bounds exception(-1)
This is happening because when I use indexOf(" "); it searches for a space. And when it returns negative 1 it means there is no space. What i believe is happening is that i am not writing to the same document i am trying to read from. If anybody can help me figure out what i am doing wrong this would help!
You're double readling the contents of the file...
You first read a line from the file using...
while ((line = reader.readLine()) != null) {
The, straight after that, you read another line using...
String scan = reader.readLine();
Get rid of the second line read...
The issue is that you are calling readline twice in same loop
while ((line = reader.readLine()) != null)
{
scan = reader.readLine();
Change the above to following and it will work
while ((line = reader.readLine()) != null)
{
String scan = line;
The problem seems to be in your retrieveAccount() method, try closing ur reader object. U have opened the file in retrieveAccount() and never closed (so its stil under locked state for other applns/mthds/threads to access).
Try adding reader.close() before end of try block
I would suggest you to create seperate methods for createAccount,retrieveAccount,writeToFile and readToFile. A method should always be responsible to handle single modules. Is the actual responsibillity of createAccount method to read from a file? I would totally say no. Firstly, because low coupling - high cohesion principles are not followed and secondly, because reusabillity does not exist in this way. There are other issues that occur with your currect approach but since you are still in the beginning is expected.
I will provide you with some parts of the things you could do, however, there will be some parts that you should work on your own, like creating the User Class ( it shouldn't be difficult and it will help you learn)
So let's see.
public void createAccount(User user, ListInterface<User> userList)
throws AuthenticationException {
if (!userList.exists(user)) {
userList.append(user);
} else {
throw new AuthenticationException(
"You cannot add this user. User already exists!");
}
}
public boolean authenticate(User user, ListInterface<User> userList)
throws AuthenticationException {
for (int i = 1; i <= userList.size(); i++) {
if (user.equals(userList.get(i))
&& user.getPassword().equals(
userList.get(i).getPassword())) {
return true;
}
}
return false;
}
public void readFromFile(String fileName, ListInterface<User> userList) {
String oneLine, oneLine2;
User user;
try {
/*
* Create a FileWriter object that handles the low-level details of
* reading
*/
FileReader theFile = new FileReader(fileName);
/*
* Create a BufferedReader object to wrap around the FileWriter
* object
*/
/* This allows the use of high-level methods like readline */
BufferedReader fileIn = new BufferedReader(theFile);
/* Read the first line of the file */
oneLine = fileIn.readLine();
/*
* Read the rest of the lines of the file and output them on the
* screen
*/
while (oneLine != null) /* A null string indicates the end of file */
{
oneLine2 = fileIn.readLine();
user = new User(oneLine, oneLine2);
oneLine = fileIn.readLine();
userList.append(user);
}
/* Close the file so that it is no longer accessible to the program */
fileIn.close();
}
/*
* Handle the exception thrown by the FileReader constructor if file is
* not found
*/
catch (FileNotFoundException e) {
System.out.println("Unable to locate the file: " + fileName);
}
/* Handle the exception thrown by the FileReader methods */
catch (IOException e) {
System.out.println("There was a problem reading the file: "
+ fileName);
}
} /* End of method readFromFile */
public void writeToFile(String fileName, ListInterface<User> userList) {
try {
/*
* Create a FileWriter object that handles the low-level details of
* writing
*/
FileWriter theFile = new FileWriter(fileName);
/* Create a PrintWriter object to wrap around the FileWriter object */
/* This allows the use of high-level methods like println */
PrintWriter fileOut = new PrintWriter(theFile);
/* Print some lines to the file using the println method */
for (int i = 1; i <= userList.size(); i++) {
fileOut.println(userList.get(i).getUsername());
fileOut.println(userList.get(i).getPassword());
}
/* Close the file so that it is no longer accessible to the program */
fileOut.close();
}
/* Handle the exception thrown by the FileWriter methods */
catch (IOException e) {
System.out.println("Problem writing to the file");
}
} /* End of method writeToFile */
Useful Information:
The userList is a dynamic linked list that uses generics (ListInterface<User>)
if you dont want to use generics you could just say ListInterface userList, whereever it appears.
Your User class should implement the comparable and include the methods stated below:
public int compareTo(User user) {
}
public boolean equals(Object user) {
}
Always try to create "plug-an-play" methods(not hardcoded), that's the reason I pass as a parameter the userList.
Note that, in case that you dont use generics, typecast might be needed. Otherwise, you will get compilation errors.
If you have any questions let me know.

problem in reading text file

I have a text file where i have names and passwords separated by :.
user1:pwd1
user2:pwd2
In the login page if the user gives the correct username and password it will lead you to the welcome page. But I am not getting this properly. The output which i get is
user1
pwd1
inside try
user1
pwd1
true
welcome user1
user2
pwd2
false
not equal
My code is below.
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.util.regex.*;
import com.sun.org.apache.xalan.internal.xsltc.compiler.Pattern;
public class TextFile {
/**
* #param args
*/
public void getNamePwd(String name, String pwd) {
// TODO Auto-generated method stub
System.out.println(name);
System.out.println(pwd);
String[] splitVals=null;
try{
System.out.println("inside try");
String strLine;
BufferedReader br = new BufferedReader(new FileReader("D:\\test\\text.txt"));
while((strLine=br.readLine())!=null){
splitVals=strLine.split(":");
for(int i=0;i<splitVals.length;i=i+2){
System.out.println(splitVals[i].toString());
System.out.println(splitVals[i].toString());
String nameUser=splitVals[i].toString();
String passWord=splitVals[i+1].toString();
System.out.println(name.equals(nameUser));
if((name.equals(nameUser))&&(pwd.equals(passWord))){
System.out.println("welcome"+name);
}
else{
System.out.println("not equal");
}
}
}
}catch(Exception e){
}
}
}
please help me..
I suspect that you want to stop looking for username/password matches after you've found one... To do this you have to break the loop upon a match. To do this you do the following:
readLoop:
while((strLine=br.readLine())!=null){
// ...
String[] splitVals = strLine.split(":");
if((name.equals(nameUser))&&(pwd.equals(passWord))){
System.out.println("welcome"+name);
break readLoop;
}
// ...
}
Besides, I don't know why you need this loop:
for(int i=0;i<splitVals.length;i=i+2)
Recall that you read the file line by line. That is, the splitted array will contain the username and password of the current line.
To print the username / password you could do something like this:
System.out.printf("Username: %s, Password: %s%n", splitVals[0], splitVals[1]);
I would probably solve it using a Scanner. Something like this:
import java.io.*;
import java.util.Scanner;
public class TextFile {
public static void main(String[] args) throws FileNotFoundException {
if (userPassOk("hello", "world"))
System.out.println("Welcome");
else
System.out.println("Get out!");
}
private static boolean userPassOk(String user, String pass)
throws FileNotFoundException {
Scanner s = new Scanner(new File("test.txt"));
while (s.hasNextLine()) {
String[] userPass = s.nextLine().split(":");
if (userPass[0].equals(user) && userPass[1].equals(pass))
return true;
}
return false;
}
}
Try resetting the value of nameUser and passWord at the end of the try()
as in
nameUser="";
passWord="";
Your print statements are wrong. That's why you can't debug this properly.
What you are printing does not match what you are using for the name and password. Fix this and try printing it out again.
for(int i=0;i<splitVals.length;i=i+2){
System.out.println(splitVals[i].toString());
System.out.println(splitVals[i].toString());
String nameUser=splitVals[i].toString();
String passWord=splitVals[i+1].toString();
However, you don't need this loop. You can just use:
String nameUser=splitVals[0];
String passWord=splitVals[1];
put break if your condition is satisfied.Don't allowed continue the loop.If you put the brak here.you got your expected output.
if((name.equals(nameUser))&&(pwd.equals(passWord))){
System.out.println("welcome"+name);
break;
}

Categories