I'm making a user system in Java using text files and i'm trying to make it so that the same username can't register twice. It completely ignores it and allows for the creation anyway.
The code I have below is:
static boolean checkUsername(String u) { //Check the username and password
boolean userFound = false;
try { //Try and read our user file
Scanner loginRead = new Scanner(loginFile); //Load the file into the scanner
loginRead.useDelimiter("|"); //Split each set of user data into an array with |
try {
if(loginRead.nextLine() ==null) {
return false;
} else {
while(loginRead.nextLine() !=null){ //Run line by line until we find this MF
String user_r = loginRead.next(); //loginRead[0] = Username
loginRead.next(); //Read the line
if(u.equals(user_r)){ //If we have a match
userFound=true;
break; //Break the login script because we've struck gold
}
}
}
} catch(NoSuchElementException e) {
return false;
}
} catch (FileNotFoundException exceptionText) { //We couldn't find the user file.
System.out.println("User file error");
}
return ((userFound==true) ? true : false); //Short hand if statement
//to tell us if we found that user
}
User file:
username|pwhash|fname|lname
username|pwhash|fname|lname
username|pwhash|fname|lname
username|pwhash|fname|lname
Where am I going wrong?
Very, very late. But I re-did the code and here is what I went with, for anyone else wondering:
static boolean checkUsername(String u) throws IOException { //We use this function when registering a user, to make sure they don't already exist
boolean userFound = false; //Our boolean for if the user exists
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("./loginData.dat")); //Load our loginData.dat file into the buffer
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (String line = br.readLine(); line != null; line = br.readLine()) { //Read the file line by line
String[] userDataNew=line.toString().split("\\|"); //Split our line up into an array using |
if(userDataNew[0].equals(u)) { //We've found their username already
userFound = true; //Set our user found bool to true
break; //Break out of the foor loop
}
}
return userFound; //Return true/false
}
Related
I have a users1.txt with some registries like: basketball president tom#gmail.com 1234 and I am making the user to give as input the email,password and two choices of spinner , and I want to search them in the file and compare them , then if its true i will print a message (open() function). In the bellow code the condition was made with success but only for the first line of the file, I want to check all the file for each input of user. To be more specific , I want the search not to stop to basketball president tom#gmail.com 1234 but continues to the second line football referee tam#gmail.com 123123 etc. until the end of file. any suggestion would be great.
signBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if( TextUtils.isEmpty(email.getText()))
email.setError("Email Required");
else if( TextUtils.isEmpty(password.getText()))
password.setError("Password Required");
else {
String text = readFromFile("users1.txt");
String[] splited = text.split("\\s+");
if(SportSpinner.getSelectedItem().toString().equals(splited[0]) && (UserSpinner.getSelectedItem().toString().equals(splited[1])) && (password.getText().toString().equals(splited[3])) && (email.getText().toString().equals(splited[2])))
open(SportSpinner.getSelectedItem().toString(), UserSpinner.getSelectedItem().toString());
else
{
if(tries==1)
open();
signBtn.startAnimation(shakeAnimation);
tries--;
message(tries);
}
}
}
});
}
private String readFromFile(String name){
StringBuilder text = new StringBuilder();
try {
File file = new File(getFilesDir().getAbsolutePath(),name);
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) {
text.append(line);
text.append('\n');
}
br.close();
}catch(IOException e){
Log.e("Exception", "File read failed: " + e.toString());
}
return String.valueOf(text);
}
If the lines for the file are always in sets of the same number, you can use a loop to increment the indices that you check. I would also add a flag of some sort to stop searching if you found it.
boolean found = false;
for (int i = 0; i <= splitted.length-3 && !found; i += 4) {
if(SportSpinner.getSelectedItem().toString().equals(splited[i]) && (UserSpinner.getSelectedItem().toString().equals(splited[i+1])) && (password.getText().toString().equals(splited[i+3])) && (email.getText().toString().equals(splited[i+2]))) {
found = true;
// Your open method goes here
}
}
if (!found) {
// Now put all the code from the previous else statement here, since it has now searched the whole list for the one set of inputs
}
This checks every line of the file for a match and drops out of the loop if there is a match.
I just want to say thank you for taking the time to look into my question. I am currently working on an inventory interface. The issue I am having is that when I read an update file, to update my database file, this is what I get: database: abc,123,10.0,5.0,false,10 (partName,partNumber,listPrice,salePrice,onSale,quantity)
after I read in the update file:
abc,123,10.0,5.0,false,10 is first in my db followed by abc,123,20.0,10.0,true,2
how do I fix this so that it updates the string in the db file, instead of appending it to the file?
here is some of my code:
//findBp method
public static BikePart findBp(ArrayList<BikePart> bpal, BikePart bp) {
BikePart found = null;
for(BikePart b : bpal) {
if(b.getPartName().equals(bp.getPartName()) && b.getPartNumber() == bp.getPartNumber()) {
found = b;
break;
}
}
return found;
}
//sort by partName
public static void sortName(ArrayList<BikePart> bpal) {
Collections.sort(bpal, BikePart.bpNameComp);
}
//sort by partNumber
public static void sortNumber(ArrayList<BikePart> bpal) {
Collections.sort(bpal, BikePart.bpPartNumComp);
}
//readFile method
public static void readFile(String fileName, ArrayList<BikePart> bpal) {
if(fileName == null || fileName.equals("")) {
return;
}
File file = new File(fileName);
try {
Scanner read = new Scanner(file);
while(read.hasNextLine()) {
String line = read.nextLine();
String pv[] = line.split(",");
BikePart bp = BikePart.toObject(pv);
BikePart found = findBp(bpal, bp);
if(found == null) {
bpal.add(bp);
} else {
found.setQuantity(found.getQuantity() + bp.getQuantity());
found.setPartName(bp.getPartName());
found.setPartNumber(bp.getPartNumber());
found.setListPrice(bp.getListPrice());
found.setSalesPrice(bp.getSalesPrice());
found.setPartOnSale(bp.isPartOnSale());
}
}
read.close();
}
catch (FileNotFoundException e) {
System.out.println(fileName + " is not found!");
System.out.println("Enter another file name.");
String fileName2 = in.nextLine();
readFile(fileName2, bpal);
}
}
//writeFile method
public static void writeFile(String fileName, ArrayList<BikePart> bpal) {
try {
BufferedWriter outStream = new BufferedWriter(new FileWriter(fileName, true));
for(BikePart bp : bpal) {
outStream.write(bp.toString());
outStream.newLine();
}
outStream.close();
}
catch (IOException e) {
System.out.println("file not found!");
}
}
public static void main(String[] args) {
//calendar field
Calendar cal = Calendar.getInstance();
//ArrayList for DB
ArrayList<BikePart> bpal = new ArrayList<BikePart>();
readFile("DB.txt", bpal);
//user input variable
String usrIn = "";
//loop for user choice
while(usrIn != "Quit") {
//prompts user to select choice
System.out.println("Please select your option from "
+ "the following menu: ");
System.out.println("Read: Read an inventory delivery file");
System.out.println("Enter: Enter a part");
System.out.println("Sell: Sell a part");
System.out.println("Display: Display a part");
System.out.println("SortName: Sort parts by part name");
System.out.println("SortNumber: Sort parts by part number");
System.out.println("Quit: ");
System.out.println("Enter your choice: ");
//initiates usrIn
usrIn = in.nextLine();
//switch for input choice
switch(usrIn) {
case "Read":
//read method
System.out.println("Enter file name: ");
String fileName = in.nextLine();
readFile(fileName, bpal);
break;
case "Enter":
//enter method
break;
case "Sell":
//sell method
break;
case "Display":
//display method
break;
case "SortName":
//sortName method
break;
case "SortNumber":
//sortNum method
break;
case "Quit":
//quit method
writeFile("DB.txt", bpal);
System.out.println("good bye! ");
break;
}
if(usrIn.equals("Quit")) {
break;
}
}
}
I haven't filled in the rest of the code yet, because I want to fix this issue first before I move on. I just want to say thanks again for taking a look.
Because you are appending to the file:
new FileWriter(fileName, true)
That's what the true parameter does.
In order to replace data in your file, you must read it, replace the data and write the new data out.
One way to do this is as illustrated in this answer. Which is briefly outlined below:
// Read all the data
BufferedReader file = new BufferedReader(new FileReader("data.txt"));
String line;
StringBuffer inputBuffer = new StringBuffer();
while ((line = file.readLine()) != null) {
inputBuffer.append(line);
inputBuffer.append('\n');
}
String inputStr = inputBuffer.toString();
file.close();
// Replace your string code goes here.....
// Then write all the updated data back
FileOutputStream fileOut = new FileOutputStream("notes.txt");
fileOut.write(inputStr.getBytes());
fileOut.close();
Regarding the duplication:
It might be a case of how you update your ArrayList. May I suggest that you print the list before writing the file to check that it is not a duplicate entry? If it is then it is not an file-writing issue but a data updating issue. Then you must ensure that you are updating the BikePart in the list instead of adding it again.
Hey I'm working on a Bank account application and i'm working on the login at the moment. I want the Programm to go through the file and check if there is already a username same as the one the user wants, if there is one it should go back and ask for a new username again. I've tried many different ways but i couldn't find one that works. I hope someone can help me. :-)
String file = "C:\\Users\\dsociety\\IdeaProjects\\bankaccount\\logins.txt";
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
BufferedReader on = new BufferedReader(new InputStreamReader(System.in));
String username;
String pw;
Boolean exists = false;
Scanner scanner = null;
try {
scanner = new Scanner(new File(file));
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
System.out.println("Please enter a username");
username = in.readLine();
BufferedReader bru = new BufferedReader(new FileReader(file));
String line;
try {
while (exists == true) {
while ((line = bru.readLine()) != null) {
while (scanner.hasNextLine()) {
String[] userAndPw = scanner.nextLine().split(":");
String user = userAndPw[0];
if (user.equals(username)) {
System.out.println("There is already a User with that username, please try a other username");
exists = false;
}
else {
exists = true;
}
}
}
}
bru.close();
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Please enter a password");
pw = on.readLine();
I looked through your code and, as someone else noticed, you can't enter the first while loop because of the exists variable being false. And I think you messed the order of the whiles a little bit.
You definitely don't need a Scanner and a BufferedReader (one of them is enough) for reading the file, just as how you don't need two different BufferedReaders to read from the system input (again, one is sufficient).
I modified your code a little bit and added some comments and I hope it works for you now:
String file = "C:\\logins.txt";
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String username;
String pw;
System.out.println("Please enter a username");
BufferedReader bru = new BufferedReader(new FileReader(file));
// we will keep the users here instead of reading the file everytime a username is entered
List<String> users = new ArrayList<>();
Boolean exists = null;
String line;
// populate the existing users list by reading all the lines in the file
while ((line = bru.readLine()) != null) {
users.add(line.split(":")[0]);
}
bru.close();
// we can enter the while loop if we are asking for the username for the first time
// or if the username entered already exists
while (exists == null || exists == true) {
// we read the username from the input
username = in.readLine();
// we suppose it doesn't already exist
exists = false;
// we look at every existing user
for (String user : users) {
/*
* if the names are the same, we don't need to look further, we know the username
* exists and so we will break from the "for" loop and ask for a username once again
* (side note: I used replaceAll in order to remove all invisible unicode characters
* that might make two strings unequal that would otherwise be identical)
*/
if (user.replaceAll("\\P{Print}", "").equals(username.replaceAll("\\P{Print}", ""))) {
System.out.println("There is already a User with that username, please try a other username");
exists = true;
break;
}
}
}
System.out.println("Please enter a password");
pw = in.readLine();
It would be better to divide the job in two parts:
Scan through the file for every username. Put username as key in a map.
Ask for input username, and check if the username is present or not.
if (myMap.containsKey(username) == true) {
// ...
} else {
// Go back to step 2
}
I hope this code will help to solve your issue:
private static boolean userExists(String consoleParam){
String filePath = "C:\\Users\\dsociety\\IdeaProjects\\bankaccount\\logins.txt";
File file = null;
FileReader fr = null;
BufferedReader br = null;
Boolean exists = false;
try{
file = new File (filePath);
fr = new FileReader (file);
br = new BufferedReader(fr);
String line;
while((line=br.readLine())!=null){
if(line.split(":")[0].equals(consoleParam)){
exists = true;
break;
}
}
}catch(Exception e){
e.printStackTrace();
}finally{
/* Close opened resources */
try{
if( null != fr ){
fr.close();
}
}catch (Exception e2){
e2.printStackTrace();
}
}
return exists;
}
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
boolean newUser = false;
/* Check if username alredy exists */
while(!newUser){
System.out.println("Please enter a username");
String username = reader.next();
newUser = !userExists(username);
}
/* Close resources */
System.out.println("New username entered!");
reader.close();
}
I'm tinkering around on a small application to read some numbers in from a file. Everything runs well so far, but now I have encountered a problem I don't know how I can effectively fix it. If the user enters, unintentionally maybe, the wrong filename a FileNotFoundException will be thrown by the JVM, that I catch in my invoking method. Now I want to give him (the user) two another tries to enter the correct filename, but I don't know how I can invoke the method again which is opening the file when I'm actually in the catch-block below.
I will illustrate my transient solution below, but I'm not really sure if this is the most effective/elegant way to solve this problem:
//code omitted
int temp = 0;
while(true) {
filename = input.next();
try {
ex.fileOpen(filename);
}
catch(FileNotFoundException e) {
if(temp++ == 3) {
System.err.println("You have entered the filename three times consecutively wrongly");
return;
}
continue;
}
break;
}
//do some other stuff
input is a scanner which reads the user input and assigns it to the String-variable filename. fileOpen is a method which takes a filename, opens the file, reads the content and write all numbers in a vector.
So, I would really appreciate every support from the more experienced java programmers.
Greetings
Tom
You could use something like this,
public class AppMain {
public static void main(String[] args) throws IOException {
String filePath = input.next();
InputStream is = getInputStream(filePath);
int temp = 0;
while(is == null && temp < 3){
filePath = input.next();
is = getInputStream(filePath);
temp++;
}
if(is == null){
System.err.println("You have entered the filename three times consecutively wrongly");
return;
}
.........
.........
}
private static InputStream getInputStream(String filePath){
InputStream is = null;
try{
is = new FileInputStream(filePath);
return is;
}catch (IOException ioException) {
return null;
}
}
}
You may want to recursively call the method again:
public void doTheStuff(int attemptsLeft)
// ...
if (attemptsLeft == 0) {
System.err.println("You have entered the filename three times consecutively wrongly");
return;
}
filename = input.next();
try {
ex.fileOpen(filename);
}
catch(FileNotFoundException e) {
doTheStuff(attemptsLeft - 1);
return;
}
// ...
}
then simply call doTheStuff(3)
You can use exists method of the File class
For example fileOpen method can return true/false whether file exists
Think this will work.
int x = 0;
while (true){
filename = input.next();
try{
ex.fileOpen(filename);
break; // If it throws an exeption, will miss the break
}catch(FileNotFoundException e){
System.err.println("File not found, try again.");
}
if (x==2){
System.errprintln("You have entered the wrong file 3 times");
System.exit(0);
}
x++
}
Do not use exceptions to control your WorkFlow. Try something like this:
final int MAX_ERROR_ALLOWED=3;
public void readFile(String filename, int errorCount){
try{
File f = new File(filename);
if(!f.exists()){
String newFilename = input.next();
if(errorCount>=MAX_ERROR_ALLOWED){
throw new JustMyException();
}
readFile(newFilename, errorCount++);
}else{
//whatever you need to do with your file
}
}
}
How about something like this (pseudocode, not executable)?
// ...
for(int i = 0; i < 3; i++)
{
// User interaction to get the filename
if(attemptToOpenFile(ex))
{
break;
}
}
// Check if the file is open here and handle appropriately.
// ...
}
bool attemptToOpenFile(File ex, String filename) { // Forgot the class name for this
try {
ex.fileOpen(filename);
return true;
} catch(FileNotFoundException e) {
return false;
}
}
Alternatively, check if the file exists before calling fileOpen().
I have an assignment where I need to write a while loop code block that contains a trycatch statement. The try block retrieves each line from an input file, and invokes an isValid method I created to check if the format is correct, passing to it the line from the file. If there are no more lines to parse, runProgram is set to false, the while loop terminates. The catch block will catch an exception that I made. So far I have
public static void main(String[] args)
{
File file;
Scanner inputFile;
String fileName;
Scanner scan = new Scanner(file);
fileName = scan.nextLine();
boolean runProgram = true;
while(runProgram)
{
try
{
// for loop to check each line of my file
// invoke isValid
// Check if it's the last line in the file, and end program if so
}
catch(BankAccountException e)
{
System.out.println("Account Exception. Do you wish to quit? y/n");
String quit = scan.nextLine();
if(quit.equals("y"))
runProgram = false;
else
runProgram = true;
}
}
}
I just have no idea how to open a file, check the next line, use my isValid method (which is just a StringTokenizer that checks for the correct format), and closes when it reaches the end of the file.
Here is my isValid method:
private static boolean isValid(String accountLine) throws BankAccountException
{
StringTokenizer strTok = new StringTokenizer(accountLine, ";");
boolean valid = true;
if(strTok.countTokens() == 2)
{
if(strTok.nextToken().length() == 10)
{
if(!strTok.nextToken().matches(".*[0-9].*"))
{
valid = true;
}
}
}
else
valid = false;
return valid;
}
I also have a question with the above method. If I call .nextToken() twice, am I right in expecting the first iteration to deal with the first token, and the second to deal with the second? Or will they both just check the first token?
Just to get you started.
try {
BufferedReader reader = new BufferedReader(new FileReader(new File("/path/to/File")));
String currLine;
while ((currLine = reader.readLine()) != null) { // returns null at EOF
if (!isValid(currLine)) throw new BankAccountException();
}
} catch (BankAccountException e) {
// same
} finally {
reader.close();
}