java program to conditionally read lines from file - java

I'm new to coding in Java. I put together this piece of code to read all lines between the "Start" and "End" tag in the following text file.
Start
hi
hello
how
are
you
doing?
End
My program is as follows....
package test;
import java.io.*;
public class ReadSecurities {
public static int countLines(String filename) throws IOException {
InputStream is = new BufferedInputStream(new FileInputStream(filename));
try {
byte[] c = new byte[1024];
int count = 0;
int readChars = 0;
boolean empty = true;
while ((readChars = is.read(c)) != -1) {
empty = false;
for (int i = 0; i < readChars; ++i) {
if (c[i] == '\n') {
++count;
}
}
}
return (count == 0 && !empty) ? 1 : count;
} finally {
is.close();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
FileInputStream in = new FileInputStream("U:\\Read101.txt");
FileOutputStream out = new FileOutputStream("U:\\write101.txt");
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out));
BufferedReader br = new BufferedReader(new InputStreamReader(in));
for (int i=1; i<=countLines("U:\\Read101.txt"); i++) {
String line=br.readLine();
while (line.contains("Start")) {
for (int j=i; j<=countLines("U:\\Read101.txt"); j++) {
String line2=br.readLine();
System.out.println(line2);
if(line2.contains("End")) break;
else {
bw.write(line2);
bw.newLine();
}
bw.close();
} break;
}
}
br.close();
}
catch (Exception e) { }
finally { }
}
}
The program reads only the first two lines "hi hello" as though the if condition does not exist. I have a feeling the mistake is very basic, but please correct me.

String line;
do{ line = br.readLine(); }
while( null != line && !line.equals("Start"));
if ( line.equals("Start") ) { // in case of EOF before "Start" we have to skip the rest!
do{
line = br.readLine();
if ( line.equals("End") ) break;
// TODO write to other file
}while(null != line )
}
Should be as easy as that. I left out creation / destruction of resources and proper Exception handling for brevity.
But please do at least log exceptions!
EDIT:
If EOF is encountered before Start, you have to skip the copy step!

You make one crucial mistake in your code: you don't handle the exceptions correctly. Two things:
never catch Exception. Either catch just one type of Exception or specify a list of exceptions you want to catch. In your case, a simple IOException would suffice.
Never leave a catch-block empty. Either throw a new exception, return a value or - in your case - print the exception with e.printStackTrace().
When you do these two things, you will notice that your code throws an IOException, because you close your bw-Stream too early. Move the bw.close() down to where br.close() is.
Now, when you have done that, your code is almost working. The only thing is - you now get a NullPointerException. This is because you don't change your line after all entries are read. The easy fix to this is change from
while(line.equals("Start")) { ...
to
if(line.equals("Start")) { ...
Also, there are some other not-so-neat things in your code, but I will leave it for now - experience comes with time.

For Java 8:
List<String> stopWords = Arrays.asList("Start", "End");
try (BufferedReader reader = new BufferedReader(input))) {
List<String> lines = reader.lines()
.map(String::trim)
.filter(s -> !StringUtils.isEmpty(s) && !stopWords.contains(s))
.collect(Collectors.toList());
}

Related

Is my readers and writers in this method not closing properly?

When I delete a record first before inserting a new record, I can do it, and after deleting I can add new record. But if I insert a new record first then my delete function is not working. Based on my research, it's mainly because the input/output is not closed properly but I have already done that, please take a look at my source code thank you.
Insert record
public void RegCustomer()
{
try
{
File F = new File("Customer.txt");
FileWriter fw = new FileWriter(F, true);
BufferedWriter bw = new BufferedWriter(fw);
PrintWriter pw = new PrintWriter(bw);
//PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(F, true)));
pw.println(this.Name+","+this.CheckInDate+","+this.CheckOutDate+","+this.Floor+","+this.RoomID+","+this.ICNumber+","+this.Contact+","+this.Email);
pw.flush();
pw.close();
fw.close();
bw.close();
}
catch(Exception e)
{
}
}
Delete Record
public boolean delcus(String Target)
{
boolean success = false;
File F = new File("Customer.txt");
File Ftc = new File("Temp.txt");
try
{
FileReader fr = new FileReader(F);
BufferedReader br = new BufferedReader(fr);
PrintWriter pr = new PrintWriter(Ftc);
String line = br.readLine();
while (line!=null)
{
String[] wordsinLine = line.split(",");
if (wordsinLine[0].equals(Target))
{
}
else
{
pr.println(line);
success = true;
}
line = br.readLine();
}
if (success)
{
pr.flush();
pr.close();
br.close();
fr.close();
}
}
catch (Exception e)
{
}
F.delete();
File dump = new File("Customer.txt");
Ftc.renameTo(dump);
return success;
}
I have another method that checks for several conditions before triggering the insert method.
public int checkroom()
{
int check = 0;
int ciDay = this.CheckInDate/10000;
int ciMonth = (this.CheckInDate/100)%100;
int coDay = this.CheckOutDate/10000;
int days = coDay - ciDay;
String name;
int Dbcid;
int Dbcod;
int DbFloor;
int DbRoomID;
try
{
File F = new File("Customer.txt");
FileReader Fr = new FileReader(F);
BufferedReader Reader = new BufferedReader(Fr);
Scanner Sc = new Scanner(Reader);
Sc.useDelimiter("[,\n]");
while(Sc.hasNext())
{
name = Sc.next();
Dbcid = Sc.nextInt();
Dbcod = Sc.nextInt();
DbFloor = Sc.nextInt();
DbRoomID = Sc.nextInt();
if (days <= 7)
{
if (DbFloor == this.Floor && DbRoomID == this.RoomID)
{
int DbcidDay = Dbcid/10000;
int DbcidMonth = (Dbcid/100)%100;
int DbcodDay = Dbcod/10000;
if(ciMonth == DbcidMonth)
{
if (ciDay >= DbcidDay && ciDay < DbcodDay)
{
check = 2;
}
else if (coDay >= DbcidDay && coDay < DbcodDay)
{
check = 3;
}
else if (ciDay <= DbcidDay && coDay >= DbcodDay)
{
check = 4;
}
else
{
check = 1;
}
}
else
{
check = 1;
}
}
else
{
check =1;
}
}
else
{
check =5;
}
}
if(check > 0)
{
Sc.close();
Reader.close();
Fr.close();
}
}
catch (Exception e)
{
}
return check;
}
There are a few issues I can see:
You need to close your streams in a finally clause (or, better still, use a try-with-resource). Otherwise, if an exception is thrown that interrupts the normal program flow, your stream will not be closed immediately.
You should only close the outermost stream object (so e.g. your BufferedReader, but not the FileReader)
You are swallowing exceptions. At least do a printStackTrace() on the exceptions you catch so you can see if any are actually thrown.
Avoid methods like File.delete() that don't throw exceptions in the case of an error. Instead, use the equivalent methods on the Files.class, which throw exceptions in the event of an error.
Incidentally, although it's not an issue as such, you don't need to call flush() just before close()-- the latter automatically flushes before closing.

Java - Read large .txt data file in batch size of 10

I have a large data file say dataset.txt where data is in the format -
1683492079 kyra maharashtra 18/04/2017 10:16:17
1644073389 pam delhi 18/04/2017 10:16:17
.......
The fields are id, name, state, and timestamp.
I have around 50,000 lines of data in the .txt data file.
My requirement is to read the data from this data file in batch size of 10.
So in first batch I need to read from 0 to 9th elements. Next batch from 10th to 19th elements and so on...
Using BufferedReader I have managed to read the whole file:
import java.io.*;
public class ReadDataFile {
public static void main(String args[]) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("dataset.txt"));
String line;
while((line = br.readLine())!= null)
{
System.out.println(line);
}
br.close();
}
}
But my requirement is to read the file in batch size of 10. I am new to Java so would really appreciate if some one can help me in simple terms.
As per #GhostCat answer - this what I have got -
public class ReadDataFile {
public static void main(String args[]) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("dataSetExample.txt"));
readBatch(br,10);
}
public static void readBatch(BufferedReader reader, int batchSize) throws IOException {
List<String> result = new ArrayList<>();
for (int i = 0; i < batchSize; i++) {
String line = reader.readLine();
if (line != null) {
// result.add(line);
System.out.println(line);
}
}
// return result;
return ;
}
}
The file is read in the readBatch method so how do I know in the main method that the end of file is reached to call the next 10 records? Kindly help.
Your requirements aren't really clear; but something simple to get you started:
A) your main method shouldn't do any reading; it just prepare that BufferedReader object
B) you use that reader with a method like:
private static List<String> readBatch(Reader reader, int batchSize) throws IOException {
List<String> result = new ArrayList<>();
for (int i = 0; i < batchSize; i++) {
String line = reader.readLine();
if (line != null) {
result.add(line);
} else {
return result;
}
}
return result;
}
To be used in your main:
BufferedReader reader = ...
int batchSize = 10;
boolean moreLines = true;
while (moreLines) {
List<String> batch = readBatch(reader, batchSize);
... do something with that list
if (batch.size() < batchSize) {
moreLines = false;
}
This is meant as "suggestion" how you could approach this. Things missing from my answer: probably you should use a distinct class, and do parsing right there (and return a List<DataClass> instead of moving around those raw "line strings".
And of course: 50000 lines isn't really much of data. Unless we are talking an embedded device, there is really not much point regarding "batch style".
And finally: the term batch processing has a very distinct meaning; also in Java, and if you intend to go there, see here for further reading.
Anybody in need of working example ---
// Create a method to read lines (using buffreader) and should accept the batchsize as argument
private static List<String> readBatch(BufferedReader br, int batchSize) throws IOException {
// Create a List object which will contain your Batch Sized lines
List<String> result = new ArrayList<>();
for (int i = 1; i < batchSize; i++) { // loop thru all your lines
String line = br.readLine();
if (line != null) {
result.add(line); // add your lines to your (List) result
} else {
return result; // Return your (List) result
}
}
return result; // Return your (List) result
}
public static void main(String[] args) throws IOException {
//input file
BufferedReader br = new BufferedReader(new FileReader("c://ldap//buffreadstream2.csv"));
//output file
BufferedWriter bw = new BufferedWriter(new FileWriter("c://ldap//buffreadstream3.csv"));
// Your Batch size i.e. how many lines you want in your batch
int batchSize = 5; // Define your batchsize here
String line = null;
long batchNumber = 1;
try {
List<String> mylist = null;
while ((line = br.readLine()) != null) { // Do it for your all line in your csv file
bw.write("Batch Number # " + batchNumber + "\n");
System.out.println("Batch Number # " + batchNumber);
bw.write(line + "\n"); // Since br.readLine() reads the next line you have to catch your first line here itself
System.out.println(line); // else you will miss every batchsize number line
// process your First Line here...
mylist = readBatch(br, batchSize); // get/catch your (List) result here as returned from readBatch() method
for (int i = 0; i < mylist.size(); i++) {
System.out.println(mylist.get(i));
// process your lines here...
bw.write(mylist.get(i) + "\n"); // write/process your returned lines
}
batchNumber++;
}
System.out.println("Lines are Successfully copied!");
br.close(); // one you are done .. dont forget to close/flush
br = null; // all
bw.flush(); // your
bw.close(); // BR and
bw = null; // BWs..
} catch (Exception e) {
System.out.println("Exception caught: " + e.getMessage()); // Catch any exception here
}
}

Writing and reading int from file after loop

I'm writing an application that is supposed to act like a cafe clip card. In other words, for every n:th (10 in my case) coffee that a customer purchases, he/she is awarded a free beverage. So, I'm quite done with the loop and I've been working on writing and reading from a file since I need the program to remember where it last left off in order for the customer to be able to close the application once he/she has been in the store. However, I'm having a difficult time figuring out how to write and read from a file, the code I have doesn't seem to output any .txt file. I need the code to have a closing condition, and upon entering this condition, it should write the "count" to a .txt file, and shut down. Once the program is being run the next time it should read from this .txt file so it knows where the count is at.
Here's what I have so far:
public class FelixNeww {
public static void main(String [] args) {
Scanner key;
String entry;
int count = 0;
String password = "knusan01";
while(true) {
System.out.println("Enter password: ");
key = new Scanner(System.in);
entry = key.nextLine();
if(entry.compareTo(password) == 0){
count++;
System.out.println("You're one step closer to a free coffe! You have so far bought "
+ count + " coffe(s)");
}
if(count == 10 && count != 0){
System.out.println("YOU'VE GOT A FREE COFFE!");
count = 0;
}
if(entry.compareTo(password) != 0){
System.out.println("Wrong password! Try again.\n");
}
}
}
public void saveToFile(int count)
{
BufferedWriter bw = null;
try
{
bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File("countStorage.txt"))));
bw.write(count);
}
catch(IOException e)
{
e.printStackTrace();
}
finally
{
if(bw != null)
{
try
{
bw.close();
}
catch(IOException e) {}
}
}
}
public int readFromFile()
{
BufferedReader br = null;
try
{
br = new BufferedReader(newInputStreamReader(newFileInputStream(new File("countStorage.txt"))));
String line = br.readLine();
int count = Integer.parseInt(line);
return count;
}
catch(IOException e)
{
e.printStackTrace();
}
finally
{
if(br != null)
{
try
{
br.close();
}
catch(IOException e) {}
}
}
return 0;
}
}
I see a few problems here. In your readFromFile() method, put a space after the keyword new. I also suggest putting a an absolute path for now (for debugging):
br = new BufferedReader(new InputStreamReader(new FileInputStream(new File("C:\\Temp\\countStorage.txt"))));
In your saveToFile() method, the constructor is wrong. Also put the full path to the file here:
bw = new BufferedWriter(new FileWriter("C:\\Temp\\countStorage.txt"));
Finally, in your saveToFile() method, write the count as a String. Writing it as an int refers to the Unicode character:
bw.write(Integer.toString(count)); //updated per Hunter McMillen
And invoke it...
FelixNeww f = new FelixNeww();
f.saveToFile(44);
System.out.println(f.readFromFile());
You need to invoke readFromFile or saveToFile in the place needed in order to become executed.
I suggest that you call readFromFile on the beginning of the Main method, use its returning contents, and saveToFile in the loop whenever the desired state changes and it needs to be saved.

NullPointerException in Array Build from File

*The following code builds a "2D" array from strings in a text file. At present it is returning a NullPointException error on the line:
temp = thisLine.split(delimiter);
My question is, am I correct in understanding that temp is returning null? If so, why, and how do I add a check for null? I'm rather new to Java, and this is my first attempt at creating a string array of arrays from a file.*
--------Edit--------
The above has been solved.
For those interested below is the code returning a IndexOutOfBoundsException. Specifically the line:
fileContents.set(i, fileContents.get(i).replace(hexLibrary[i][0], hexLibrary[i][1]));
System.out.println("SnR after this");
String[][] hexLibrary; // calls the replaces array from the LibToArray method
hexLibrary = LibToArray();
for(int i=0;i<502;i++){
{
fileContents.set(i, fileContents.get(i).replace(hexLibrary[i][0], hexLibrary[i][1]));
}
}
for (String row : fileContents) {
System.out.println(row); // print array to cmd
}
______________________________
public static String[][] LibToArray()
{
String thisLine;
String[] temp;
String delimiter=",";
String [][] hexLibrary = new String[502][2];
try
{
BufferedReader br= new BufferedReader(new FileReader("hexlibrary.txt"));
for (int j=0; j<502; j++) {
thisLine=br.readLine();
temp = thisLine.split(delimiter);
for (int i = 0; i < 2; i++) {
hexLibrary[j][i]=temp[i];
}
}
}
catch (IOException ex) { // E.H. for try
JOptionPane.showMessageDialog(null, "File not found. Check name and directory."); // error message
}
return hexLibrary;
}
It's more likely that thisLine is null. That will happen if you run out of input before 502 lines are read. If thisLine is not null, then thisLine.split(delimiter) will not return null. You should always check for a null line:
for (int j=0; j<502; j++) {
thisLine=br.readLine();
if (thisLine != null) {
temp = thisLine.split(delimiter);
for (int i = 0; i < 2; i++) {
hexLibrary[j][i]=temp[i];
}
} else {
// report error: premature end of input file
break; // no point in continuing to loop
}
}
Personally, I'd write your method to not assume any particular file length:
public static String[][] LibToArray() {
List<String[]> lines = new ArrayList<>();
String delimiter=",";
try (BufferedReader br= new BufferedReader(new FileReader("hexlibrary.txt"))) {
String line = br.readLine();
while (line != null) {
String[] tmp = line.split(delimiter);
// the next line is dangerous--what if there was only one token?
// should add a check that there were at least 2 elements.
lines.add(new String[] {tmp[0], tmp[1]});
line = br.readLine();
}
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, "File not found. Check name and directory.");
}
String[][] hexLibrary = new String[lines.length][];
lines.toArray(hexLibrary);
return hexLibrary;
}
(The above uses the new Java 7 try-with-resources syntax. If you're using an earlier Java, you should add a finally clause that closes br before the method returns.
If the first line (or any line) of hexlibrary.txt is empty or is not delimited by ","s, the String array returned by split() will probably be null.
To check for that, just add an if-condition around your second for loop, something like this:
if (temp == null) { /* your loop here */ }
You are not checking for end of the stream while reading the file.
Method readLine returns a null if the reader reaches end of the stream. You are hitting this point (null) in the first for loop (before it exits), depending on number of lines in the text file.

More Effective way of picking a part a String from JTextPane?

It's not that my code doesn't work, but I am doubting whether it's very efficient or not. My theory is, that it isn't xD
I have a JTextPane where I have to take the text in it (Making a new line every time the JTextPane got a new line basically), and put it into a .txt file. As I said everything works but I am doubting the implementation of it.
This is the part I am doubting:
public void printLog() {
String s = logTextArea.getText();
ArrayList<String> log = new ArrayList<>();
StringBuilder sb = new StringBuilder();
for(int i = 0; i < s.length(); i++) {
if(s.charAt(i) != '\n') {
sb.append(s.charAt(i));
} else {
log.add(sb.toString());
sb.delete(0, sb.length());
}
}
This is the entire thing just for reference:
public void printLog() {
String s = logTextArea.getText();
ArrayList<String> log = new ArrayList<>();
StringBuilder sb = new StringBuilder();
for(int i = 0; i < s.length(); i++) {
if(s.charAt(i) != '\n') {
sb.append(s.charAt(i));
} else {
log.add(sb.toString());
sb.delete(0, sb.length());
}
}
File f = new File("JServer_Log.txt");
BufferedWriter bw = null;
FileWriter fr = null;
try {
if(f.exists()) {
fr = new FileWriter(f,true);
} else {
fr = new FileWriter(f);
}
} catch (IOException e) {
// Nothing to do really.
}
try {
bw = new BufferedWriter(fr);
Iterator<String> itr = log.iterator();
bw.newLine();
while(itr.hasNext()) {
bw.write(itr.next());
bw.newLine();
}
} catch (IOException e) {
// Nothing to do really. We lost the log?
} finally {
try {
bw.close();
} catch(IOException ioe) {
// The program is closing any way.
}
}
}
It seems that you just need to make sure you use the platform's appropriate newline sequence. You can just say s = s.replace("\n", System.getProperty("line.separator")) and then write that whole string directly to file. In fact, the way I see it, this is all the code you need (except maybe for exception handling, up to you):
public void printLog() throws IOException {
final FileWriter w = new FileWriter("JServer_Log.txt", true);
try {
w.write(logTextArea.getText().replace("\n",
System.getProperty("line.separator")));
} finally { w.close(); }
}
For information, the first code can be replaced by:
List<String> log = Arrays.asList(logTextArea.getText().split("\n"));
but other answers give you a way to replace the whole method.
Why bothering, to use JTextComponents.write(Writer out) throws IOExceptionwrite() this is pretty accepting newline, tabs, e.i. that came from Native OS
use split:
String[] log = s.split("\n");

Categories

Resources