Comparing ArrayList with user input - java

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.

Related

java.io.BufferedWriter throttles or completely stopped during the process of writing, anyone know why?

As described in the question, I have encountered a weird throttling of write speed (even paused entirely) when using java.io.BufferedWriter to write.
My program is trying to read from a bunch of .csv files, and repack them to another bunch of .csv files grouped by the first column.
For example, if I have a line in the .csv file Tom, 86, 87, 88, this line will be written to the .csv file named Tom.csv.
I uses a HashMap<String, BufferedWriter> to cache the writers so that the program only have to open / close the writers once.
(I purposely split the file listing and the process logic for debugging)
The code:
package dev.repackcsv;
import java.io.*;
import java.nio.file.*;
import java.util.*;
public class Main {
private static final Path USER_DIR;
private static final Path PROP_FILE;
private static final Properties PROPERTIES;
private static final Path SCAN_DIR;
private static final Path OUTPUT_DIR;
private static final List<Path> SCANNED_FILE_LIST;
private static final Map<String, BufferedWriter> OUTPUT_FILE_MAP;
private static void loadProperties() {
try (InputStream propFileInputStream = Files.newInputStream(PROP_FILE)) {
PROPERTIES.load(propFileInputStream);
} catch (IOException e) {
System.err.println("[Error] Failed to load properties from \"application.properties\"");
System.exit(1);
}
}
private static String getProperty(String propertyName) {
String property = PROPERTIES.getProperty(propertyName);
if (property == null) {
System.err.println("[Error] Undefined property: " + propertyName);
System.exit(1);
}
return property;
}
static {
USER_DIR = Paths.get(System.getProperty("user.dir"));
PROP_FILE = USER_DIR.resolve("application.properties");
if (!Files.exists(PROP_FILE)) {
System.err.println("[Error] \"application.properties\" file does not exist.");
System.exit(1);
}
PROPERTIES = new Properties();
loadProperties();
SCAN_DIR = Paths.get(getProperty("scan.dir")).toAbsolutePath();
if (!Files.exists(SCAN_DIR)) {
System.err.println("[Error] Scan directory does not exist");
System.exit(1);
}
OUTPUT_DIR = Paths.get(getProperty("output.dir")).toAbsolutePath();
if (!Files.exists(OUTPUT_DIR)) {
System.err.println("[Error] Output directory does not exist");
System.exit(1);
}
SCANNED_FILE_LIST = new LinkedList<>();
OUTPUT_FILE_MAP = new HashMap<>();
}
private static void loadScannedFileList()
throws IOException {
try (DirectoryStream<Path> ds = Files.newDirectoryStream(SCAN_DIR)) {
for (Path path : ds) {
SCANNED_FILE_LIST.add(path.toAbsolutePath());
}
}
}
private static BufferedWriter getOutputFileBufferedWriter(String key, String headLine) throws IOException {
if (OUTPUT_FILE_MAP.containsKey(key)) {
return OUTPUT_FILE_MAP.get(key);
} else {
Path outputFile = OUTPUT_DIR.resolve(key + ".csv");
boolean isNewFile = false;
if (!Files.exists(outputFile)) {
Files.createFile(outputFile);
isNewFile = true;
}
BufferedWriter bw = Files.newBufferedWriter(outputFile);
if (isNewFile) {
bw.write(headLine);
bw.newLine();
bw.flush();
}
OUTPUT_FILE_MAP.put(key, bw);
return bw;
}
}
private static void processScannedCSV(Path csvFile)
throws IOException {
System.out.printf("[Info] Current file \"%s\"%n", csvFile);
long fileSize = Files.size(csvFile);
try (BufferedReader br = new BufferedReader(new InputStreamReader(Files.newInputStream(csvFile)))) {
String headLine = br.readLine();
if (headLine == null) { return; }
String dataLine;
long readByteSize = 0;
while ((dataLine = br.readLine()) != null) {
int firstCommaIndex = dataLine.indexOf(',');
if (firstCommaIndex == -1) { continue; }
BufferedWriter bw = getOutputFileBufferedWriter(dataLine.substring(0, firstCommaIndex), headLine);
bw.write(dataLine);
bw.newLine();
readByteSize += dataLine.getBytes().length;
System.out.print("\r[Progress] " + readByteSize + '/' + fileSize);
}
}
System.out.print("\r");
}
private static void processScannedFiles()
throws IOException {
for (Path file : SCANNED_FILE_LIST) {
if (!Files.exists(file)) {
System.out.printf("[WARN] Scanned file \"%s\" does not exist, skipping...%n", file);
continue;
}
if (!file.toString().endsWith(".csv")) { continue; }
processScannedCSV(file);
}
}
public static void main(String[] args)
throws IOException {
loadScannedFileList();
processScannedFiles();
for (BufferedWriter bw : OUTPUT_FILE_MAP.values()) {
bw.flush();
bw.close();
}
}
}
The output (For this scenario the program is freezed during the line bw.write(dataLine);):
I uses Intellij-IDEA as the editor and executes the program using debug mode.
Connected to the target VM, address: '127.0.0.1:25111', transport: 'socket'
[Info] Current file "..\scan-dir\L2_options_20150102.csv"
[Progress] 8166463/109787564
It would be great if anyone knows the cause / has a solution for this :(
Thanks!
Having many files open can be a heavy load on the disk operating system, the number of file handles (limited!), and "moving the write head around" should one do things concurrently.
About the statics
The code shows experience (also concerning Java), maybe also from a language like C. Because the use of static is unusual. you could in main do a new Main().executeMyThings(); and drop static elsewhere.
Measures to take
Do not use text but binary data, not Writer/Reader, but OutputStream/InputStream. This prevent a Unicode conversion back and forth. Also you risk data loss, when a Windows UTF-8 file on Linux.
Use ArrayList rather LinkedList as for many items it is likely to behave better.
You might want to collect file paths instead of BufferedWriters. Every BufferedWriter is not only a OS resource, but maintains a buffer (memory). It might even be more performant, writing the head line, closing and reopening it in append mode. The headline could be written be with Files.writeString.
System.out is costly. A ConsoleLogger might be safer would be safer with concurrency,
but costs too.
readByteSize misses the line break, 2 for Windows files.
A BufferedWriter can be created with a larger/smaller buffer size.
for (Path path : ds) {
SCANNED_FILE_LIST.add(path.toAbsolutePath());
}
might be better as:
ds.forEach(path -> SCANNED_FILE_LIST.add(path.toAbsolutePath());

Pass in file text into hashmap

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".

Unable to modify a file entered as an argument JAVA

I'm trying to get this to work but it doesn't and I don't get why,
It's supposed to be a script where I enter an argument file and it replaces it with the correct replaced characters in it.
It doesn't replace the file I entered as argument.
I can get it to work If I place the whole code in the main function without calling a method.
Thanks.
public class Rename
{
public static void main(String[] args) throws IOException{
File origine = new File(args[0]);
renameFile(origine);
}
public static void renameFile(File fileOriginal) throws IOException
{
try
{
File tempFile = File.createTempFile("buffer", ".tmp");
FileWriter fw = new FileWriter(tempFile);
Reader fr = new FileReader(fileOriginal);
BufferedReader br = new BufferedReader(fr);
while (br.ready())
{
fw.write(br.readLine().replace("#/A#" , "Á"));
}
fw.close();
br.close();
fr.close();
tempFile.renameTo(fileOriginal);
} catch (IOException e) {
e.printStackTrace();
}
}
}
renameTo() returns a value. You are ignoring it.
You can't rename a file to the name of an existing file. You have to ensure the target name doesn't exist.
ready() is not a test for end of stream: see the Javadoc.
A method that modifies the content of a file should not be called renameFile().

Assistance on simple authentication system in Java

I have written a very simple program that reads in a username and password from a text file, where the username and password are separated by a comma. The contents of the text file contains the following
accounts.txt
Alex,1234
David,5678
My java application is written as follows
public class Authenticate {
public void signIn(String username, String password) throws IOException {
FileReader fr = new FileReader("location/accounts.txt");
BufferedReader br = new BufferedReader(fr);
while (true) {//read file line by line
String line = br.readLine();
if (line == null) {
break;
}
String splitByComma = ",";
String[] details = line.split(splitByComma);
String registeredUser = details[0];
String registeredPass= details[1];
if(username.equals(registeredUser) && password.equals(registeredPass)){
System.out.println("signed in successfully!");
}
else{
System.out.println("sign in failed");
}
}
br.close();
}
}
My App class which called the program:
public class App {
public static void main(String[] args) throws IOException {
Register register = new Register("location/accounts.txt");
Authenticate auth = new Authenticate();
auth.signIn("David", "5678");
}
}
The problem is when I pass in "Alex" "1234" in method for example, the output is
signed in successfully!
sign in failed
And when I pass in "David" "5678" i get
sign in failed
signed in successfully!
I want the application to output "signed in successfully" and "sign in failed" only once depending on the credentials entered.
Many thanks!
This means you are calling your method twice with different values. Check the calling code (which you haven't provided to us).
Other remarks:
Please don't consider something like this for serious authentication. Passwords should at least be hashed in your file (for example using BCrypt). There are many frameworks which offer industry strength authentication solutions which you should use instead of 'rolling your own'.
You should close resources in one of these ways:
1) in a finally block:
BufferedReader br = null;
try {
br = new BufferedReader(...);
// do stuff
}
finally {
if (br != null) {
br.close();
}
}
2) using the Java 8 try-with-resources idiom:
try (BufferedReader br = new BufferedReader(...)) {
// do stuff
}
(the BufferedReader will be automatically closed by the runtime environment)
In your example above you should probably check the input for null values before checking the values with .equals.
First search for the user name. Once found, check the password and exit the loop:
public class Authenticate {
public void signIn(String username, String password) throws IOException {
try (
FileReader fr = new FileReader("location/accounts.txt");
BufferedReader br = new BufferedReader(fr);
) {
boolean success = false;
String line;
while ((line = br.readLine()) != null) {
String[] details = line.split(",");
String registeredUser = details[0];
if (registeredUser.equals(username)) {
String registeredPass = details[1];
success = registeredPass.equals(password);
break;
}
}
System.out.println(success ? "signed in successfully!" : "sign in failed");
}
}
}

How to store text from JOptionPane into text file

I am a novice. I am trying to take the user-input text from the JOptionPane, and store it into a text file. Thereafter I would like to read the text and do what-not with it.
May I please have help on storing the inputted text? Thanks.
Here's my code:
import javax.swing.JOptionPane;
import java.io.*;
public class RunProgram {
public static void introView() {
//The introduction
JOptionPane.showMessageDialog(null, "Welcome." +
" To begin, please click the below button to input some information " +
"about yourself.");
}
public static void personInput() {
try{
File userInfo = new File("C:\\Users\\WG Chasi\\workspace\\" +
"Useful Java\\products\\UserInfo.txt");
userInfo.getParentFile().mkdirs();
FileWriter input = new FileWriter(userInfo);
JOptionPane userInput = new JOptionPane();
userInput.showInputDialog("Enter details");/*I want to store the text from the InputDialog into the text file*/
//Write text from the JOptionPane into UserInfo.txt
}catch(Exception e){
JOptionPane.showMessageDialog(null, "An ERROR has occured.");
}
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
introView();
personInput();
}
});
}
}
You have any number of potential options, depending on your needs...
You could...
Write the contents to a Properties file...
private Properties properties = new Properties();
//...
String name = JOptionPane.showInputDialog("What is your name?");
properties.set("user.name", name);
//...
protected void savePropeties() throws IOException {
try (OutputStream os = new FileOutputStream(new File("User.properties"))) {
properties.store(os, "User details");
}
}
protected void loadPropeties() throws IOException {
try (InputStream is = new FileInputStream(new File("User.properties"))) {
// Note, this will overwrite any previously existing
// values...
properties.load(is);
}
}
As you can see, you have to physically load and save the contents yourself. This does mean, however, you get to control the location of the file...
You could...
Make use of the Preferences API...
String name = JOptionPane.showInputDialog("What is your name?");
Preferences preferences = Preferences.userNodeForPackage(RunProgram.class);
preferences.put("user.name", name);
Then you would simply use something like...
Preferences preferences = Preferences.userNodeForPackage(RunProgram.class);
String name = preferences.get("user.name", null);
to retrieve the values.
The benefit of this is the storage process is taking care for you, but you lose control of where the data is stored.
You could...
Write the data to a file yourself, in your own format. This is lot of work and overhead, but you gain the benefit of not only controlling the location of the file, but also the format that the data is maintained in. See Basic I/O for some more details.
Write the data in XML format, which provides a level of hierarchical control (if that's important), but does increase the complexity of the management.
Try this
public static void personInput()
{
String whatTheUserEntered = JOptionPane.showInputDialog("Enter details");
JFileChooser chooser = new JFileChooser();
chooser.setCurrentDirectory( new File( "./") );
int actionDialog = chooser.showSaveDialog(yourWindowName); //where the dialog should render
if (actionDialog == JFileChooser.APPROVE_OPTION)
{
File fileName = new File(chooser.getSelectedFile( ) + ".txt" ); //opens a filechooser dialog allowing you to choose where to store the file and appends the .txt mime type
if(fileName == null)
return;
if(fileName.exists()) //if filename already exists
{
actionDialog = JOptionPane.showConfirmDialog(yourWindowName,
"Replace existing file?");
if (actionDialog == JOptionPane.NO_OPTION) //open a new dialog to confirm the replacement file
return;
}
try
{
BufferedWriter out = new BufferedWriter(new FileWriter(fileName));
out.write(whatTheUserEntered );
out.close(); //write the data to the file and close, please refer to what madProgrammer has explained in the comments here about where the file may not close correctly.
}
catch(Exception ex)
{
System.err.println("Error: " + ex.getMessage());
}
}
}
I am basically attempting to get the text from the input dialog and write it to a file of your choice. The file will be written as a text file using the appending string ".txt" which sets the mime type so will always be text.
Let me know how it goes.

Categories

Resources