Mapping Object from file in java - 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);
}
}
}

Related

How to i print the result from the readline() method

I’m trying to print out the result from the readline method in a certain format. I also need to add two more if statements, but I’m not sure how to get the code to continue through them if the previous one is true.
public static void main(String[] args) {
String csvFile = args[0]; //name of our csv file
BufferedReader br = null;
String line = "";
String cvsSplitBy = ",";
String[] columns = new String[6];
String columnLine = "";
float notToBeBelow = 12;
try {
br = new BufferedReader(new FileReader(csvFile));
if ((columnLine = br.readLine()) != null) {
columns = columnLine.split(cvsSplitBy);
while ((line = br.readLine()) != null) {
// use comma as separator
String[] routerInfo = line.split(cvsSplitBy);
if (routerInfo[2].toLowerCase().equals("no")) {
float OSVersion = Integer.parseInt(routerInfo[3]);
if(OSVersion >= 12) {
}
}
You can do the following:
if (condition) {
} else {
if (condition2) {}
else {}
if (condition3) {}
else {}
}
You can place an if inside the else of another one.

unable to understand how to find end of file

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.

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..

read and find string from text file

I am loading text file contents to GUI using this code:
try {
BufferedReader br = new BufferedReader(new FileReader ("text.txt"));
String line;
while ((line = br.readLine()) != null) {
if (line.contains("TITLE")) {
jTextField2.setText(line.substring(11, 59));
}
}
in.close();
} catch (Exception e) {
}
Then contents of text.txt file:
JOURNAL journal name A12340001
TITLE Sound, mobility and landscapes of exhibition: radio-guided A12340002
tours at the Science Museum A12340003
AUTHOR authors name A12340004
On jTextField2 I am getting this line: "Sound, mobility and landscapes of exhibition: radio-guided".
The problem is I don't know how to get to jTextField2 the string of next line "tours at the Science Museum".
I would like to ask how can I get both line on jTextField2 i.e. "Sound, mobility and landscapes of exhibition: radio-guided tours at the Science Museum"?
Thank you in advance for any help.
If you are using Java 8 and assuming that the columns have a fixed number of characters, you could something like this:
public static void main(String args[]) throws IOException {
Map<String, String> sections = new HashMap<>();
List<String> content = (List<String>)Files.lines(Paths.get("files/input.txt")).collect(Collectors.toList());
String lastKey = "";
for(String s : content){
String k = s.substring(0, 10).trim();
String v = s.substring(10, s.length()-9).trim();
if(k.equals(""))
k=lastKey;
sections.merge(k, v, String::concat);
lastKey=k;
}
System.out.println(sections.get("TITLE"));
}
The first column is the key. When the keys does not exist, the last key is used. A Map is used to store the keys and the values. When the key already exist, the value is merged with the existing one by concatenation.
This code outputs the expected String: Sound, mobility and landscapes of exhibition: radio-guidedtours at the Science Museum.
EDIT: For Java 7
public static void main(String args[]) {
Map<String, String> sections = new HashMap<>();
String s = "", lastKey="";
try (BufferedReader br = new BufferedReader(new FileReader("files/input.txt"))) {
while ((s = br.readLine()) != null) {
String k = s.substring(0, 10).trim();
String v = s.substring(10, s.length() - 9).trim();
if (k.equals(""))
k = lastKey;
if(sections.containsKey(k))
v = sections.get(k) + v;
sections.put(k,v);
lastKey = k;
}
} catch (IOException e) {
System.err.println("The file could not be found or read");
}
System.out.println(sections.get("TITLE"));
}
Why not create a MyFile class that does the parsing for you, storing key-value-pairs in a Map<String, String>, which you can then access. This will make your code more readable and will be easier to maintain.
Something like the following:
public class MyFile {
private Map<String, String> map;
private String fileName;
public MyFile(String fileName) {
this.map = new HashMap<>();
this.fileName = fileName;
}
public void parse() throws IOException {
BufferedReader br = new BufferedReader(new FileReader(fileName));
String line = br.readLine();
String key = "";
while (line != null) {
//Only update key if the line starts with non-whitespace
key = line.startsWith(" ") ? title : line.substring(0, line.indexOf(" ")).trim();
//If the key is contained in the map, append to the value, otherwise insert a new value
map.put(key, map.get(key) == null ? line.substring(line.indexOf(" "), 59).trim() : map.get(key) + line.substring(line.indexOf(" "), 59).trim());
line = br.readLine();
}
}
public String getEntry(String key) {
return map.get(key);
}
public String toString() {
StringBuilder sb = new StringBuilder();
for (Entry entry:map.entrySet()) {
sb.append(entry.getKey()).append(" : ").append(entry.getValue()).append("\n");
}
return sb.toString();
}
}
This will parse the entire file first. The expected format of the file is:
0 ... 59
[KEY][WHITE SPACE][VALUE]
0 ... 59
[WHITE SPACE][VALUE TO APPEND TO PREVIOUS KEY]
This allows for variable length keys.
Allowing you to handle exceptions separately, and then easily reference the contents of the file like so:
MyFile journalFile = new MyFile("text.txt");
try {
journalFile.parse();
} catch (IOException e) {
System.err.println("Malformed file");
e.printStackTrace();
}
jTextField2.setText(journalFile.getEntry("TITLE"));
An empty (all spaces) first column indicates that a line is the continuation of the previous one. So you can buffer the lines and repeatedly concatenate them, until you get a non-empty first column, and then write/print the whole line.
try {
BufferedReader br = new BufferedReader(new FileReader("text.txt")) ;
String line ;
String fullTitle = "" ;
while ((line = br.readLine()) != null) {
//extract the fields from the line
String heading = line.substring(0, 9) ;
String titleLine = line.substring(10, 69) ;
//does not select on "TITLE", prints all alines
if(heading.equals(" ")) {
fullTitle = fullTitle + titleLine ;
} else {
System.out.println(fullTitle) ;
fullTitle = titleLine ;
}
}
System.out.println(fullTitle) ; //flush the last buffered line
} catch (Exception e) {
System.out.println(e) ;
}
you can do this
First of all read the entire file into a string object.
then get the indexes of the TITLE and AUTHOR
like int start=str.indexOf("TITLE"); and int end=str.indexOf("AUTHOR");
then add the length of TITLE into start index start+="TITLE".length();
and subtract the length of AUTHOR from end index end-="AUTHOR".length();
at last you have the start and end index of text that you want.
so get the text like.
String title=str.subString(start,end);

Categories