Why does my anti-duplicate file loop not function? - java

I am creating a project where a random "UserID" is generated when the user wants to add a customer. Along with this UserID, a file is created with the formatted userID which contains user entered first name and last name. I am currently using random to generate user ID's, and created a do while loop to avoid possible duplicate. In the final project, I will have random set to pull from 9999, but for demonstration and duplicate testing purposes, it is set to 1.
All of the sudden, my do-while loop is not functioning as it has been. I have tried moving a few things around, checking syntax and changing directories, but nothing is working.
Why is my do-while loop that serves as an anti-duplicate file method not working?
public static void userAddition() throws IOException
{
boolean retry = true;
String formattedUserId = "";
Random randomNumbers = new Random();
int userId;
final int MAX_RETRIES = 10;
int retryCount = 0;
do
{
retryCount++;
userId = randomNumbers.nextInt(1);
formattedUserId = String.format("%04d", userId);
File f = new File("C:/Users/Nick/Desktop/Library" + formattedUserId + ".txt");
retry = f.exists();
}
while (retry && retryCount < MAX_RETRIES);
if (retry)
{
System.out.println("Error");
}
else
{
// happy path
String userFirstName = JOptionPane.showInputDialog("Enter the customer's first name:");
String userLastName = JOptionPane.showInputDialog("Enter the customer's last name:");
FileWriter fw = new FileWriter(formattedUserId + ".txt", true);
PrintWriter outputFile = new PrintWriter(fw);
outputFile.printf("#%s%n", formattedUserId);
outputFile.printf("%s %s", userFirstName, userLastName);
System.out.println(formattedUserId);
outputFile.close();
}
}
}
I expect the do-while loop to run through 10 times, before hitting the MAX_RETRIES and displaying "Error".

You test for the existence of file C:/Users/Nick/Desktop/Library0000.txt:
File f = new File("C:/Users/Nick/Desktop/Library" + formattedUserId + ".txt");
Then you create the file in the folder of the project with the name 0000.txt:
FileWriter fw = new FileWriter(formattedUserId + ".txt", true);
So your test for existence will never return true :)
The easy fix is to store the calculated file name in a variable:
String fileName = String.format("C:/Users/Nick/Desktop/Library/%04d.txt", userId);
File f = new File(fileName);
...
FileWriter fw = new FileWriter(fileName, true);
By the way, have a look at try-with-resources, you should use it like this:
try (Writer writer = new PrintWriter(FileWriter(fileName, true))) {
writer.printf("#%s%n", formattedUserId);
writer.printf("%s %s", userFirstName, userLastName);
// notice: no close(), this is handled automatically and better!
}

Related

How to remove a row from a csv file if that row contains a certain data in java

I have a csv file that basically mimics a database and my goal is to remove a row from that csv if the csv file contains that username input I provide
the current csv file is:
Jack chan,customer,jack#yorku.ca,jack12,3144134414,13 Arboretum,user2
Donald tusk,customer,donald#yorku.ca,donald1,1213141114,14 Arboretum,user3
tom jack,customer,tom11#yahoo.com,tom44,131344122,14 wells st,user34
jack,parking officer,12rfw#hmail.com,jack,12131131134,12ddcscs,peo1
jewel khan,parking officer,jkhan#hotmail.com,jwel12,2131412141,12 wliis str,peo2
shane li,parking officer,shane#gmail.com,shaneli,1343513414,13 mac st,peo33
james chang,parking officer,james15#gmail.com,james12,31452434114,13 chang st,peo77
my objective is to remove the row of say Shane li using his username "shaneli" and not causing any change to other data. but the current code I have is not causing the file's other data to change
the expected output csv file is row with shaneli gets deleted with other rows remaining intact:
Jack chan,customer,jack#yorku.ca,jack12,3144134414,13 Arboretum,user2
Donald tusk,customer,donald#yorku.ca,donald1,1213141114,14 Arboretum,user3
tom jack,customer,tom11#yahoo.com,tom44,131344122,14 wells st,user34
jack,parking officer,12rfw#hmail.com,jack,12131131134,12ddcscs,peo1
jewel khan,parking officer,jkhan#hotmail.com,jwel12,2131412141,12 wliis str,peo2
james chang,parking officer,james15#gmail.com,james12,31452434114,13 chang st,peo77
this is the code java code I have and I need a java solution:
private static String userPath = "/CSVs/database.csv";
public void removeUser(String name,String userType,String email,String userName,String phoneNumber,String address,String password) {
// FIX THIS
String tmpFile = "tmp.csv";
// String target1 = ""; String target2 = ""; String target3 = ""; String target4 = ""; String target5 = "";String target6 = "";String target7 = "";
String target = "";
File oldFile = new File(userPath);
File newFile = new File(tmpFile);
System.out.println(userName);
try {
FileWriter fw = new FileWriter(tmpFile, true);
BufferedWriter bfw = new BufferedWriter(fw);
PrintWriter pw = new PrintWriter(bfw);
x = new Scanner(new File(userPath));
x.useDelimiter("[,\n]");
while (x.hasNext()) {
target = x.next();
if (!target.equals(userName)) {
pw.printf("%s,%s,%s,%s,%s,%s,%s\n", name, userType,email,userName,phoneNumber,address,password);
// pw.println(target + "," + target + "," + target + "," + target + "," + target + "," + target + "," + target);
}
}
x.close();
pw.flush();
pw.close();
oldFile.delete();
File dmp = new File(userPath);
newFile.renameTo(dmp);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
Please advice
Thanks in advance !!
Solution
The way I've come up with is to do the following:
Create a new file
If the username is not equal, add line, otherwise skip it
Just as we've listed out our steps, we can create a function to do each one.
Code
1) Creating a new file
private void createFile(){
try {
File myObj = new File("CSVs/tmpFile.csv");
} catch (IOException e) {
e.printStackTrace();
}
}
We can then create the file which will be stored at the desired file path and stored as tmpFile.csv.
2) If the username are not equal, add line
private void addDataContents(String userNameToDelete){
try{
String userPath = "CSVs/database.csv";
BufferedReader csvReader = new BufferedReader(new FileReader("CSVs/database.csv"));
String row;
FileWriter myWriter = new FileWriter("CSVs/tmpFile.csv");
while (((row = csvReader.readLine()) != null)){
String[] line = row.split(",");
if (!line[3].equals(userNameToDelete)){
myWriter.write(row + "\n");
}
}
myWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
We then read through the contents of database.csv. We read every line one by one and split the line up by commas as it is a CSV file ( Comma Separated Values ). As the username will always be stored in the 3rd index, we can compare the username we wish to delete with the value stored at the index. If they are not the same, we can go ahead and write the line to our new file. If they are the same, our loop will just continue onto the next line.
Final Notes
I hope everything is easy to read and understandable.
You need to delete the whole row containing specific data from a CSV file. The Java code will be rather long if you try to use the high-level language to do this. It is very simple to accomplish the task in SPL, an open-source Java package. You just need one line of code, as shown below:
A
1
>file("tmp.csv").export#c(file("database.csv").import#wc().select(~(4)!=userNameToDelete))
SPL offers JDBC driver to be invoked by Java. Just store the above SPL script as removeUser.splx and invoke it in Java in the same way you call a stored procedure:
…
Class.forName("com.esproc.jdbc.InternalDriver");
con= DriverManager.getConnection("jdbc:esproc:local://");
st = con.prepareCall("call removeUser(?)");
st.setObject(1,"shaneli");
st.execute();
…

How to rename instances of filepath scattered throughout program based on user input?

I'm pretty new to Java, so apologies if this question seems dumb, I've tried google but there's not really anything on there that matches what I'm looking for.
I am trying to get my program to take in user input and rename .txt files linked to the program with their input. My only issue is, I don't know how I would then take that input and update all the named instances of the filepath across the program. For the most part, I am passing the filepath into methods for usage, but the initial variable of filepath I have declared as a String.
Any advice on the most efficient way to update all instances of this variable at once with the new file name?
String filepath = "src/file.txt";
Here is the code I currently have for editing the file name:
public static void fileRename(){
String oldFileName = "";
String newFileName = "";
Scanner in = new Scanner(System.in);
System.out.println("Please enter old File name: ");
System.out.println("Formatted as: src/oldFileName.csv");
oldFileName = in.next();
System.out.println("Please enter new File name: ");
System.out.println("Formatted as: src/newFileName.csv");
newFileName = in.next();
File oldFile = new File(oldFileName);
File newFile = new File(newFileName);
oldFile.renameTo(newFile);
// sets filepath variable across program equal to newFileName
}
Once the user has renamed the file, I am struggling with then updating the filepath variable across the program, as it occurs multiple times within the program.
String targetExtension = ".txt";
if (args.length >= 1 ) {
int extIndex = args[0].lastIndexOf(".");
if (extIndex != -1) {
String ext = args[0].substring(extIndex);
System.out.println(ext);
if (ext.equalsIgnoreCase(".xml")){
try
{
File f = new File(args[0]);
if (!f.exists())
{
f.createNewFile();
}
args[0] = args[0].substring(0, extIndex) + targetExtension;
System.out.println(" " + args[0]);
File change = new File(args[0]);
f.renameTo(change);
}catch (IOException e)
{
e.printStackTrace();
}
}
}
you can use elseif for all the extension.

How to get the updated file text

I am making a JFrame from where the user will be able to insert new methods in the file. If the file is not there, program will create the new file and then insert the method there. If the file is already there, it will try to create the new method with the given name but if the file contains the method with the same name, it'll give user the alert.
I am able to do all these things properly, only problem is after creating the new method in the class file, if the user again click on the Create Method button, application does not throws any alert as it is unable to read the new method name from the file. When I check the file content, I can see the new method there but somehow my code is not able to read the new code from the file. Here is the code for the same.
File f = null;
f = new File(Report.path + "//src//_TestCases//" + tc_name + ".java");
if (!f.exists()) {
BufferedWriter bw = new BufferedWriter(new FileWriter(f));
f.createNewFile();
bw.write(testcase);
bw.close();
}
Class<?> c = Class.forName("_TestCases." + tc_name);
Method[] m = c.getDeclaredMethods();
for (int i = 0; i < m.length; i++) {
if (m[i].getName().toLowerCase()
.equals(module_name.toLowerCase())) {
JOptionPane
.showMessageDialog(null,
"Module with the given name already exists. Please provide other name.");
return false;
}
}
List<String> lines = Files.readAllLines(f.toPath(),
StandardCharsets.UTF_8);
String text = "";
if (lines.contains(" #AfterClass")) {
text = " #AfterClass";
} else {
text = "#AfterClass";
}
lines.add(lines.indexOf(text), "#Test\npublic void " + module_name
+ "() throws Exception {\n");
Files.write(f.toPath(), lines, StandardCharsets.UTF_8);
for (int i = 0; i < tc_values.size(); i++) {
lines.add(lines.indexOf(text), tc_values.get(i));
Files.write(f.toPath(), lines, StandardCharsets.UTF_8);
}
lines.add(lines.indexOf(text), "\n}\n");
Files.write(f.toPath(), lines, StandardCharsets.UTF_8);
Not sure what the issue was but when I changed the logic of getting the method name from the file, it worked for me. Used scanner to read the file contents and get the method name, earlier was using the below line to get the method name from the file.
Method[] m = c.getDeclaredMethods();

Java rename not working

Here is my code
private void edit(String search_bookname) {
String current_bookname ="", current_ISBN = "", current_author = "", current_rating = "", record = "", comma = ",", current_status = "";
int flag1 = 0, flag2 = 0;
File file = new File("Book_data.txt");
try {
BufferedReader reader = new BufferedReader (new FileReader (file));
File f = new File("Book_data_copy.txt");
FileWriter create = new FileWriter(f);
PrintWriter y = new PrintWriter(create);
while(reader.ready())
{
record = reader.readLine();
StringTokenizer st = new StringTokenizer(record, ",");
while(st.hasMoreTokens()) {
current_bookname = st.nextToken();
current_author = st.nextToken();
current_ISBN = st.nextToken();
current_rating = st.nextToken();
current_status = st.nextToken();
flag2 = 0;
if (search_bookname.equals(current_bookname)) {
flag1 = 1;
flag2 = 1;
try {
y.print(current_bookname); y.print(comma);
y.print(current_author); y.print(comma);
y.print(current_ISBN); y.print(comma);
y.print(current_rating); y.print(comma);
y.println("Borrowed");
} catch(Exception e) {}
Thread.sleep(1000);
}
}
if(flag2==0) // All non-matching records shall only be written to file. Record to be deleted will not be written to new file
{
y.print(current_bookname); y.print(comma); //One record per line..... Each field in a record is seperated by COMMA (" , " )
y.print(current_author); y.print(comma);
y.print(current_ISBN); y.print(comma);
y.print(current_rating);y.print(comma);
y.println(current_status);
}
}
reader.close();
y.close();
create.close();
} catch (Exception e) {}
if(flag1==1) //Rename File ONLY when record has been found for Edit
{
File oldFileName = new File("Book_data_copy.txt");
File newFileName = new File("Book_data.txt");
System.out.println("File renamed .....................");
try
{
newFileName.delete(); oldFileName.renameTo(newFileName);
if (oldFileName.renameTo(newFileName))
System.out.println("File renamed successfull !");
else
System.out.println("File rename operation failed !");
Thread.sleep(1000);
} catch (Exception e) {}
}
}
The project is for a library system. I am relatively new to java and I use netbeans on windows 8.1. The code outputs rename operation failed. Almost exactly the same code for edit has been used before in the program and it worked.
Any suggestions or code corrections would be helpfu.
Thanks!
Your issue is with the below code section
oldFileName.renameTo(newFileName);
if (oldFileName.renameTo(newFileName))
you are trying to rename twice. The first might pass but the 2nd will definitely fail. Check if the original file was renamed. If any error is thrown pring the stack trace and add the trace to your post.
You are trying to rename oldFileName twice:
newFileName.delete(); oldFileName.renameTo(newFileName); // rename
if (oldFileName.renameTo(newFileName)) // rename again ?!
System.out.println("File renamed successfull !");
else
System.out.println("File rename operation failed !");
The second rename in the if() fails, because the file was renamed already in the line before.
There are any number of problems here, starting with ignoring exceptions; not closing the file in a finally block; and using Reader.ready() incorrectly.
This is 2015. Use java.nio.file!
final Path srcFile = Paths.get("Book_data.txt").toAbsolutePath();
final Path dstFile = srcFile.resolveSibling("Book_data_copy.txt");
try (
final BufferedReader reader = Files.newBufferedReader(srcFile, StandardCharsets.UTF_8);
final BufferedWriter writer = Files.newBufferedWriter(dstFile, StandardCharsets.UTF_8,
StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
final PrintWriter pw = new PrintWriter(writer);
) {
// work with reader and pw
}
if (flag1 == 1)
Files.move(dstFile, srcFile, StandardCopyOption.REPLACE_EXISTING,
StandardCopyOption.ATOMIC_MOVE);
If you did that from the start, not only would your resources have been closed safely (your code doesn't do that) but you would have gotten a meaningful exception as well (you are trying to rename twice; you would have had a NoSuchFileException on the second rename).
Relying on File is an error, and it has always been.

print only array items that are greater than a certain int

I wrote this simple script that reads a text file and then adds the data to an array however i only want to print the first and last name of the students that have over 90 credits
Student[] student = new Student[50];
Scanner userin, filein;
String filename;
int numStudents;
// Get the filename from the user, with exception handling to deal with incorrect file names
userin = new Scanner(System.in);
filename = null;
filein = null;
filename = Students.txt;
try {
filein = new Scanner(new FileReader(filename)); // try to open the file
} catch (FileNotFoundException e) { // failed to open the file
System.out.println("Invalid file - try again");
filename = null;
}
numStudents = 0;
while (filein.hasNext()){
String lastName = filein.next();
String firstName = filein.next();
double gpa = filein.next();
int Credits = filein.next();
student[numStudents++] = new Student(lastName,firstName,gpa,Credits);
}
int i=0;
do
{
System.out.println(student[i].toString());
i++;
}
while ((student[i] != null)&&(i <= student.length));
"script"?
This is some ugly code. Formatting and structure matter. I'd recommend paying more attention to it in the future. It'll make your maintenance life easier as your programs (aka "scripts") become more complex.
Learn the Sun Java coding standards. You aren't following them now.
Everything in Java has to be a part of a class. I'll assume that you know that. This must be a snippet you cut out of your class.
Your code is too chaotic to worry about making it nice. This'll work:
if (student[i].getCredits() >= 90)
System.out.println(student[i].toString());

Categories

Resources