I need to be prove about user-input path.
Coz when user give not folder path but file path. Program "fall down".
I understand that this is a bug but how to be ensure about user path correct.
Code:
class PathAndWord {
final String path;
final String whatFind;
PathAndWord(String path, String whatFind) {
this.path = path;
this.whatFind = whatFind;
}
boolean isProperlyInitialized() {
return path != null && whatFind != null;
}
}
public void askUserPathAndWord() {
try {
tryToAskUserPathAndWord();
} catch (IOException | RuntimeException e) {
System.out.println("Wrong input!");
e.printStackTrace();
} catch (InterruptedException e) {
System.out.println("Interrupted.");
e.printStackTrace();
}
}
private void tryToAskUserPathAndWord() throws IOException, InterruptedException {
PathAndWord pathAndWord = readPathAndWord();
if (pathAndWord.isProperlyInitialized()) {
performScan(pathAndWord, "GameOver.tmp");
System.out.println("Thank you!");
} else {
System.out.println("You did not enter anything");
}
}
private PathAndWord readPathAndWord() throws IOException {
System.out.println("Please, enter a Path and Word (which you want to find):");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String path = readPath(bufferedReader);
String whatFind = readWord(bufferedReader);
return new PathAndWord(path, whatFind);
}
private String readPath(BufferedReader bufferedReader) throws IOException {
System.out.println("Please enter a Path:");
return bufferedReader.readLine();
}
private String readWord(BufferedReader bufferedReader) throws IOException {
System.out.println("Please enter a Word:");
return bufferedReader.readLine();
}
private void performScan(PathAndWord pathAndWord, String endOfWorkFileName) throws InterruptedException {
BlockingQueue<File> queue = new LinkedBlockingQueue<File>();
File endOfWorkFile = new File(endOfWorkFileName);
CountDownLatch latch = new CountDownLatch(2);
FolderScan folderScan = new FolderScan(pathAndWord.path, queue, latch,
endOfWorkFile);
FileScan fileScan = new FileScan(pathAndWord.whatFind, queue, latch,
endOfWorkFile);
Executor executor = Executors.newCachedThreadPool();
executor.execute(folderScan);
executor.execute(fileScan);
latch.await();
}
Qustions:
How do check if user input path is correct?
If path isn't correct
to show message that path is wrong! Try again.
Able to check word - whatFind whether it's correct, too.
Does need before point do?
private String readPath(BufferedReader bufferedReader) throws IOException {
boolean ok = false;
do {
System.out.println("Please enter a Path:");
File f = new File(bufferedReader.readLine());
if(f.exists() && f.isDirectory())
ok = true;
else
System.err.println("Doesn't exist or is not a folder.");
} while(!ok);
return f.getAbsolutePath();
}
EDIT: This method does a task "read a path from user, which exists and is a directory". If the user types invalid path (non-existent or a file) the method recognizes this, warns the user and asks them again... and again and again - until they answer correctly.
It's a good custom to check data locally, if you can. When calling the method later you can be sure it returns, what you expect.
Related
I get an error when I try to type a password consisting only alphanumeric characters but loops the way I intended if I type symbols. This is my first time trying to make a program that writes and reads a file and I'm still stuck here. I tried to paste the entire code to a different class but still runs into the same situation. I have no clue what caused this error. The IDE I'm currently using is Eclipse.
The full error is:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 1 out of bounds for length 0
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:266)
at java.base/java.util.Objects.checkIndex(Objects.java:359)
at java.base/java.util.ArrayList.get(ArrayList.java:427)
TaskPerf6.main(TaskPerf6.java:66)
Source:
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Scanner;
public class TaskPerf6 {
public static boolean isAlphaNumeric(String username) {
return username != null && username.matches("^[a-zA-Z0-9]*$");
}
public static boolean isAlphaNumeric1(String password) {
return password != null && password.matches("^[a-zA-Z0-9]*$");
}
public static void main(String[] args) throws IOException {
Scanner scan = new Scanner(System.in);
System.out.println("Type L to log-in or R to register.");
String choice = scan.nextLine();
File file = new File("records.txt");
FileWriter writer = new FileWriter(file);
//Register
if (choice.compareToIgnoreCase("R") == 0) {
System.out.println("Registration:");
while(true) {
try {
System.out.println("Write your username (Alphanumeric Characters Only):");
String username = scan.nextLine();
if (isAlphaNumeric(username)==true) break;
writer.write(username + "\n");
writer.close();
}
catch (java.lang.IndexOutOfBoundsException e) {
System.out.println("a");
}
catch (java.io.IOException e) {
System.out.println("");
}
}
while(true) {
try {
System.out.println("Write your password (Alphanumeric Characters Only):");
String password = scan.nextLine();
if (isAlphaNumeric1(password)==true) break;
writer.write(password + "\n");
writer.close();
}
catch (java.lang.IndexOutOfBoundsException e) {
System.out.println("a");
}
catch (java.io.IOException e) {
System.out.println("");
}
}
String line1 = Files.readAllLines(Paths.get("records.txt")).get(1);
}
}
}
You do not need two of the same methods; delete one of the isAlphaNumeric methods.
public static boolean isAlphaNumeric(String word) {
return word != null && word.matches("^[a-zA-Z0-9]*$");
}
Your problem is here:
String line1 = Files.readAllLines(Paths.get("records.txt")).get(1);
you are attempting to retrieve the second line of this file from the .get(1), when you have not wrote anything to the file.
The reason why you are not writing to a file is because you are using break whenever the username and password matches your regex pattern.
if (isAlphaNumeric(username)==true) break;
writer.write(username + "\n");
writer.close();
which will take you out of the while loop before you can write to the file.
You should practice breaking up your code for reusability. Very helpful: here is my solution for your task.
public class TaskPerf6 {
static String fileName = "records.txt";
static File file = new File(fileName);
static Scanner scan = new Scanner(System.in);
static final String REGISTER = "R";
static final String LOGIN = "L";
public static void main(String[] args){
System.out.println("Type L to log-in or R to register.");
String choice = scan.nextLine();
switch(choice.toUpperCase()) {
case REGISTER:
register();
break;
case LOGIN:
login();
break;
}
String line1 = getLineItem(0);
System.out.println(line1);
}
private static void login() {
// TODO
}
private static void register() {
while(true) {
System.out.println("Write your username (Alphanumeric Characters Only):");
String username = scan.nextLine();
if (processed(username))
break;
}
while(true) {
System.out.println("Write your password (Alphanumeric Characters Only):");
String password = scan.nextLine();
if (processed(password))
break;
}
}
private static boolean processed(String word) {
boolean success = true;
if (isAlphaNumeric(word)) {
if (!writeToFile(word)) {
System.out.println("Was unable to write to file");
success = false;
}
} else {
System.out.println("Was not alphanumeric, try again");
success = false;
}
return success;
}
private static boolean isAlphaNumeric(String word) {
return word != null && word.matches("^[a-zA-Z0-9]*$");
}
private static boolean writeToFile(String word ) {
boolean success = true;
try {
FileWriter writer = new FileWriter(file);
writer.write(word + "\n");
writer.close();
} catch (IndexOutOfBoundsException | IOException e) {
success = false;
}
return success;
}
private static String getLineItem(int i) {
String item = "";
try {
item = Files.readAllLines(Paths.get(fileName)).get(i);
} catch (IOException e) {
e.printStackTrace();
}
return item;
}
}
first change to be done might be not closing writer in the first loop for username but in second loop for password.
while(true) {
try {
System.out.println("Write your username (Alphanumeric Characters Only):");
String username = scan.nextLine();
if (isAlphaNumeric(username)==true){
System.out.println("username correct");
writer.write(username+"\n");
break;}
} catch (java.lang.IndexOutOfBoundsException e) {System.out.println("a");}
catch (java.io.IOException e) {System.out.println("");}
}
while(true) {
try {
System.out.println("Write your password (Alphanumeric Characters Only):");
String password = scan.nextLine();
if (isAlphaNumeric1(password)==true){
System.out.println("pass correct");
writer.write(password);
writer.close();
break;
}
}
catch (java.lang.IndexOutOfBoundsException e) {System.out.println("a");}
catch (java.io.IOException e) {System.out.println("");}
}
When record.txt cannot be found and you try to get index 1 that's why you're getting the index out of bound exception. Please use the following if check:
String line1;
if(!Files.readAllLines(Paths.get("records.txt")).isEmpty())
line1 = Files.readAllLines(Paths.get("records.txt")).get(1);
i have a problem in my java exercise.
i need to print a multiply contact information to a file, but when i print more then 1 contact, only 1 contact is displayed in the file..
i tried to debug that but i cant find any mistake
i will put the code of my classes here:
This is Demo Class which i run the code from
public class Demo {
public static void main(String[] args) {
System.out.println("Insert number of Contacts:");
Scanner scanner = new Scanner(System.in);
int val = scanner.nextInt();
Contact[] contacts = new Contact[val];
for(int i = 0 ; i < val; i++) {
System.out.println("Contact #"+(i+1));
System.out.print("Owner: \n");
String owner = scanner.next();
System.out.print("Phone number: \n");
String phoneNum = scanner.next();
System.out.print("Please Select Group:\n"
+ "1 For FRIENDS,\n" +
"2 For FAMILY,\n" +
"3 For WORK,\n" +
"4 For OTHERS");
int enumNum = scanner.nextInt();
Group group;
switch(enumNum) {
case 1:
group=Group.FRIENDS;
break;
case 2:
group=Group.FAMILY;
break;
case 3:
group=Group.WORK;
break;
default:
group=Group.OTHERS;
}//switch end
contacts[i] = new Contact(owner,phoneNum,group);
}//loop end
System.out.println("Insert File name");
String fileName = scanner.next();
File f=null;
for(int i = 0 ; i < val; i++) {
if(i==0) {
f = new File(fileName);
contacts[0].Save(fileName);
}
else {
contacts[i].Save(f);
}
}
}
}
This is Contact Class:
enum Group {
FRIENDS,
FAMILY,
WORK,
OTHERS
};
public class Contact {
private String phoneNumber,owner;
private Group group;
PrintWriter pw = null;
public Contact(String owner ,String phoneNumber,Group group) {
setPhoneNumber(phoneNumber);
setOwner(owner);
setGroup(group);
}
public Contact(String fileName) {
File file = new File(fileName+".txt");
try {
Scanner scanner = new Scanner(file);
phoneNumber=scanner.nextLine();
owner=scanner.nextLine();
String str=scanner.nextLine();
group = Group.valueOf(str);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
catch(Exception e) {
e.printStackTrace();
}
}
public Contact(File file) {
try {
Scanner scanner = new Scanner(file);
phoneNumber=scanner.nextLine();
owner=scanner.nextLine();
String str=scanner.nextLine();
group = Group.valueOf(str);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
catch(Exception e) {
e.printStackTrace();
}
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
public void Save(String fileName) {
File f = new File(fileName+".txt");
try {
if(f.createNewFile()) {
System.out.println("File created");
pw = new PrintWriter(f); //יצירת מדפסת לקובץ
pw.println(phoneNumber+"\n"+owner+"\n"+group+"\n\n\n");
}
} catch (IOException e) {
e.printStackTrace();
}
pw.close();
}
public void Save(File f) {
PrintWriter pw=null;
try {
pw = new PrintWriter(f);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
pw.println(phoneNumber+"\n"+owner+"\n"+group);
pw.close();
}
public String toString() {
return phoneNumber+"\n"+owner+"\n"+group;
}
}
Every time you create PrintWriter the file is being overwritten. Since you create a new PrintWriter for each contact, the file contains only the last contact information. What you should do is to create PrintWriter only once and use it for all contacts.
Firstly, let's create a new save method with such signature:
public void save(PrintWriter writer)
I have also used the lowercase name of the method due to Java naming convention.
Now the implementation of save method will look like this:
writer.println(phoneNumber);
writer.println(owner);
writer.println(group + "\n\n\n");
Then we should replace the usage of Save method with the new one. Here is your code:
String fileName = scanner.next();
File f = null;
for (int i = 0; i < val; i++) {
if(i == 0) {
f = new File(fileName);
contacts[0].Save(fileName);
} else {
contacts[i].Save(f);
}
}
In order to fix the issue we can change it like this:
String fileName = scanner.next();
File file = new File(fileName);
try (PrintWriter writer = new PrintWriter(file)) {
for (int i = 0; i < val; i++) {
contacts[i].save(writer);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
I have also used try-with-resources which closes the PrintWriter automatically.
From the Javadoc of the constructor of PrintWriter:
public PrintWriter(File file)
Parameters: file - The file to use as the destination of this writer. If the file exists then it will be truncated to zero size; otherwise, a new file will be created. The output will be written to the file and is buffered.
In the Save function you create a PrintWriter everytime. So everytime the file is truncated, and then you lose the contact you saved before.
Since File I/O classes in java use Decorator Design pattern, you can use a FileWriter to take advantage of appending to a file. So you can use this code for Save() method :
public void Save(String fileName) {
File f = new File(fileName+".txt");
try {
//System.out.println("File created"); You don't need to create new file.
FileWriter fw=new FileWriter(f,true):// second argument enables append mode
pw = new PrintWriter(fw); //יצירת מדפסת לקובץ
pw.println(phoneNumber+"\n"+owner+"\n"+group+"\n\n\n");
} catch (IOException e) {
e.printStackTrace();
}
pw.close();
}
I'm trying to compare a string, pass, to a dictionary file list. If it directly matches a word, it is considered weak (balloon). If it contains the word from the dictionary file (#balloon232), it is considered moderate. If neither, its strong. In this code, weak and moderate both work correctly, but when a strong pass is entered, it says it is moderate. Thanks for the help.
public static void passwordStrength(String pass, String file2) {
boolean found2 = false;
boolean found3 = false;
try {
y = new Scanner(new File(file2));
z = new Scanner(new File(file2));
while (y.hasNextLine()) {
if (pass.equals(y.nextLine().trim())) {
System.out.println("\nYour password is weak");
found2 = true;
break;
}
}
while (z.hasNextLine()) {
if (pass.contains(z.nextLine().trim()) && !found2) {
System.out.println("\nYour password is moderate");
found3 = true;
break;
}
}
if (!found3 && !found2) {
System.out.println("\nYour password is strong");
}
y.close();
z.close();
} catch (Exception e) {
System.out.print("Error");
}
}
The logic seems fine it should print password is strong. You should print out all lines that you read in from the file to debug and see both when the password and the word from the file doesn't match.
I don't think it makes sense to create multiple scanners and read the file twice. You can read in the file once and test the pass to see if it's a week or moderate and return the string and if not found return strong. You can throw the exception so that main up to you. Unless you specifically want to print out the password strength in this function.
Here is a sample.
import java.io.File;
import java.util.Scanner;
public class PasswordTest {
public static String passwordStrength(String pass, String file2) {
try {
Scanner fileScanner = new Scanner(new File(file2));
while (fileScanner.hasNextLine()) {
String passInFile = fileScanner.nextLine().trim();
if (pass.equals(passInFile)) {
return ("Your password is weak");
}
if (pass.contains(passInFile)) {
return "Your password is moderate";
}
}
} catch (Exception e) {
return e.getMessage();
}
return "Your Password is strong";
}
public static void main(String[] args) {
System.out.println(passwordStrength("test", "test.txt"));
}
}
I am having a bit of an issues trying to pass in a file read by my program and sorted accordantly. I am not used to working with files, and i ran out of ideas as to how this could be achieved.
/////////////////////////////////////// class reads file ///////////////////////////////////
import java.io.*;
public class InFileReader {
private BufferedReader inputStream = null;
private String fileLine;
private StringBuilder sb;
public String getFile(File fileRead) throws FileNotFoundException,
IOException {
inputStream = new BufferedReader(new FileReader(fileRead)); //reads files
sb = new StringBuilder();
while((fileLine = inputStream.readLine()) != null){//keep reading lines in file till there is none
sb.append(fileLine).append("\n");
}
return sb.toString(); //returns StringBuffer read values in String form
}
}
///////////////////////////////////////////////////// end of read file class ///////////////////////
public void getFile(File fileRead) throws FileNotFoundException,
IOException {
try {
String input = fileReader.getFile(fileRead.getAbsoluteFile());
HashMap<Integer, Thing.Ship> hashmap = new HashMap<>();
while (!input.isEmpty()) { // as long as there is data in the file keep looping
Scanner sc = new Scanner(input); // scan file
if (!input.startsWith("//")) { // take out "//" from directory
String type = "";
if (sc.hasNext()) { // if there are character lines get next line
type = sc.next();
}
if (type.equalsIgnoreCase("port")) { // looks for "port"
world.assignPort(new Thing.SeaPort(sc)); // assigns value to Seaport
} else if (type.equalsIgnoreCase("dock")) {
world.assignDock(new Thing.Dock(sc));
} else if (type.equalsIgnoreCase("ship")) {
Thing.Ship s = new Thing.Ship(sc);
hashmap.put(s.getIndex(), s);
world.assignShip(s);
} else if (type.equalsIgnoreCase("pship")) {
Thing.Ship s = new Thing.PassengerShip(sc);
hashmap.put(s.getIndex(), s);
world.assignShip(s);
} else if (type.equalsIgnoreCase("cship")) {
Thing.Ship s = new Thing.CargoShip(sc);
hashmap.put(s.getIndex(), s);
world.assignShip(s);
} else if (type.equalsIgnoreCase("person")) {
world.assignPerson(new Thing.Person(sc));
}
}
}
//inputOut.setText(type);
inputOut.setText(world.toString());
} catch (Exception e) {
System.out.println(e + "-----");
}
}
Here fileRead knows where to find the file to be read "C:\Users\abe\IdeaProjects\CreateSeaPortDataFile\src\text.txt"
public void getFile(File fileRead) throws FileNotFoundException,
IOException {
this is where things just fall apart:
String input = fileReader.getFile(fileRead.getAbsoluteFile());
My intent here is to pass the location of the file so that the getFile class can read it and then be sorted into the hashmap.
again i am not familiar with how to work with file, any suggestion or comment would be greatly appreciated.
thank you in advanced.
If you get a FileNotFoundException then the file was not found.
You say the filename was "C:\Users\abe\IdeaProjects\CreateSeaPortDataFile\src\text.txt".
If you type that name in the code you must escape the backslash:
"C:\\Users\\abe\\IdeaProjects\\CreateSeaPortDataFile\\src\\text.txt".
I have been trying to compare the file content with user input. The program is reading from a specific file and it checks against the user's string input. I am having trouble comparing the ArrayList with the user input.
public class btnLoginListener implements Listener
{
#Override
public void handleEvent(Event arg0)
{
//variables for the class
username = txtUsername.getText();
password = txtPassword.getText();
MessageBox messageBox = new MessageBox(shell, SWT.OK);
try {
writeFile();
messageBox.setMessage("Success Writing the File!");
} catch (IOException x)
{
messageBox.setMessage("Something bad happened when writing the file!");
}
try {
readFile("in.txt");
} catch (IOException x)
{
messageBox.setMessage("Something bad happened when reading the file!" + x);
}
if (username.equals(names))
{
messageBox.setMessage("Correct");
}
else
{
messageBox.setMessage("Wrong");
}
messageBox.open();
}
}
private static void readFile(String fileName) throws IOException
{
//use . to get current directory
File dir = new File(".");
File fin = new File(dir.getCanonicalPath() + File.separator + fileName);
// Construct BufferedReader from FileReader
BufferedReader br = new BufferedReader(new FileReader(fin));
String line = null;
while ((line = br.readLine()) != null)
{
Collections.addAll(names, line);
}
br.close();
}
I am assuming you are trying to check whether an element exists in the list. If yes, then you need to use contains method, here's the Javadoc.
So, instead of using if (username.equals(names)), you can use if (names.contains(username)).
Apart from this, you should make the following changes:
Don't read the file every time an event is called. As you are reading a static file, you can read it once and store it in an ArrayList.
Make variables username and password local.
Remove writeFile() call unless it's appending/writing dynamic values on each event.