Java BufferedReader acting strange - java

I can't understand for the life of me why bufferedreader is not reading the next line in my file. It keeps returning an empty string. I put the reader in a while loop in the proper format. My text file does not contain any special characters. It only contains numbers and some strings delimited by white spaces. I don't get it.
//Read from file method
public void readFile(File x) throws IOException{
File rFile = x;
String fileLine;
Transaction holder;
int Type;
//This will destroy the current account to add in the new one
//Main.$acct.destroyTrans();
try {
// FileReader reads text files in the default encoding.
FileReader fileReader = new FileReader(rFile);
// Always wrap FileReader in BufferedReader.
BufferedReader bufferedReader = new BufferedReader(fileReader);
//Gathering initial information about account
Main.$acct.setName(bufferedReader.readLine());
Main.$acct.setBalance(Double.parseDouble(bufferedReader.readLine()));
Main.$acct.setTransCount(Integer.parseInt(bufferedReader.readLine()));
Main.$acct.setSC(Double.parseDouble(bufferedReader.readLine()));
//Adding the objects
while((fileLine = bufferedReader.readLine()) != null) {
//Tokenize the String to extract information
StringTokenizer st = new StringTokenizer(fileLine," ");
//Go through each token and put it into an arrayList
ArrayList<String> list = new ArrayList();
while(st.hasMoreTokens()) {
list.add(st.nextToken());
}
//Grab each piece of data
Type = Integer.parseInt(list.get(0));
//Route the proper objects to their proper places
switch(Type){
case 1:
{
holder = new Check(Integer.parseInt(list.get(1)), Type, Double.parseDouble(list.get(3)), Integer.parseInt(list.get(2)));
Main.$acct.addNewTrans(holder);
break;
}
case 2:
{
holder = new Deposit(Integer.parseInt(list.get(1)), Type, Double.parseDouble(list.get(5)), Double.parseDouble(list.get(3)),
Double.parseDouble(list.get(4)));
Main.$acct.addNewTrans(holder);
break;
}
case 3:
{
holder = new Transaction(Integer.parseInt(list.get(1)), Type, Double.parseDouble(list.get(4)));
Main.$acct.addNewTrans(holder);
break;
}
default:
{}
}
//End of switch
}
//End of while loop
bufferedReader.close();
}
//End of Try
//Exception handling portion
catch(FileNotFoundException ex) {
System.out.println(
"Unable to open file '" +
rFile.getName() + "'");
}
catch(IOException ex) {
System.out.println(
"Error reading file '"
+ rFile.getName() + "'");
// Or we could just do this:
// ex.printStackTrace();
}
}
Sample File:
billy
500
4
5
1 0 1 100
3 1 Srv. Chrg. 0.15
2 2 Deposit 100 100 200

Your code is running just fine as long as the input file format and encoding are the standard ones.
Make sure your input file has no redundant line breaks (or an extra line break at the end of the file);
I tested your code with ANSI encoded file, and it worked as expected.
Fix your exception handling to handle general cases - it will help you debug the error.
i.e. do something like this at the end of the method:
} catch(Exception e) {
// Throw the exception here, or print it to the console...
e.printStackTrace();
}
Goodluck!

Related

Regular Expressions to Display Messages from a Text Log File

I'm trying to figure out how to use regular expressions to condense and sort the information I'm getting from this code. Here's the code and I'll explain as I go:
import java.io.*;
import java.util.*;
public class baseline
{
// Class level variables
static Scanner sc = new Scanner(System.in);
public static void main(String[] args) throws IOException,
FileNotFoundException { // Start of main
// Variables
String filename;
// Connecting to the output file with a buffer
PrintWriter outFile = new PrintWriter(
new BufferedWriter(
new FileWriter("chatOutput.log")));
// Get the input file
System.out.print("Please enter full name of the file: ");
filename = sc.next();
// Assign the name of the input file to a file object
File log = new File(filename);
String textLine = null; // Null
String outLine = ""; // Null
BufferedWriter bw = null;
try
{
// assigns the input file to a filereader object
BufferedReader infile = new BufferedReader(new FileReader(log));
sc = new Scanner(log);
while(sc.hasNext())
{
String line=sc.nextLine();
if(line.contains("LANTALK"))
System.out.println(line);
} // End of while
try
{
// Read data from the input file
while((textLine = infile.readLine()) != null)
{
// Print to output file
outLine = textLine;
sc = new Scanner (outLine);
while(sc.hasNext())
{
String line=sc.nextLine();
if(line.contains("LANTALK"))
outFile.printf("%s\n",outLine);
}// end of while
} // end of while
} // end of try
finally // This gets executed even when an exception is thrown
{
infile.close();
outFile.close();
} // End of finally
} // End of try
catch (FileNotFoundException nf) // Goes with first try
{
System.out.println("The file \""+log+"\" was not found");
} // End of catch
catch (IOException ioex) // Goes with second try
{
System.out.println("Error reading the file");
} // End of catch
} // end of main
} // end of class
So I'm reading an input file, getting only the lines that display "LANTALK", and printing them out to another file. And here is a sample of what the output looks like so far:
14:29:39.731 [D] [T:000FEC] [F:LANTALK2C] <CMD>LANMSG</CMD>
<MBXID>922</MBXID><MBXTO>5608</MBXTO><SUBTEXT>LanTalk</SUBTEXT><MOBILEADDR>
</MOBILEADDR><LAP>0</LAP><SMS>0</SMS><MSGTEXT>It is mailing today right?
</MSGTEXT>
14:41:33.703 [D] [T:000FF4] [F:LANTALK2C] <CMD>LANMSG</CMD>
<MBXID>929</MBXID><MBXTO>5601</MBXTO><SUBTEXT>LanTalk</SUBTEXT><MOBILEADDR>
</MOBILEADDR><LAP>0</LAP><SMS>0</SMS><MSGTEXT>Either today or tomorrow -
still waiting to hear. </MSGTEXT>
And what I need is to get all of the characters between <MSGTEXT> and </MSGTEXT> to be able to display the message cleanly. How should I write this into the code to repeat with every "LANTALK" line and still write out correctly? Thanks!
Try it with Jsoup.
Example:
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
....
while(sc.hasNext())
{
String line=sc.nextLine();
if(line.contains("LANTALK")){
Document doc = Jsoup.parse(line);
Element msg = doc.select("MSGTEXT").first();
System.out.println(msg.text());
}
System.out.println(line);
} // End of while
.....
You can find MSGTEXT using a regex:
<MSGTEXT>(.*?)</MSGTEXT>
However, some of the messages contain newlines, which makes this a bit more difficult.
One way to get past this is to read the entire file into a String, and then look for matches.
try {
String text = new String(Files.readAllBytes(Paths.get(log)));
Matcher m = Pattern.compile("<MSGTEXT>(.*?)</MSGTEXT>", Pattern.DOTALL).matcher(text);
while (m.find()) {
System.out.println("Message: " + m.group(1));
}
} catch (IOException e) {
//Handle exception
}
Console output:
Message: It is mailing today right?
Message: Either today or tomorrow -
still waiting to hear.
Keep in mind that if you are dealing with large log files this approach could use a lot of memory.
Also note that parsing XML with regex is generally considered a bad idea; it works fine for now, but if you plan on doing anything more complicated you should use an XML parser as others have suggested.

Scanner reading "\n" or Enter/Return key

So, I'm trying to set up a simple config for a project. The goal here is to read certain values from a file and, if the file does not exist, to write said file. Currently, the creation of the file works fine, but my Scanner is acting a bit funny. When I reach the code
case "resolution": resolution = readConfig.next();
it makes the value of resolution "1024x768\nvsync" whereas it should only be "1024x768". If it were working as I planned, then the next value for
readingConfig = readConfig.next();
at the beginning of my while loop would be "vsync", which my switch statement would then catch and continue editing the values to those of the file.
Why is my Scanner picking up on the "\n" that is the 'enter' to the next line in the text document?
public static void main(String[] args) {
int musicVol = 0;
int soundVol = 0;
String resolution = null;
boolean vsync = false;
Scanner readConfig;
String readingConfig;
File configFile = new File(gameDir + "\\config.txt");
if (configFile.exists() != true) {
try {
configFile.createNewFile();
PrintWriter writer = new PrintWriter(gameDir + "\\config.txt");
writer.write("resolution = 1024x768 \n vsync = true \n music = 100 \n sound = 100");
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
readConfig = new Scanner(configFile);
readConfig.useDelimiter(" = ");
while (readConfig.hasNext()) {
readingConfig = readConfig.next();
switch (readingConfig) {
case "resolution":
resolution = readConfig.next();
break;
case "vsync":
vsync = readConfig.nextBoolean();
break;
case "music":
musicVol = readConfig.nextInt();
break;
case "sound":
soundVol = readConfig.nextInt();
break;
}
}
readConfig.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
Instead of using .hasNext and .next(), you will have to use .hasNextLine() and .nextLine(). I would write this as a comment, but do not have enought rep to comment yet.
You are using next() which will not delimit your lines, try using nextLine() instead:
String nextLine() Advances this scanner past the current line and
returns the input that was skipped.
I'd suggest not using the delimiter, and get the whole line instead as a string, and then split the string to the parts you want.
Something like
String nextLine = readConfig.nextLine();
String[] split = nextLine.split(" = ");
String resolution = split[1]; // just an example
...
Aha, solved!
What this does is pull the entire text file into a String (using Scanner.nextLine() removes the '\n') and then adds the " = " at the end of each line instead. Thus, when the Scanner runs back over the String for the switch, it will already be ignoring the " = " and pull the desired information from the String.
String config = "";
try {
readConfig = new Scanner(configFile);
while (readConfig.hasNext()) {
config += readConfig.nextLine() + " = ";
readConfig = new Scanner(config);
readConfig.useDelimiter(" = ");

program only read last line in .txt file java

I have a problem and don't know what to do. This method is supposed to read all the text in a .txt document. My problem is when the document contains more then one line of text and the program only read the last line. The program don't need to worry about signs like . , : or spaces, but it have to read all the letters. Can anybody help me?
example text
hello my name is
(returns the right result)
hello my
name is
(returns only name is)
private Scanner x;
String readFile(String fileName)
{
try {
x = new Scanner (new File(fileName + (".txt")));
}
catch (Exception e) {
System.out.println("cant open file");
}
while (x.hasNext()) {
read = x.next();
}
return read;
}
It's because when you use read = x.next(), the string in the read object is always being replaced by the text in the next line of the file. Use read += x.next() or read = read.concat(x.next()); instead.
You replace every read with every read(). Also, you didn't close() your Scanner. I would use a try-with-resources and something like,
String readFile(String fileName)
{
String read = "";
try (Scanner x = new Scanner (new File(fileName + (".txt")));) {
while (x.hasNextLine()) {
read += x.nextLine() + System.lineSeparator(); // <-- +=
}
} catch (Exception e) {
System.out.println("cant open file");
}
return read;
}

Read one line of a csv file in Java

I have a csv file that currently has 20 lines of data.
The data contains employee info and is in the following format:
first name, last name, Employee ID
So one line would like this: Emma, Nolan, 2
I know how to write to the file in java and have all 20 lines print to the console, but what I'm not sure how to do is how to get Java to print one specific line to the console.
I also want to take the last employee id number in the last entry and have java add 1 to it one I add new employees. I thinking this needs to be done with a counter just not sure how.
You can do something like this:
BufferedReader reader = new BufferedReader(new FileReader(<<your file>>));
List<String> lines = new ArrayList<>();
String line = null;
while ((line = reader.readLine()) != null) {
lines.add(line);
}
System.out.println(lines.get(0));
With BufferedReader you are able to read lines directly. This example reads the file line by line and stores the lines in an array list. You can access the lines after that by using lines.get(lineNumber).
You can read text from a file one line at a time and then do whatever you want to with that line, print it, compare it, etc...
// Construct a BufferedReader object from the input file
BufferedReader r = new BufferedReader(new FileReader("employeeData.txt"));
int i = 1;
try {
// "Prime" the while loop
String line = r.readLine();
while (line != null) {
// Print a single line of input file to console
System.out.print("Line "+i+": "+line);
// Prepare for next loop iteration
line = r.readLine();
i++;
}
} finally {
// Free up file descriptor resources
r.close();
}
// Remember the next available employee number in a one-up scheme
int nextEmployeeId = i;
BufferedReader reader =new BufferedReader(new FileReader("yourfile.csv"));
String line = "";
while((line=reader.readLine())!=null){
String [] employee =line.trim().split(",");
// if you want to check either it contains some name
//index 0 is first name, index 1 is last name, index 2 is ID
}
Alternatively, If you want more control over read CSV files then u can think about CsvBeanReader that will give you more access over files contents..
Here is an algorithm which I use for reading csv files. The most effective way is to read all the data in the csv file into a 2D array first. It just makes it a lot more flexible to manipulate the data.
That way you can specify which line of the file to print to the console by specifying it in the index of the array and using a for. I.e: System.out.println(employee_Data[1][y]); for record 1. y is the index variable for fields. You would need to use a For Loop of course, to print every element for each line.
By the way, if you want to use the employee data in a larger program, in which it may for example store the data in a database or write to another file, I'd recommend encapsulating this entire code block into a function named Read_CSV_File(), which will return a 2D String array.
My Code
// The return type of this function is a String.
// The CSVFile_path can be for example "employeeData.csv".
public static String[][] Read_CSV_File(String CSVFile_path){
String employee_Data[][];
int x;
int y;
int noofFields;
try{
String line;
BufferedReader in = new BufferedReader(new FileReader(CSVFile_path));
// reading files in specified directory
// This assigns the data to the 2D array
// The program keeps looping through until the line read in by the console contains no data in it i.e. the end of the file.
while ( (( line = in.readLine()) != null ){
String[] current_Record = line.split(",");
if(x == 0) {
// Counts the number of fields in the csv file.
noofFields = current_Record.length();
}
for (String str : values) {
employee_Data[x][y] = str;
System.out.print(", "+employee_Data[x][y]);
// The field index variable, y is incremented in every loop.
y = y + 1;
}
// The record index variable, x is incremented in every loop.
x = x + 1;
}
// This frees up the BufferedReader file descriptor resources
in.close();
/* If an error occurs, it is caught by the catch statement and an error message
* is generated and displayed to the user.
*/
}catch( IOException ioException ) {
System.out.println("Exception: "+ioException);
}
// This prints to console the specific line of your choice
System.out.println(("Employee 1:);
for(y = 0; y < noofFields ; y++){
// Prints out all fields of record 1
System.out.print(employee_Data[1][y]+", ");
}
return employee_Data;
}
For reading large file,
log.debug("****************Start Reading CSV File*******");
copyFile(inputCSVFile);
StringBuilder stringBuilder = new StringBuilder();
String line= "";
BufferedReader brOldFile = null;
try {
String inputfile = inputCSVFile;
log.info("inputfile:" + inputfile);
brOldFile = new BufferedReader(new FileReader(inputfile));
while ((line = brOldFile.readLine()) != null) {
//line = replaceSpecialChar(line);
/*do your stuff here*/
stringBuilder.append(line);
stringBuilder.append("\n");
}
log.debug("****************End reading CSV File**************");
} catch (Exception e) {
log.error(" exception in readStaffInfoCSVFile ", e);
}finally {
if(null != brOldFile) {
try {
brOldFile.close();
} catch (IOException e) {
}
}
}
return stringBuilder.toString();

How do I make my java code search only for a to z and 0 to 9

My java code takes almost 10-15minutes to run (Input file is 7200+ lines long list of query). How do I make it run in short time to get same results?
How do I make my code to search only for aA to zZ and 0 to 9??
If I don't do #2, some characters in my output are shown as "?". How do I solve this issue?
// no parameters are used in the main method
public static void main(String[] args) {
// assumes a text file named test.txt in a folder under the C:\file\test.txt
Scanner s = null;
BufferedWriter out = null;
try {
// create a scanner to read from the text file test.txt
FileInputStream fstream = new FileInputStream("C:\\user\\query.txt");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
// Write to the file
out = new BufferedWriter(new FileWriter("C:\\user\\outputquery.txt"));
// keep getting the next String from the text, separated by white space
// and print each token in a line in the output file
//while (s.hasNext()) {
// String token = s.next();
// System.out.println(token);
// out.write(token + "\r\n");
//}
String strLine="";
String str="";
while ((strLine = br.readLine()) != null) {
str+=strLine;
}
String st=str.replaceAll(" ", "");
char[]third =st.toCharArray();
System.out.println("Character Total");
for(int counter =0;counter<third.length;counter++){
//String ch= "a";
char ch= third[counter];
int count=0;
for ( int i=0; i<third.length; i++){
// if (ch=="a")
if (ch==third[i])
count++;
}
boolean flag=false;
for(int j=counter-1;j>=0;j--){
//if(ch=="b")
if(ch==third[j])
flag=true;
}
if(!flag){
System.out.println(ch+" "+count);
out.write(ch+" "+count);
}
}
// close the output file
out.close();
} catch (IOException e) {
// print any error messages
System.out.println(e.getMessage());
}
// optional to close the scanner here, the close can occur at the end of the code
finally {
if (s != null) {
// close the input file
s.close();
}
}
}
For something like this I would NOT recommend java though it entirely possible it is much easier with GAWK or something similar. GAWK also has java like syntax so its easy to pick up. You should check it out.
SO isn't really the place to ask such a broad how-do-I-do-this-question but I will refer you to the following page on regular expression and text match in Java. Also, check out the Javadocs for regexes.
If you follow that link you should get what you want, else you could post a more specific question back on SO.

Categories