unable to understand how to find end of file - java

I'm writing a code where I've to read current line and next line. If next line contains some string, I need to delete current line.
But when I do it, once it reaches the EOF, it is showing me null pointer exception.
Below is my code.
private static void cleanUpTempFile(File temp) throws IOException {
FileReader fr = new FileReader(temp);
BufferedReader temp_in = new BufferedReader(fr);
String tempStr, tempStr1 = null;
int i = 0;
for (String next, footnotes = temp_in.readLine(); footnotes != null; footnotes = next) {
next = temp_in.readLine();
try {
if (next.contains("pb") && (next != null)) {
tempStr = footnotes;
tempStr1 = tempStr;
tempStr = tempStr1.replace(tempStr1, "");
footnotes = tempStr;
}
} catch (Exception e) {
System.out.println(e);
}
System.out.println(footnotes);
}
temp_in.close();
}
It is throwing me error since when it comes since, when it comes to end, current line is showing last line and next points to next line which is null. How can I sort this.
Also, whenever there is a replace done, and empty line is created, Is there a way that I can stop creating a new line.
I tried adding the below code in my if
tempStr1 = tempStr;
footnotes = tempStr1.replace("\\s", "");
But this doesn't seem working.
Tried with the below code and my console prints null.
private static void cleanUpTempFile(File temp) throws IOException {
FileReader fr = new FileReader(temp);
BufferedReader temp_in = new BufferedReader(fr);
String tempStr, tempStr1 = null;
String footnotes;
while ((footnotes = temp_in.readLine()) != null) {
String next;
while ((next = temp_in.readLine()) != null) {
if (next.contains("pb")) {
tempStr = footnotes;
tempStr1 = tempStr;
tempStr = tempStr1.replace(tempStr1, "");
footnotes = tempStr;
}
}
}
System.out.println(footnotes);
temp_in.close();
}
Thanks.

As suggested by Baldurian you can check this by using Scanner#hasNextLine():
Scanner input = new Scanner(new File(filename));
String prevLine = input.nextLine();
while(input.hasNextLine())
{
String nextLine = input.nextLine();
//do some stuff
prevLine = nextLine;
}

Along with checking if the file exists and appending to it if so you should also have a .hasNextLine() conditional.

Related

How would I best implement a system that prevents the calling of one method, if said method has already been applied?

One part of what I'm working on requires me to prompt the user to choose if they want a .txt file to be organized via the last name alphabetically or vice versa. I've gotten all the code down so my trouble isn't in editing or changing my .txt file but I want to prevent the user from selecting last name if last name has already been applied or vice versa. Basically, like a light switch, where if it's on (organized first name) then the only option is off (organize by last name).
I'm not sure how to best describe this, but if you run the code firstOrLast.equals("last") then run firstOrLast.equals("first") it will do nothing, but you can continue to run "last". I believe my error involves how I assign the boolean when checking what its current value is.
public static boolean isFirst = true;
public static void sortPatientsByName(String firstOrLast, String fileName) throws IOException {
if (firstOrLast.equals("last")) { // CODE FOR LAST NAME, FIRST NAME
if (isFirst == true) { // BOOLEAN TO SEE IF OTHER HAS BEEN CALLED
FileReader fileReader = new FileReader(fileName);
BufferedReader bufferedReader = new BufferedReader(fileReader);
String[] words = null;
ArrayList<String> sortName = new ArrayList<>();
String line = "";
while ((line = bufferedReader.readLine()) != null) {
words = line.split(" ");
String swapFirst = "";
String swapLast = "";
String holdBirth = "";
String holdStatus = "";
swapFirst = words[1];
swapLast = words[0];
holdBirth = words[2];
holdStatus = words[3];
line = swapFirst + " " + swapLast + " " + holdBirth + " " + holdStatus;
sortName.add(line);
}
bufferedReader.close();
Collections.sort(sortName);
FileWriter writer = new FileWriter(fileName);
for (int i = 0; i < sortName.size(); i++) {
writer.write(sortName.get(i));
writer.write("\r\n");
}
writer.close();
//isFirst = false; // NOT SURE IF ASSIGNING BOOLEAN FALSE SHOULD BE CALLED WITHIN
}
isFirst = false;
}
if (firstOrLast.equals("first")) { // CODE FOR FIRST NAME, LAST NAME
if (isFirst == false) { // BOOLEAN TO SEE IF OTHER HAS BEEN CALLED
FileReader fileReader = new FileReader(fileName);
BufferedReader bufferedReader = new BufferedReader(fileReader);
ArrayList<String> sortName = new ArrayList<>();
String line = "";
while ((line = bufferedReader.readLine()) != null) {
sortName.add(line);
}
bufferedReader.close();
Collections.sort(sortName);
FileWriter writer = new FileWriter(fileName);
for (int i = 0; i < sortName.size(); i++) {
writer.write(sortName.get(i));
writer.write("\r\n");
}
writer.close();
//isFirst = true;
}
isFirst = true;
}
}
The issue here is that when you start your code the only thing that can run is the "first" part.
You can try to change the boolean type to Boolean and set it to null like :
static Boolean isFirst = null
Then in your code you check if boolean is null (for the first time is run) and at then end of the run set it to the corresponding value:
static Boolean isFirst = null;
public static void sortPatientsByName() throws IOException {
if (firstOrLast.equals("last")) {
if (isFirt == null || isFirst == false) {
***
isFirst = false;
}
if (firstOrLast.equals("first")) {
if (isFirt == null || isFirst == true) {
***
isFirst = true;
}
}
That way when you'll run it it pass the first time due to null and after it can only pass to the first one it pass through
One cleaner way would be to create a enum for the different possibility

Decipher encrypted text file

I have deciphering method that should open a test file with encrypted text, then read and decipher each line of text that I read in from the input file. The text file is called mystery.txt.
I can get the method to work when only inputting single characters but I can't get it to work where I open the .txt file and decipher line by line.
Dechiphering method:
public static String cipherDecipherString(String text)
{
// These are global. Put here for space saving
private static final String crypt1 = "cipherabdfgjk";
private static final String crypt2 = "lmnoqstuvwxyz";
// declare variables
int i, j;
boolean found = false;
String temp="" ; // empty String to hold converted text
readFile();
for (i = 0; i < text.length(); i++) // look at every chracter in text
{
found = false;
if ((j = crypt1.indexOf(text.charAt(i))) > -1) // is char in crypt1?
{
found = true; // yes!
temp = temp + crypt2.charAt(j); // add the cipher character to temp
}
else if ((j = crypt2.indexOf(text.charAt(i))) > -1) // and so on
{
found = true;
temp = temp + crypt1.charAt(j);
}
if (! found) // to deal with cases where char is NOT in crypt2 or 2
{
temp = temp + text.charAt(i); // just copy across the character
}
}
return temp;
}
My readFile method:
public static void readFile()
{
FileReader fileReader = null;
BufferedReader bufferedReader = null;
String InputFileName;
String nextLine;
clrscr();
System.out.println("Please enter the name of the file that is to be READ (e.g. aFile.txt: ");
InputFileName = Genio.getString();
try
{
fileReader = new FileReader(InputFileName);
bufferedReader = new BufferedReader(fileReader);
nextLine = bufferedReader.readLine();
while (nextLine != null)
{
System.out.println(nextLine);
nextLine = bufferedReader.readLine();
}
}
catch (IOException e)
{
System.out.println("Sorry, there has been a problem opening or reading from the file");
}
finally
{
if (bufferedReader != null)
{
try
{
bufferedReader.close();
}
catch (IOException e)
{
System.out.println("An error occurred when attempting to close the file");
}
}
}
}
Now I thought that I would just be able to call my readFile() method then go into the decipher code and it let work it's way through the file but I cannot get it to work at all.
In readFile() you aren't doing anything with the lines you read, you aren't calling cipherDecipherString() anywhere.
Edit: You can add all the lines from the file to an array and return the array from the fuction. Then iterate through that array and decipher line by line
Change the readFile() return type to ArrayList;
ArrayList<String> textLines = new ArrayList<>();
while(nextLine != null) {
textLines.add(nextLine);
nextLine = bufferedReader.readLine();
}
return textLines;
Then in cipherDecipherString() call readFile().
ArrayList<String> textLines = readFile();

Reading from two files at the same time

Suppose we have two files as f1 and f2.
Also suppose that there is a function named comparision(File f1,File f2).
This function will get the two files as arguments and take the first character(word) from f1 and compare it with all the characters in the f2 until the end, picking second ones and doing it until end as first and etc.
My question is: How can I implement this? Do I need to know the EOF ? And if so, how to get it?
Assume that files are plain text (.txt) and every word is in one line.
as an example:
f1:
I
am
new
to
java
f2:
java
is
a
programing
language
Here's the code:
static void comparision(File f, File g) throws Exception
{
Set<String> text = new LinkedHashSet<String>();
BufferedReader br = new BufferedReader(new FileReader(g));
for(String line;(line = br.readLine()) != null;)
text.add(line.trim().toString());
if(text==null)
return;
BufferedReader br = new BufferedReader(new FileReader(f));
String keyword = br.readLine();
if (keyword != null) {
Pattern p = Pattern.compile(keyword, Pattern.CASE_INSENSITIVE);
StringBuffer test = new StringBuffer(text.toString());
matcher = p.matcher(test);
if (!matcher.hitEnd()) {
total++;
if (matcher.find()) {
//do sth
}
}
}
}
edit by jcolebrand
Something to think about, we need program flow that looks like this (psuedocode)
function(file1,file2) throws exceptions{
ArrayList<string> list1, list2; //somebody said we should use an ArrayList ;-)
string readinTempValue = null;
br = BufferedReader(file1) //we are already using a BufferredReader
readinTempValue = br.ReadLine();
//this is a loop structure
while (readinTempValue != null){ //trust me on this one
//we need to get the string into the array list....
//how can we ADD the value to list1
readinTempValue = br.ReadLine(); //trust me on this one
}
br = BufferedReader(file2) //we are already using a BufferredReader
readinTempValue = br.ReadLine();
//this is a loop structure
while (readinTempValue != null){ //trust me on this one
//we need to get the string into the array list....
//how can we ADD the value to list2
readinTempValue = br.ReadLine(); //trust me on this one
}
foreach(value in list1){
foreach(value in list2){
compare value from list 1 to value from list 2
}
}
}
Simple basic algorithm (can be fine tuned based upon WHY you want to compare)
Read the second file and create a HashSet "hs"
for each word "w" in file 1
if(hs.contains(w))
{
w is present in the second file
}
else
{
w is not present in the second file
}
modifications to OP's code
static int comparision(File f, File g) throws Exception
{
int occurences = -1;
Set<String> text = new HashSet<String>();
BufferedReader br = new BufferedReader(new FileReader(g));
String line = br.readLine();
while (line != null)
{
String trimmedLine = line.trim();
if (trimmedLine.length() > 0)
{
text.add(trimmedLine.toString());
}
line = br.readLine();
}
if (text.isEmpty())
{
// file 1 doesn't contain any useful data
return -1;
}
br = new BufferedReader(new FileReader(f));
String keyword = br.readLine();
if (keyword != null)
{
String trimmedKeyword = keyword.trim();
if (trimmedKeyword.length() > 0)
{
if (text.contains(trimmedKeyword))
{
occurences++;
}
}
line = br.readLine();
}
return occurences;
}

Find a specific line of a text file (not by line_number) and store it as a new String

I am trying to read a text file in java using FileReader and BufferedReader classes. Following an online tutorial I made two classes, one called ReadFile and one FileData.
Then I tried to extract a small part of the text file (i.e. between lines "ENTITIES" and "ENDSEC"). Finally l would like to tell the program to find a specific line between the above-mentioned and store it as an Xvalue, which I could use later.
I am really struggling to figure out how to do the last part...any help would be very much apprciated!
//FileData Class
package textfiles;
import java.io.IOException;
public class FileData {
public static void main (String[] args) throws IOException {
String file_name = "C:/Point.txt";
try {
ReadFile file = new ReadFile (file_name);
String[] aryLines = file.OpenFile();
int i;
for ( i=0; i < aryLines.length; i++ ) {
System.out.println( aryLines[ i ] ) ;
}
}
catch (IOException e) {
System.out.println(e.getMessage() );
}
}
}
// ReadFile Class
package textfiles;
import java.io.IOException;
import java.io.FileReader;
import java.io.BufferedReader;
import java.lang.String;
public class ReadFile {
private String path;
public ReadFile (String file_path) {
path = file_path;
}
public String[] OpenFile() throws IOException {
FileReader fr = new FileReader (path);
BufferedReader textReader = new BufferedReader (fr);
int numberOfLines = readLines();
String[] textData = new String[numberOfLines];
String nextline = "";
int i;
// String Xvalue;
for (i=0; i < numberOfLines; i++) {
String oneline = textReader.readLine();
int j = 0;
if (oneline.equals("ENTITIES")) {
nextline = oneline;
System.out.println(oneline);
while (!nextline.equals("ENDSEC")) {
nextline = textReader.readLine();
textData[j] = nextline;
// xvalue = ..........
j = j + 1;
i = i+1;
}
}
//textData[i] = textReader.readLine();
}
textReader.close( );
return textData;
}
int readLines() throws IOException {
FileReader file_to_read = new FileReader (path);
BufferedReader bf = new BufferedReader (file_to_read);
String aLine;
int numberOfLines = 0;
while (( aLine = bf.readLine()) != null ) {
numberOfLines ++;
}
bf.close ();
return numberOfLines;
}
}
I don't know what line you are specifically looking for but here are a few methods you might want to use to do such operation:
private static String START_LINE = "ENTITIES";
private static String END_LINE = "ENDSEC";
public static List<String> getSpecificLines(Srting filename) throws IOException{
List<String> specificLines = new LinkedList<String>();
Scanner sc = null;
try {
boolean foundStartLine = false;
boolean foundEndLine = false;
sc = new Scanner(new BufferedReader(new FileReader(filename)));
while (!foundEndLine && sc.hasNext()) {
String line = sc.nextLine();
foundStartLine = foundStartLine || line.equals(START_LINE);
foundEndLine = foundEndLine || line.equals(END_LINE);
if(foundStartLine && !foundEndLine){
specificLines.add(line);
}
}
} finally {
if (sc != null) {
sc.close();
}
}
return specificLines;
}
public static String getSpecificLine(List<String> specificLines){
for(String line : specificLines){
if(isSpecific(line)){
return line;
}
}
return null;
}
public static boolean isSpecific(String line){
// What makes the String special??
}
When I get it right you want to store every line between ENTITIES and ENDSEC?
If yes you could simply define a StringBuffer and append everything which is in between these to keywords.
// This could you would put outside the while loop
StringBuffer xValues = new StringBuffer();
// This would be in the while loop and you append all the lines in the buffer
xValues.append(nextline);
If you want to store more specific data in between these to keywords then you probably need to work with Regular Expressions and get out the data you need and put it into a designed DataStructure (A class you've defined by our own).
And btw. I think you could read the file much easier with the following code:
BufferedReader reader = new BufferedReader(new
InputStreamReader(this.getClass().getResourceAsStream(filename)));
try {
while ((line = reader.readLine()) != null) {
if(line.equals("ENTITIES") {
...
}
} (IOException e) {
System.out.println("IO Exception. Couldn't Read the file!");
}
Then you don't have to read first how many lines the file has. You just start reading till the end :).
EDIT:
I still don't know if I understand that right. So if ENTITIES POINT 10 1333.888 20 333.5555 ENDSEC is one line then you could work with the split(" ") Method.
Let me explain with an example:
String line = "";
String[] parts = line.split(" ");
float xValue = parts[2]; // would store 10
float yValue = parts[3]; // would store 1333.888
float zValue = parts[4]; // would store 20
float ... = parts[5]; // would store 333.5555
EDIT2:
Or is every point (x, y, ..) on another line?!
So the file content is like that:
ENTITIES POINT
10
1333.888 // <-- you want this one as xValue
20
333.5555 // <-- and this one as yvalue?
ENDSEC
BufferedReader reader = new BufferedReader(new
InputStreamReader(this.getClass().getResourceAsStream(filename)));
try {
while ((line = reader.readLine()) != null) {
if(line.equals("ENTITIES") {
// read next line
line = reader.readLine();
if(line.equals("10") {
// read next line to get the value
line = reader.readLine(); // read next line to get the value
float xValue = Float.parseFloat(line);
}
line = reader.readLine();
if(line.equals("20") {
// read next line to get the value
line = reader.readLine();
float yValue = Float.parseFloaT(line);
}
}
} (IOException e) {
System.out.println("IO Exception. Couldn't Read the file!");
}
If you have several ENTITIES in the file you need to create a class which stores the xValue, yValue or you could use the Point class. Then you would create an ArrayList of these Points and just append them..

Mapping Object from file in java

I want map my object from text file, the text file contents are like this :
~
attribute1value
attribute2value
attribute3value
attribute4value
attribute5value
attribute6value
~
attribute1value
attribute2value
attribute3value
attribute4value
attribute5value
attribute6value
...continued same
So for each 5 attributes I want to create new object and map those 6 properties to it(that is not issue), the issue is how can I distinguish lines while reading, how can I get the first group, second group etc . thank you
I suggest using a 3rd-party utility such as Flatworm to handle this for you.
Adapted from here, and assuming there are always 6 properties per object:
You can use java.io.BufferedReader to read a file line by line.
BufferedReader reader = new BufferedReader(new FileReader("/path/to/file.txt"));
String line = null;
int count = 0;
MyObject obj = null;
while ((line = reader.readLine()) != null) {
if(obj == null) obj = new MyObject();
if(count <= 6) {
switch(count) {
case 0: // ignore: handles '~'
break;
case 1: // assign value of line to first property, like:
obj.prop1 = line;
break;
// etc up to case 6
}
count++;
} else {
// here, store object somewhere, then...
obj = null;
count = 0;
}
}
Here is a more flexible approach. We can specify a custom (single-line) delimiter, no delimiter is actually needed at the beginning or at the end of the file (but can be given), the number of lines of a record is flexible. The data is parsed into a simple model which can be used to validate data and create the final objects.
private String recordDelimiter = "~";
public static List<List<String>> parse(Reader reader) {
List<List<String>> result = new ArrayList<List<String>>();
List<String> record = new ArrayList<String>();
boolean isFirstLine = true;
while ((line = reader.readLine()) != null) {
line = line.trim();
if (line.length() == 0) {
continue; // we skip empty lines
}
if (delimiter.equals(line.trim()) {
if (!isFirstLine) {
result.add(record);
record = new ArrayList<String>();
} else {
isFirstLine = false; // we ignore a delimiter in the first line.
}
continue;
}
record.add(line);
isFirstLine = false;
}
if (!result.contains(record))
result.add(record); // in case the last line is not a separator
return result;
}
Primitive code, no exception handling, requires 100% perfect file structure and file which ends in the record delimiter character '~'.
Gives you a start though.
public class Record {
private String field1 = null;
private String field2 = null;
private String field3 = null;
private String field4 = null;
private String field5 = null;
private String field6 = null;
private void read(DataInputStream din) throws IOException, ClassNotFoundException {
BufferedReader reader = new BufferedReader(new InputStreamReader(din));
field1 = reader.readLine();
field2 = reader.readLine();
field3 = reader.readLine();
field4 = reader.readLine();
field5 = reader.readLine();
field6 = reader.readLine();
reader.readLine(); // Skip separator line "~".
}
private static void main(String[] args) throws IOException, ClassNotFoundException {
FileInputStream fin = new FileInputStream("C:\\file.dat");
DataInputStream din = new DataInputStream(fin);
Collection<Record> records = new LinkedList<Record>();
while(0 < din.available()) {
Record record = new Record();
record.read(din);
records.add(record);
}
}
}

Categories