Removing a line from a file via button action - java

YES, I have searched the method to remove a specific line via comparing&matching, but mine is different from the situations I've searched, and the wrong action takes place.
The code here is the actionPerformed for the button btnRemove. What it does is it removes the selected cell from the table, and also is meant to remove the corresponding cell (string) value from the file Activities.dat
However, what happens is that the code makes the entire file removed and blank, leaving 1 empty line, not just the line I want removed.
btnRemove.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
//Execute when button is pressed
int row = table.getSelectedRow();
int column = table.getSelectedColumn();
if (row >= 0) {
if (column >=0) {
for(int i=0; i<5; i++)
{
table.setValueAt("", row, column);
}
}
}
File file1 = new File("Activities.dat");
try
{
BufferedWriter writer = new BufferedWriter(new FileWriter(file1));
BufferedReader reader = new BufferedReader(new FileReader(file1));
Object lineToRemove = table.getValueAt(row, column);
lineToRemove.toString();
System.out.print(lineToRemove);
String currentLine;
while((currentLine = reader.readLine()) != null)
{
// trim newline when comparing with lineToRemove
String trimmedLine = currentLine.trim();
Object lineToRemove = table.getValueAt(row, column);
lineToRemove.toString();
if(trimmedLine.equals(lineToRemove)) continue;
writer.write(currentLine);
}
writer.close();
}
catch (IOException ex)
{
Logger.getLogger(ActivityScreen.class.getName()).log(Level.SEVERE, null, ex);
}
}
});

You're making a duplicate lineToRemove in your while loop. It will also be better if you changed the type of line to String and assign the value of table.getValueAt(row, column).toString() to it (and don't change it afterwards). Also, you're setting the value of [row, column] before you get it. You will be searching for "" (searching for nothing if not a very good idea). Try doing something like this:
btnRemove.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// Execute when button is pressed
int row = table.getSelectedRow();
int column = table.getSelectedColumn();
if (row >= 0) {
if (column >= 0) {
File file1 = new File("Activities.dat");
File temp = new File(file1.getAbsolutePath() + ".tmp"); // temp file
PrintWriter writer = null;
BufferedReader reader = null;
try {
writer = new PrintWriter(new BufferedWriter(new FileWriter(temp)), false);
reader = new BufferedReader(new FileReader(file1));
String lineToRemove = table.getValueAt(row, column).toString();
System.out.print(lineToRemove);
String currentLine;
while ((currentLine = reader.readLine()) != null) {
// trim newline when comparing with lineToRemove
String trimmedLine = currentLine.trim();
if (trimmedLine.equals(lineToRemove))
continue;
writer.println(currentLine);
}
} catch (IOException ex) {
Logger.getLogger(ActivityScreen.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
if (reader != null)
reader.close();
if (writer != null) {
writer.flush();
writer.close();
file1.delete(); // delete the old one
temp.renameTo(file1); // make temp same as original
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
table.setValueAt("", row, column);
}
}
}
});

Look at RandomAccessFile. Leave the file as it is until the line you want to remove, then copy the rest of the file from the end of your removed part to the end of file from the point you started removing.
Pseudo code:
String line = "line I want to remove";
RandomAccessFile raf = openRandomAccessFile();
while(!line.equals(raf.readLine())) {
//just going to the point we want
}
long beginOfTheRemovingPointer = raf.getFilePointer()-size of removed line;
raf.seek(beginOfTheRemovingPointer);
raf.write(from beginOfTheRemovingPointer+size of removed line until the end);
raf.setLength(new length);
The RandomAccessFile methods exist. Just take a look at the API to know what they do exactly.

Related

JavaFX reading a text file and displaying it to multiple text fields

I have a text file with 4 lines of random words, line for line, and I need to be able to read each line and display it to its text field (First line goes into first text field, etc), but it is only reading the last line and displaying it into any text field.
"myfile.txt"
one
two
three
onetwothree
TextField label1Text = new TextField();
TextField label2Text = new TextField();
TextField label3Text = new TextField();
load.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent l) {
String line = "";
try {
BufferedReader reader = new BufferedReader(new FileReader("myfile.txt"));
while ((line = reader.readLine()) != null) {
label1Text.setText(line);
label2Text.setText(line);
label3Text.setText(line);
labelO2Text.setText(line);
}
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
});
primaryStage.show();
}
}
Your current code reads each line in turn, and for each line sets the text of all the labels to that line of text.
Instead, you need to take each label in turn, and set its text to the next line from the file. You can do that with something like:
try (BufferedReader reader = new BufferedReader(new FileReader("myfile.txt"))) {
List.of(label1Text, label2Text, label3Text, label02Text)
.forEach(label -> {
try {
label.setText(reader.readLine());
} catch (IOException exc) {
// handle exception
}
});
}
You are reading a single line, then setting the content of that line to all 3/4 TextFields (there is one missing in your example). After the loop finishes, all TextFields are set to the content of the last line of your file.
There is a variety of ways to achieve what you want - if you only ever have 4 entries, the following will work:
String[] lines = new String[4];
int index = 0;
while ((line = reader.readLine()) != null) {
lines[index++] = line;
if (index==4) break;
}
label1Text.setText(lines[0]);
label2Text.setText(lines[1]);
label3Text.setText(lines[2]);
label4Text.setText(lines[3]);
If you had references to your TextFields in an array, you could also do
int index = 0;
while ((line = reader.readLine()) != null) {
labels[index++].setText(line);
if (index==4) break;
}
The problem sits in your loop
while ((line = reader.readLine()) != null) {
label1Text.setText(line);
label2Text.setText(line);
label3Text.setText(line);
labelO2Text.setText(line);
}
Basically if we look at the loop, first iteration changes all of the labels to the word "One", second iteration in the loop sets all the labels to "Two", than "Three" and last iteration sets all labels as "Four".
To solve the problem you can add a simple counter with some if statements, so it will tell your loop what to do.
int counter = 0;
while ((line = reader.readLine()) != null) {
if(counter == 0)
label1Text.setText(line);
if(counter == 1)
label2Text.setText(line);
if(counter == 2)
label3Text.setText(line);
if(counter == 3)
labelO2Text.setText(line);
counter++;
}
I am sure it is not the most optimal way, but if you want to do it with loop, that's it.

Need to read from a txt file in the assets folder in android studio

My buddy and I are writing a simple app in Android Studio. When you push a button, a new activity opens with the name of the button you pushed and displays the text in that file.
I have the code that generates the first set of buttons (these are hard coded), and I can get the name of the buttons pushed. My trouble is reading the text file and displaying the contents. Each line in the text file is a word that needs to be the text value of a button. I can't hard code the words because they can change often.
Example; On the main activity you push the button labeled "Round", it sends you to a page that has all the words in the text file named "round" listed as buttons.
I asked this question earlier, but it was put on hold as too vague.
I hope this is more clear.
Here's the code I'm using, but need the code to read the file. This is not working right.
I can't get it to display even the first line. The file contents are this ---
Pipe
Elbow
Reducer
Tap on flat
EC
Please help.
Thanks in advance.
public class test extends Activity {
int counter = 0;
protected void onCreate(Bundle savedInstanceState) {
counter = 0;
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_content);
TableLayout table = (TableLayout) findViewById(R.id.tblLayoutContent);
BufferedReader reader = null;
try {
reader = new BufferedReader(
new InputStreamReader(getAssets().open("round.txt")));
// do reading, usually loop until end of file reading
String mLine;
while ((mLine = reader.readLine()) != null) {
for (int row = 0; row < 10; row++) {
TableRow tblRow = new TableRow(this);
tblRow.setPadding(5, 30, 5, 5);
table.addView(tblRow);
int NUM_COL = 3;
for (int col = 0; col != NUM_COL; col++) {
Button btn = new Button(this);
btn.setText(mLine);
tblRow.addView(btn);
NUM_COL++;
}
}
}
} catch (IOException e) {
//log the exception
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
//log the exception
}
}
}
}
}
Here's an image of my structure:
Well I found the answer. Thank you for pointing me in the right direction.
Here it is
try {
InputStream is = getAssets().open("round.txt");
// We guarantee that the available method returns the total
// size of the asset... of course, this does mean that a single
// asset can't be more than 2 gigs.
int size = is.available();
// Read the entire asset into a local byte buffer.
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
// Convert the buffer into a string.
String text = new String(buffer);
// Finally stick the string into the text view.
// Replace with whatever you need to have the text into.
TextView tv = (TextView)findViewById(R.id.text);
tv.setText(text);
} catch (IOException e) {
// Should never happen!
throw new RuntimeException(e);
}
Reworked the code and this is the one that works.
BufferedReader reader;
try {
InputStream is = getAssets().open("round.txt");
reader = new BufferedReader(new InputStreamReader(is));
// Finally stick the string into the text of the button.
TableLayout table = (TableLayout) findViewById(R.id.tblLayoutContent);
String line = reader.readLine();
int lineLength = (line.length());
while (line != null){
TableRow tblRow = new TableRow(this);
tblRow.setPadding(5, 30, 5, 5);
table.addView(tblRow);
for (int col = 0; col < NUM_COL; col++) {
Button btn = new Button(this);
btn.setTextSize(14);
btn.setText(line);
tblRow.addView(btn);
line = reader.readLine();
}
};
} catch (IOException e) {
// Should never happen!
throw new RuntimeException(e);
}
}
U can read from a file, line by line like this:
String filename = "filename.txt";
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new InputStreamReader
(this.getAssets().open(filename), StandardCharsets.UTF_8));
String line;
while ((line = bufferedReader.readLine()) != null) {
//add the lines in some arraylist if you want to set them.
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
In Kotlin , we can do as
val string = requireContext().assets.open("round.txt").bufferedReader().use {
it.readText()
}
Try this... add getResources()
reader = new BufferedReader(
new InputStreamReader(getResources().getAssets().open("round.txt")));

Using Buffered Reader and Writer to remove blank lines in a textfile; however I always leave the last line blank

I have a BufferedReaderand BufferedRriter that reads and removes blank lines from a textfile. It all works fine except I cannot for the life of me find a good solution to end it.
public static void cleanUpData(){
File inputFile = new File("C:\\Users\\student\\workspace\\EmployeePunch\\src\\EmployeeData.txt"); // Your file
File tempFile = new File("C:\\Users\\student\\workspace\\EmployeePunch\\src\\EmployeeDataNew.txt");// temp file
BufferedReader reader = null;
BufferedWriter writer = null;
try{
reader = new BufferedReader(new FileReader(inputFile));
writer = new BufferedWriter(new FileWriter(tempFile,true));
String currentLine;
while((currentLine = reader.readLine()) != null) {
if(currentLine.equals("")) continue;
writer.append(currentLine+"\n");
}
}
catch (IOException e) {
e.printStackTrace();
}finally{
try {
reader.close();
inputFile.delete();
writer.close();
boolean successful = tempFile.renameTo(inputFile);
System.out.println(successful);
validateEmployee();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
I know the reason it is doing it is being of the writer.append(currentLine+"\n"); but what would be another solution to stop at the last line?
Is there a way to know when I am right before the last line so to avoid using the +"\n"?
Don't add a newline after every output line. Instead, insert a a newLine before every line after the first line.
For example, you can replace your while loop with the following code:
boolean needsNewLine = false;
while((currentLine = reader.readLine()) != null) {
if(currentLine.equals("")) continue;
if (!needsNewLine) {
needsNewLine = true;
} else {
writer.append('\n');
}
writer.append(currentLine);
}

Java Reading Text File Yielding Null Result

Here I have some code where I create an ActionListener for a JCheckBox.
Once the user clicks the JCheckBox the actionlistener is triggered and this code runs.
First I check whether they are selecting it or deselecting the check box and I input this into the text file. I re-input the checkbox's text plus a 0 if the user is deselecting it or a 1 if they are selecting it.
However, when I try to read through my file using a loop it seems to only result in null values. Here is an excerpt of exactly what I'm talking about.
for (int i = 0; i < notes.length; i++) {
String text;
try {
text = br.readLine();
if (text.contains(s)) {
brw.write(s + "0");
brw.newLine();
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
The notes.length is an array that contains the amount of lines of my file. I've also tried changing that to an int that held line the line count. No change, still didn't work. If I print out "text" and "s" I get the checkbox's text value followed by "null". The text variable should have a value.
I get a NullPointerException..
selected
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at SideNotes$2.actionPerformed(SideNotes.java:86)
By the way.. when I read the file in other places I do not get a NullPointerException. It returns the line just fine.
Full code:
File file = new File("notes.txt");
if (file.exists()) {
try {
FileInputStream fs = new FileInputStream(file);
final BufferedReader br = new BufferedReader(
new InputStreamReader(fs));
final BufferedReader reader = new BufferedReader(
new FileReader("notes.txt"));
FileWriter writer = new FileWriter(file, true);
final BufferedWriter brw = new BufferedWriter(writer);
while (reader.readLine() != null)
lines++;
// reader.close();
notes = new JCheckBox[lines];
ActionListener al = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JCheckBox checkbox = (JCheckBox) e.getSource();
if (checkbox.isSelected()) {
System.out.println("selected");
String s = checkbox.getText();
for (int i = 0; i < notes.length; i++) {
String text;
try {
text = br.readLine();
if (text.contains(s)) {
brw.write(s + "0");
brw.newLine();
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
} else {
System.out.println("deselected");
String s = checkbox.getText();
for (int i = 0; i < notes.length; i++) {
String text;
try {
text = br.readLine();
if (text.contains(s)) {
brw.write(s + "0");
brw.newLine();
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
};
Why am I getting a null result, and how do I fix it?
I think this one should be :
String s = checkBox.getText().toString();
so you can set the value of text as String.

Java File cannot be deleted nor renamed

See my code below:
I can write a key and a string in one line of a file. If the key already exists I want to overwrite it by creating a new file and fill it with the content of my source file. In the end I am going to delete the old file and rename my temporary file. But it does not work. As you can see I print booleans for deleting and renameTo methods. Both are returned as "false".
I read in some other Threads that I have to close all Readers and Writers that are in contact with my file in order to be able to rename or delete it.
You see my fault?
(Note that some comments are written in german)
public static boolean dini_Set(String filepath, String key, String value) throws IOException
{
if(key.length() <= 0 || value.length() <= 0) return false;
String pfilepath = rootdirectory.concat(filepath);
File pfile = new File(pfilepath);
//dini_Remove(filepath.concat(".part"));
if(dini_Exists(filepath) == false) return false;
// Checkt ob der Key schon existiert
FileReader fr = new FileReader(pfilepath);
BufferedReader br = new BufferedReader(fr);
String ausw;
boolean foundkeybool = false;
while((ausw = br.readLine()) != null)
{
String foundkey = ausw.substring(0,ausw.indexOf("="));
//System.out.println(foundkey);
if(foundkey.equals(key))
{
foundkeybool = true;
System.out.println(foundkeybool);
// Key exists and content has to be overwritten
String newline = key.concat("=").concat(value);
String tmpdir = rootdirectory.concat("tmp.tmp");
File tmp = new File(tmpdir);
tmp.createNewFile();
String currentLine;
FileWriter fw = new FileWriter(tmpdir);
BufferedWriter bw = new BufferedWriter(fw);
br.close();
fr.close();
fr = new FileReader(pfilepath);
br = new BufferedReader(fr);
while((currentLine = br.readLine()) != null)
{
// trim newline when comparing with lineToRemove
String trimmedLine = currentLine.trim();
System.out.println(trimmedLine);
if(trimmedLine.equals(ausw))
{
System.out.println("Austauschen: "+newline);
bw.write(newline);
}
else
{
bw.write(currentLine);
System.out.println("Lassen: "+currentLine);
}
bw.newLine();
}
br.close();
fr.close();
bw.close();
fw.close();
tmp.setWritable(true);
pfile.setWritable(true);
// boolean removed = dini_Remove(filepath);
boolean removed = pfile.delete();
System.out.println("Datei wurde gelöscht: "+removed);
boolean renamed = tmp.renameTo(pfile);
System.out.println("Datei umbenannt: "+renamed);
break;
}
}
// if key does now exists we can create a new one
if(foundkeybool == false)
{
FileWriter fw = new FileWriter(pfilepath,true);
BufferedWriter bw = new BufferedWriter(fw);
bw.write(key.concat("=").concat(value));
bw.newLine();
bw.close();
}
return true;
}
This may not fix your problem, but it will get you closer.
You MUST ensure that any resource that you open is closed properly. Currently in your code, if, for some reason, an exception is thrown, none of your resources will be closed.
Even if you're not interested in dealing with the exception within the method, you should still wrap the file access code within a try-finally block
FileReader fr = null;
BufferedReader br = null;
try {
fr = new FileReader(pfilepath);
br = new BufferedReader(fr);
//...//
} finally {
try {
br.close();
} catch (Exception exp) {
}
try {
fr.close();
} catch (Exception exp) {
}
}
You may find that you only need to close the BufferedReader and it should be calling close on it's child Reader, but I'm paranoid about ensuring that everything is clean
If you are using Java 7, you may wish to take a look at The try-with-resources Statement
Updated
I'm not sure your code makes sense. Basically, what you should be doing, is reading the entire source file and writing it the temp location (as you don't know in advance if the key needs to be updated, and you would probably need to read the source file anyway to find out).
Once this has being completed, if you made changes to the temp file, delete the source file and rename the temp file into it's place.
You code seems mighty inefficient to me...
Okai, I want to give you a brief update about the code.
I changed it this way and for now it is working as it should.
Do you have some more things I can change to optimize the code?
public static boolean dini_Set(String filepath, String key, String value) throws IOException
{
if(key.length() <= 0 || value.length() <= 0) return false;
String pfilepath = rootdirectory.concat(filepath);
File pfile = new File(pfilepath);
//dini_Remove(filepath.concat(".part"));
if(dini_Exists(filepath) == false) return false;
// Checkt ob der Key schon existiert
boolean foundkeybool = false;
File tmp = null;
try(BufferedReader br = new BufferedReader(new FileReader(pfilepath)))
{
String ausw;
while((ausw = br.readLine()) != null)
{
String foundkey = ausw.substring(0,ausw.indexOf("="));
System.out.println(foundkey);
if(foundkey.equals(key))
{
foundkeybool = true;
System.out.println(foundkeybool);
//Key exists and content has to be overwritten
String newline = key.concat("=").concat(value);
String tmpdir = rootdirectory.concat("tmp.tmp");
tmp = new File(tmpdir);
tmp.createNewFile();
String currentLine;
try(BufferedWriter bw = new BufferedWriter(new FileWriter(tmpdir)))
{
try(BufferedReader br2 = new BufferedReader(new FileReader(pfilepath)))
{
while((currentLine = br2.readLine()) != null)
{
//trim newline when comparing with lineToRemove
String trimmedLine = currentLine.trim();
System.out.println(trimmedLine);
if(trimmedLine.equals(ausw))
{
System.out.println("Austauschen: "+newline);
bw.write(newline);
}
else
{
bw.write(currentLine);
System.out.println("Lassen: "+currentLine);
}
bw.newLine();
}
}
}
break;
}
}
}
if(foundkeybool == true)
{
tmp.setWritable(true);
pfile.setWritable(true);
//boolean removed = dini_Remove(filepath);
boolean removed = pfile.delete();
System.out.println("Datei wurde gelöscht: "+removed);
boolean renamed = tmp.renameTo(pfile);
System.out.println("Datei umbenannt: "+renamed);
}
else //(foundkeybool == false) if key does now exists we can create a new one
{
try(BufferedWriter bw = new BufferedWriter(new FileWriter(pfilepath,true)))
{
bw.write(key.concat("=").concat(value));
bw.newLine();
bw.close();
}
}
return true;
}

Categories

Resources