Problems writing to and reading from a file - java

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.

Related

How can I get my code to recognize when another a file has been changed as it is running?

I have a method in one file, XFunction.java, that rewrites another class in another file, NDrive.java, then calls the rewritten method from the NDrive class. The problem is, when the method is called, my code still seems to think the method is what it was before it was rewritten. In fact, even if ndrive.delete() returns true and ndrive.exists() returns false, my code STILL reads the old method (and the file NDrive.java is still there). Does my approach not make any sense? Is it fundamentally flawed, or can I fix it?
Here's the method below.
private double evaluate(String exp) {
File ndrive = new File("NDrive.java");
PrintWriter write = null;
Scanner scan = null;
try {
scan = new Scanner(ndrive);
} catch (FileNotFoundException fnfe) {
System.out.println("File not found");
}
int lineCount = 0;
String contents = "";
if (scan != null) {
while (scan.hasNextLine()) {
String line = scan.nextLine();
lineCount++;
if (lineCount == 9) {
contents += " double y = " + exp + ";\n";
} else {
contents += line + "\n";
}
}
try {
write = new PrintWriter(ndrive);
} catch (FileNotFoundException fnfe) {
System.out.println("File not found for writer");
}
write.print(contents);
System.out.print(contents);
write.close();
scan.close();
}
return NDrive.returnY();
}
The line NDrive.returnY() should return a different output since the body (contents) of that method in Ndrive.java was changed. But it doesn't. Unless the body of returnY() is "changed" to what it already is (is unchanged) which happens after I run the program again without changing the input exp, because the file NDrive.java already contains the new line.
Can anyone help? I've been looking at this for a really, really long time.

Unable to Read a Text File via BufferedReader

I am unable to read a text file via a BufferedReader Object. However I can successfully write to the same text file via a BufferedWriter Object.
The intent of my program is to read a text file called queryCountFile.txt which will then able to figure out how many Query Objects (my custom object) have been previously created. From there, I will then be able to create as many Query Objects as a want while being able to keep track of the number of said Queries.
The function that tries (and fails) to read from the text file is called findNumberOfQueries(). It is located in my file called Query.java
Can anyone understand why I am unable to read from the text file?
QuickControllerApplication.java
#SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
public class QuickControllerApplication {
public static void main(String[] args) {
SpringApplication.run(QuickControllerApplication.class, args);
//everthing below this line is for testing purposes
Query littleQuery = new Query(101L);
//littleQuery.testPrint();
littleQuery.generateQueryID();
System.out.println(littleQuery.findNumberOfQueries());
}
}
Query.java
/**************************************************************
* queryIDNumber - a long that holds the individual data of an
* individual query. Each query will have a unique number
* associated with it.
**************************************************************/
public class Query {
final Long MIN_ID_NUMBER = 1L; //minimum ID Number that can be ever generated by the program
final String QUERY_COUNT_FILE = "queryCountFile.txt"; //this file will simply hold a number that states how many queries have been created
final int SKIP_NUM_LINES_IN_FILE = 2; //the first X number of lines that will skipped in QUERY_COUNT_FILE
//final Long MAX_ID_NUMBER = 9223372036854775807L; //maximum ID Number that can be ever generated by the program
private Long queryID; //each query must have a unique ID Number which will go in the URL when the user is viewing the result of the query search.
private static Long totalQueryIDs = 0L; //holds the value of how many queries have been created over the life of the program
public Query(Long previouslyGeneratedIDNumber)
{
generateQueryID();
//totalQueryIDs++;
//OTHER FUNCTION CALLS
//WILL PROBABLY GO
//HERE LATER...
}
/**************************************************************
* generateQueryID - Generate a ID Number for a query. ID
* Number must be unique, and then is assigned to queryID
**************************************************************/
public void generateQueryID(){
Long generatedNumber;
//Finds the totalQueryIDs stored in QUERY_COUNT_FILE
generatedNumber = findNumberOfQueries();
if (generatedNumber <= MIN_ID_NUMBER){
totalQueryIDs = MIN_ID_NUMBER;
}
else {
totalQueryIDs = generatedNumber + 1L;
}
queryID = totalQueryIDs;
}
/**************************************************************
* findNumberOfQueries - This function finds out how many
* queries have been generated so far. This function will check
* a text file that will contain the past number of queries
* that have been generated.
**************************************************************/
public Long findNumberOfQueries(){
//Check a file. If queryCountFile.txt is not found then numberOfQueries is considered 0 and becomes 1?
try {
Date date = new Date();
//Assume default encoding.
FileWriter fileWriter = new FileWriter(QUERY_COUNT_FILE);
FileReader fileReader = new FileReader(QUERY_COUNT_FILE);
//Always wrap FileWriter in BufferedWriter.
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
//Always wrap FileReader in BufferedReader.
BufferedReader bufferedReader = new BufferedReader(fileReader);
bufferedWriter.write("FILE LAST WRITTEN TO ON: " + date + "\n");
bufferedWriter.write("totalQueryIDs:\n");
bufferedWriter.write("5");
//reading from QUERY_COUNT_FILE
try{
System.out.println("got here\n"); //debug statement
String line; //temp var
//skip first SKIP_NUM_LINES_IN_FILE lines in QUERY_COUNT_FILE
for (int count = 0; count < SKIP_NUM_LINES_IN_FILE; count++) {
bufferedReader.readLine();
}
line = bufferedReader.readLine();
while (line != null) {
System.out.println("stuff bufferedReader got: " + line);
}
}
catch(IOException ex) {
System.out.println("Error reading to file '" + QUERY_COUNT_FILE + "'");
}
//Close the file.
bufferedWriter.close();
bufferedReader.close();
}
catch(IOException ex) {
System.out.println("Error writing to file '" + QUERY_COUNT_FILE + "'");
}
return totalQueryIDs;
}
}
Let me suggest you another way of reading your lines using most recent APIs method which make it easier to read and maintain (at least in my opinion) :
try(final Stream<String> fileStream = Files.lines(Paths.get("queryCountFile.txt")){
fileStream.skip(SKIP_NUM_LINES_IN_FILE)
.forEach(line -> processMyLine(line));
}
For completeness, the problem in your example is that you never re-assign line variable in your loop :
while(line != null)
should be :
while((line = bufferedReader.readLine()) != null)

How do I make my java code search only for a to z and 0 to 9

My java code takes almost 10-15minutes to run (Input file is 7200+ lines long list of query). How do I make it run in short time to get same results?
How do I make my code to search only for aA to zZ and 0 to 9??
If I don't do #2, some characters in my output are shown as "?". How do I solve this issue?
// no parameters are used in the main method
public static void main(String[] args) {
// assumes a text file named test.txt in a folder under the C:\file\test.txt
Scanner s = null;
BufferedWriter out = null;
try {
// create a scanner to read from the text file test.txt
FileInputStream fstream = new FileInputStream("C:\\user\\query.txt");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
// Write to the file
out = new BufferedWriter(new FileWriter("C:\\user\\outputquery.txt"));
// keep getting the next String from the text, separated by white space
// and print each token in a line in the output file
//while (s.hasNext()) {
// String token = s.next();
// System.out.println(token);
// out.write(token + "\r\n");
//}
String strLine="";
String str="";
while ((strLine = br.readLine()) != null) {
str+=strLine;
}
String st=str.replaceAll(" ", "");
char[]third =st.toCharArray();
System.out.println("Character Total");
for(int counter =0;counter<third.length;counter++){
//String ch= "a";
char ch= third[counter];
int count=0;
for ( int i=0; i<third.length; i++){
// if (ch=="a")
if (ch==third[i])
count++;
}
boolean flag=false;
for(int j=counter-1;j>=0;j--){
//if(ch=="b")
if(ch==third[j])
flag=true;
}
if(!flag){
System.out.println(ch+" "+count);
out.write(ch+" "+count);
}
}
// close the output file
out.close();
} catch (IOException e) {
// print any error messages
System.out.println(e.getMessage());
}
// optional to close the scanner here, the close can occur at the end of the code
finally {
if (s != null) {
// close the input file
s.close();
}
}
}
For something like this I would NOT recommend java though it entirely possible it is much easier with GAWK or something similar. GAWK also has java like syntax so its easy to pick up. You should check it out.
SO isn't really the place to ask such a broad how-do-I-do-this-question but I will refer you to the following page on regular expression and text match in Java. Also, check out the Javadocs for regexes.
If you follow that link you should get what you want, else you could post a more specific question back on SO.

Reading a customers name in a txt file with File Reader

My problem is that I can't figure out how to read the customers name with File Reader.
I am making a reservation system and I need to know of the customer already exist. That's why I have to read my Customers.txt file so I can check if someone is already a customer. If he is not I will make a new one with File writer(I Already have the code).
The meaning of this reservation system is to make reservations with a barber. I have to put the reservations in another txt file called Reservations.txt , and in that file you can see each reservation time and who made the reservation.
Thanks for the help!
This is the code I already have:
(some comments are in Dutch but I will translate them )
package nielbutaye;
import java.io.*;
import java.util.UUID;
/**
* #author Niel
*
*/
public class Klant {
//declaration that represents the text
public static String S;
public static String NEWLINE = System.getProperty("line.separator");
/**
* constructor
*/
public Klant(){}
/**
* #return
* By giving the name of the customer you will get all the data from the customer
*/
public double getCustomer() {
return 0 ;
}
/**
* Make a new customer
*/
public void setNew customer(){
// make a newSimpleInOutDialog
SimpleInOutDialog input = new SimpleInOutDialog("A new customer");
//input
S = "Name customer: " + input.readString("Give in your name:");
WriteToFile();
S = "Adress: " + input.readString("Give your adress");
WriteToFile();
S = "Telephonenummber: " + input.readString("Give your telephonenumber");
WriteToFile();
//making a customerID
UUID idCustomer = UUID.randomUUID();
S = "CustomerID: " + customerID.toString();
WriteToFile();
}
public void WriteToFile(){
try{
FileWriter writer = new FileWriter("L:\\Documents/Informatica/6de jaar/GIP/Customer.txt", true);
BufferedWriter out = new BufferedWriter(writer);
//Wrting away your data
out.write(S + NEWLINE);
//Closing the writer
out.close();
}catch (Exception e){//Catch when there are errors
System.err.println("Error: " + e.getMessage());
}
}
}
A BufferedReader() has a method named readLine(), which you can use to read a line from a file:
BufferedReader br = new BufferedReader(new FileReader("Customers.txt"));
String line;
while ((line = br.readLine()) != null)
{
...
}
br.close();
From your WriteToFile() method it seems a customer's details occupies four lines, with the name of the customer appearing on the first line. When searching for a customer, arrange the while loop to only examine every fourth line read.
Other points:
There appears to be no reason for S to be a member variable, nevermind a static. Just declare a local String instance in setNewCustomer() and pass it as an argument to WriteToFile().
Instead of defining a NEWLINE variable you can use BufferedWriter's newLine() method.

Java How To Read A Specific Line

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

Categories