I have a text file with serialized objects written it. The file contains data like this -
line[com.high.3449%]
line[com.high.58850?]
line[com.high.47646%]
I want to read this and store 1 by 1 in an arraylist. But when I read it I am just able to read the first line which is line[com.high.3449%] but not everything. I am using below logic to read -
List<MyData> myobjects1 = new ArrayList<MyData>();
List<MyData> myobjects2 = new ArrayList<MyData>();
FileInputStream fin = new FileInputStream("/storage/200B-431F/Documents/MyData.txt");
ois = new ObjectInputStream(fin);
try {
myobjects1 = (List<MyData>) ois.readObject();
while (myobjects1 != null) {
myobjects2.addAll(myobjects1);
Log.d("hi", "second arraylist " + myobjects2);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
ois.close();
server.sendData(myobjects2);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch(Exception e) {}
Can someone help me how to read all the data and store in the arraylist myobjects2?
The issue seems to be related to your loop when you read back the data. There is no need to loop (it will loop forever)
Instead of
myobjects1 = (List<MyData>) ois.readObject();
while (myobjects1 != null) {
myobjects2.addAll(myobjects1);
...
You should use
myobjects1 = (List<MyData>) ois.readObject();
if (myobjects1 != null) {
myobjects2.addAll(myobjects1);
}
If you want to loop through the myobjects you need to use something like
for (MyData myData : myobjects1) {
myobjects2.add(myData);
}
Am adding the code I used to test the answer.
package test;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
public class LoadFileObject {
public static class MyData implements Serializable {
private String line, content;
public MyData(String line, String content) {
setLine(line);
setContent(content);
}
public String getLine() {
return line;
}
public void setLine(String line) {
this.line = line;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content= content;
}
public String toString() {
return (line+content);
}
}
#Test
public void doWork() throws Exception {
List<MyData> myobjects1 = new ArrayList<MyData>();
myobjects1.add(new MyData("l1", "content1"));
myobjects1.add(new MyData("l2", "content2"));
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("mydata.txt"));
oos.writeObject(myobjects1);
oos.close();
List<MyData> myobjects2 = new ArrayList<MyData>();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("mydata.txt"));
myobjects2 = (List<MyData>) ois.readObject();
System.out.println("read:" + myobjects2.size());
for (MyData myData : myobjects2) {
System.out.println("myData line:" + myData.getLine() + " content:" + myData.getContent());
}
}
}
try this :
FileInputStream fis = null;
BufferedReader reader = null;
try {
fis = new FileInputStream("/storage/200B-431F/Documents/MyData.txt/CPU.txt");
reader = new BufferedReader(new InputStreamReader(fis));
System.out.println("Reading File line by line using BufferedReader");
String line = reader.readLine();
while(line != null){
System.out.println(line);
line = reader.readLine();
// here line variable will hold the data for each line of your text file
// i.e you can add the string to the arrayList here
myObjects2.add(line);
}
} catch (FileNotFoundException ex) {
}
catch (IOException ex) {
}
Related
Suppose that file.txt only contains "Hello". When I compile the Java code, it shows
Error: This method must return a result of type java.lang.String in line5.
When I print in readTxt function, that works, it can show "Hello".
I already check the result is correctly String type, but it also shows compiler error. How can I make the return value to the main function?
import java.io.*;
import java.lang.String;
public class ReadTxtFile {
public static String readTxt(String filePath) {
try {
File file = new File(filePath);
if(file.isFile() && file.exists()) {
InputStreamReader isr = new InputStreamReader(new FileInputStream(file), "utf-8");
BufferedReader br = new BufferedReader(isr);
String lineTxt = null;
lineTxt = br.readLine();
//System.out.println(lineTxt);
br.close();
return lineTxt;
} else {
}
} catch (Exception e) {
}
}
public static void main(String[] args) {
String filePath = "C:/file.txt";
String fileword = readTxt(filePath);
System.out.println(fileword);
}
}
You promised to return a String from your method, so you now have to do that. The only way around that promise is to throw an exception.
public static String readTxt(String filePath) { // Here you promise to return a String
try {
...
if(file.isFile() && file.exists()) {
...
return lineTxt; // Here you return a String as promised
} else {
// Here you're missing either return or throw
}
} catch (Exception e) {
// Here you're missing either return or throw
}
}
This is fundamentally a design problem - what should your method do if it fails to read the file for some reason? Return a special string like "Error"? Return null? Fail and throw and exception? Something else?
Answer that to yourself and it will be clear to you how to fix the code.
There are several best practices you should follow that will prevent future error. I have tried to cover them. Not saying mine is the perfect one, but you will get the idea.
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class StackOverFlow {
public static void main(String[] args) {
try {
String sText = getFileText("C:/file.txt");
System.out.println("Text is: " + sText);
} catch (FileNotFoundException e) {
System.out.println("File not Found");
} catch (IOException e) {
System.out.println("#Error while reading text: " + e.getMessage());
}
}
private static String getFileText(String filePath) throws FileNotFoundException, IOException {
File file = new File(filePath);
String line = null;
StringBuilder stringBuilder = new StringBuilder();
String ls = System.getProperty("line.separator");
BufferedReader reader = null;
try{
reader = new BufferedReader(new FileReader(file));
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
stringBuilder.append(ls);
}
reader.close();
}finally {
reader.close();
}
return new String(stringBuilder);
}
}
I am making a Library System in Java, I am able to add new books, view and save them. However, I now want to search them using a Search window box. The saved data is located in a txt file. I would like to search for specific fields. I am thinking of implementing a linear search method, but am not too sure how to do it.
package bcu.storer;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import bcu.model.Book;
public class BookStorer {
public void StoreBooks(ArrayList<Book> booksList) throws IOException
{
FileWriter fw = new FileWriter(".\\data\\books.txt");
BufferedWriter bw = new BufferedWriter(fw);
try {
for (int i = 0; i < booksList.size(); i++)
{
String content = "";
Book book = booksList.get(i);
content += book.getIsbn()+"::";
content += book.getTitle()+"::";
content += book.getAuthor()+"::";
content += book.getPublisher()+"::";
content += book.getPudDate()+"::";
content += book.getStatus()+"\n";
bw.write(content);
}
System.out.println("Complete storing all books!");
} catch (IOException ae) {
ae.printStackTrace();
} finally {
try {
if (bw != null)
bw.close();
if (fw != null)
fw.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
This is the code which stores the book information to the TXT file, I would like to access this data in the search results.
I'm not sure if that's what you want. I help it helps you.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class ReadFromFile {
private static final String FILENAME = "pathToFile";
public static void main(String[] args) {
BufferedReader br = null;
FileReader fr = null;
try {
//br = new BufferedReader(new FileReader(FILENAME));
fr = new FileReader(FILENAME);
br = new BufferedReader(fr);
String sCurrentLine;
while ((sCurrentLine = br.readLine()) != null) {
Array[String] tmpBook = sCurrentLine.split("::");
Book myBook = new Book(tmpBook(0),tmpBook(1),tmpBook(2), tmpBook(3), tmpBook(4), tmpBook(5))
/*Check here if is the book you are looking for*/
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null)
br.close();
if (fr != null)
fr.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
This will read the file, line by line, and will get all the lines that match the search criteria.
This map provides the position (column) of each of the fields in the Book object.
private static Map<String, Integer> fieldToPositionMap = ImmutableMap.<String, Integer>builder()
.put("Isbn", 0)
.put("Title", 1)
.put("Author", 2)
.put("Publisher", 3)
.put("PudDate", 4)
.put("Status", 5)
.build();
Note: I have used GoogleGuava's ImmutableMap to construct the map, but you can build it in a traditional way.
The search method takes the name of the field and the value that you want to search for (eg, Isbn=ABC or Publisher=XYZ) and returns all the rows (as Book objects) that match the criteria.
public List<Book> search(String fieldName, String fieldValue) {
try {
return Files.lines(Paths.get("/path/to/txt/file")) //reads a file line by line
.filter(line -> {
String[] blocks = line.split("::");
//filter (choose) a row if value of the searched field equals the provided value
return blocks[fieldToPositionMap.get(fieldName)].equals(fieldValue);
})
.map(this::deserialize) //convert the line to a Book object
.collect(Collectors.toList()); //collect the result
} catch (IOException e) {
throw new RuntimeException(e);
}
}
//To convert a row from the file to a Book instance
private Book deserialize(String line) {
String [] blocks = line.split("::");
Book book = new Book();
book.setIsbn(blocks[0]);
book.setTitle(blocks[1]);
book.setAuthor(blocks[2]);
book.setPublisher(blocks[3]);
book.setPudDate(blocks[4]);
book.setStaus(blocks[5]);
}
Note: You might have to handle cases when a row does not have all fields
I have 2 class files in my simple project - sorry another newbee here!
But I get a compilation error on the last part where I am trying to print the hopefully stored configuration settings from a file for my project that will be referred to throughout the project.
The file is just rows of values like this 'ButtonConfig,8,V,NULL,bunny,mpg'
I basically want to be able to used the contents of this arraylist to dynamicly set up the configuration of a Raspberry pi GPO pins i.e. for the above values button attached to GPO pin 8 will play video (V) "<..other value...>_bunny.mpg"
Any help greatly appreciated - just telling me why I can't access the getExtension method would be nice!
Contents of first java file is -
package bpunit;
public class ButtonConfig {
private String keyword;
private String gponumber;
private String buttontype;
private String language;
private String filename;
private String extension;
public String getKeyword() {
return keyword;
}
public void setKeyword(String keyword) {
this.keyword = keyword;
}
...............
public String getExtension() {
return extension;
}
public void setExtension(String extension) {
this.extension = extension;
}
}
The second contains this -
package bpunit;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Read_ini {
public void Read_ini_toObject()
{
String csvFileToRead = "configs/BPUnit.properties";
BufferedReader br = null;
String line;
String splitBy = ",";
List buttonList = new ArrayList();
try {
br = new BufferedReader(new FileReader(csvFileToRead));
while ((line = br.readLine()) != null) {
// split on comma(',')
String[] buttonconfig = line.split(splitBy);
// create button object to store values
ButtonConfig buttonObject = new ButtonConfig();
// add values from csv to car object
buttonObject.setKeyword(buttonconfig[0]);
buttonObject.setGponumber(buttonconfig[1]);
buttonObject.setButtontype(buttonconfig[2]);
buttonObject.setLanguage(buttonconfig[3]);
buttonObject.setFilename(buttonconfig[4]);
buttonObject.setExtension(buttonconfig[5]);
// adding button object to a list
buttonList.add(buttonObject);
}
// print values stored in buttonList
printButtonList(buttonList);
} catch (FileNotFoundException e) {
System.out.print(e);
} catch (IOException e) {
System.out.print(e);
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
System.out.print(e);
}
}
}
}
public void printButtonList(List buttonListToPrint) {
for (int i = 0; i < buttonListToPrint.size(); i++) {
// THE LINE BELOW FAILS - getExtension() does not exist
// and all other attempts give me pointer references
//instead of the text //
System.out.println(buttonListToPrint.get(i).getExtension());
}
}
}
You have to add the parameterized type ButtonConfig to your ArrayList. It ends up being List<ButtonConfig> instead of just List.
package bpunit;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Read_ini {
public void Read_ini_toObject()
{
String csvFileToRead = "configs/BPUnit.properties";
BufferedReader br = null;
String line;
String splitBy = ",";
List<ButtonConfig> buttonList = new ArrayList<ButtonConfig>();
try {
br = new BufferedReader(new FileReader(csvFileToRead));
while ((line = br.readLine()) != null) {
// split on comma(',')
String[] buttonconfig = line.split(splitBy);
// create button object to store values
ButtonConfig buttonObject = new ButtonConfig();
// add values from csv to car object
buttonObject.setKeyword(buttonconfig[0]);
buttonObject.setGponumber(buttonconfig[1]);
buttonObject.setButtontype(buttonconfig[2]);
buttonObject.setLanguage(buttonconfig[3]);
buttonObject.setFilename(buttonconfig[4]);
buttonObject.setExtension(buttonconfig[5]);
// adding button object to a list
buttonList.add(buttonObject);
}
// print values stored in buttonList
printButtonList(buttonList);
} catch (FileNotFoundException e) {
System.out.print(e);
} catch (IOException e) {
System.out.print(e);
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
System.out.print(e);
}
}
}
}
public void printButtonList(List<ButtonConfig> buttonListToPrint) {
for (int i = 0; i < buttonListToPrint.size(); i++) {
// THE LINE BELOW FAILS - getExtension() does not exist
// and all other attempts give me pointer references
//instead of the text //
System.out.println(buttonListToPrint.get(i).getExtension());
}
}
}
The reason why the compilation is failing is because when you add an object to the ArrayList it is upcast as an object of the class Object. Now when you extract it you simply have to typecast it back to the original type. so all you have to do is this :
public void printButtonList(List buttonListToPrint) {
for (int i = 0; i < buttonListToPrint.size(); i++) {
// THE LINE BELOW FAILS - getExtension() does not exist
// and all other attempts give me pointer references
//instead of the text
ButtonConfig buttonObject =(ButtonConfig)buttonListToPrint.get(i);
System.out.println(buttonObject.getExtension());
}
}
Or as mentioned in the comments and answers above you could use generics and create an List of type ButtonConfig
public void Read_ini_toObject()
{
String csvFileToRead = "configs/BPUnit.properties";
BufferedReader br = null;
String line;
String splitBy = ",";
List<ButtonConfig> buttonList = new ArrayList<ButtonConfig>();
and pass it in the function printButtonList
public void printButtonList(List<ButtonConfig> buttonListToPrint) {
for (int i = 0; i < buttonListToPrint.size(); i++) {
// THE LINE BELOW FAILS - getExtension() does not exist
// and all other attempts give me pointer references
//instead of the text
System.out.println(buttonListToPrint.get(i).getExtension());
}
}
I am trying to load in a file from my computer with all the words of the dictionary in the file.
When I load the file i put the words into an array of strings.
I then want to eliminate all words that have more than 9 letters in them.
I then want to save the words that are 9 letters or smaller into another separate text file.
When i try to open the new file it only has 9 words in it, yet my print to the screen on eclipse will print the all words of nine or less letters.
Can anyone help!
This is a program that was gave to me as part of the question.
import java.io.*;
public class FileIO{
public String[] load(String file) {
File aFile = new File(file);
StringBuffer contents = new StringBuffer();
BufferedReader input = null;
try {
input = new BufferedReader( new FileReader(aFile) );
String line = null;
int i = 0;
while (( line = input.readLine()) != null){
contents.append(line);
i++;
contents.append(System.getProperty("line.separator"));
}
}
catch (FileNotFoundException ex) {
System.out.println("Can't find the file - are you sure the file is in this location: "+file);
ex.printStackTrace();
}
catch (IOException ex){
System.out.println("Input output exception while processing file");
ex.printStackTrace();
}
finally {
try {
if (input!= null) {
input.close();
}
}
catch (IOException ex) {
System.out.println("Input output exception while processing file");
ex.printStackTrace();
}
}
String[] array = contents.toString().split("\n");
for(String s: array){
s.trim();
}
return array;
}
public void save(String file, String[] array) throws FileNotFoundException, IOException {
File aFile = new File(file);
Writer output = null;
try {
output = new BufferedWriter( new FileWriter(aFile) );
for(int i=0;i<array.length;i++){
output.write( array[i] );
output.write(System.getProperty("line.separator"));
}
}
finally {
if (output != null) output.close();
}
}
}
this is the class i tried to use
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.*;
public class countdown{
public static void main(String args[]){
FileIO reader = new FileIO();
Scanner scan = new Scanner(System.in);
String[] inputs = reader.load("C:/Users/Sony/Documents/dict.csv"); //Reading the File as a String array from a file called dict
String[] input = new String[inputs.length]; //new String array for strings less than 9 letters
for(int i=0;i<inputs.length;i++){
if(inputs[i].length()<=9) { //if string of index i is less than 9
input[i]=inputs[i]; //add it to the new array called input
System.out.println(input[i]); //print line to check
}
}
try{
reader.save("C:/Users/Sony/Documents/dictnew.csv",input);
//this is where i save it to the new file called dictnew.
}catch (Exception e){
System.out.println(e.getClass());
}
}
}
After reading how you want you can split rest logic remains same.
package com.srijan.playground;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class FilterLengthWords {
public static void main(String[] args) throws IOException {
BufferedReader br = null;
BufferedWriter bw = null;
try {
br = new BufferedReader(new FileReader("Sample.txt"));
bw = new BufferedWriter(new FileWriter("Output.txt"));
String tmp = null;
while((tmp=br.readLine())!=null) {
if(tmp.length()<=9) {
bw.write(tmp);
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(br!=null) {
br.close();
br=null;
}
if(bw!=null){
bw.close();
bw=null;
}
}
}
}
Thanks
my research on google-search and stackoverflow regarding this problem didn't resolve it.
i'd like to show you a snipped of my Datastructure:
there's a class, called "SequenceHolder" => this one carries an:
ArrayList<SequenceData> data;
within the Sequenceholder, there is a function to call the serialization:
public void writeSequenceList() throws FileNotFoundException, IOException {
FileOutputStream fout = new FileOutputStream(path);
ObjectOutputStream oout = new ObjectOutputStream(fout);
oout.writeObject(data);
oout.close();
fout.close();
}
The class SequenceObject has following fields: (this one is on the top, where i start the serialization)
private ArrayList<SequenceModel> recordedSequenceData;
private String sequenceUrl;
while the SequenceModel is defined like this:
private Object sequenceRawData;
private boolean isProcessedByRequest;
The sequenceRawdata objects are basically two other classes (containing Strings only)!
every class of this "trail" implements the interface "Serializable".
this is the deserialization:
public ArrayList<SequenceData> loadSequenceList() throws FileNotFoundException, IOException, ClassNotFoundException {
FileInputStream fileIn = new FileInputStream(path);
ObjectInputStream in = new ObjectInputStream(fileIn);
this.data = (ArrayList<SequenceData>) in.readObject();
in.close();
fileIn.close();
return data; // load from de-serialization
}
after a deserialization of the SequenceObject, i'll only retrieve the "sequenceUrl", but no recordedSequenceData.
Is there a trick to do this?!
It came just up to my mind, to extend some classes with the ObjectOutputStream and call the writingprocess with "this" explicitly in every class - but yeah, i am not sure if thats a good idead.
What do you mean by "The sequenceRawdata objects are basically two other classes (containing Strings only)!" because when I try to run the same program :
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
class SequenceModel implements Serializable
{
public SequenceModel(Object a, boolean b)
{
sequenceRawData = a;
isProcessedByRequest = b;
}
public String toString()
{
return (String)sequenceRawData + isProcessedByRequest + " SeqModel ";
}
private Object sequenceRawData;
private boolean isProcessedByRequest;
}
class SequenceData implements Serializable
{
public SequenceData(ArrayList<SequenceModel> a, String b)
{
recordedSequenceData = a;
sequenceUrl = b;
}
public String toString()
{
return recordedSequenceData + sequenceUrl + " SeqData ";
}
private ArrayList<SequenceModel> recordedSequenceData;
private String sequenceUrl;
}
class SequenceHolder implements Serializable
{
ArrayList<SequenceData> data;
public String toString()
{
return data + " SeqHol ";
}
public SequenceHolder(ArrayList<SequenceData> a)
{
data = a;
}
public void writeSequenceList() throws FileNotFoundException, IOException {
FileOutputStream fout = new FileOutputStream(Test.file);
ObjectOutputStream oout = new ObjectOutputStream(fout);
oout.writeObject(data);
oout.close();
fout.close();
}
public ArrayList<SequenceData> loadSequenceList() throws FileNotFoundException, IOException, ClassNotFoundException {
FileInputStream fileIn = new FileInputStream(Test.file);
ObjectInputStream in = new ObjectInputStream(fileIn);
this.data = (ArrayList<SequenceData>) in.readObject();
in.close();
fileIn.close();
return data; // load from de-serialization
}
}
public class Test
{
public static File file = new File("abc.txt");
public static void main(String[] args)
{
SequenceModel obj = new SequenceModel("abc", false);
ArrayList list = new ArrayList(); list.add(obj);
SequenceData obh = new SequenceData(list, "str");
ArrayList l2 = new ArrayList();
l2.add(obh);
SequenceHolder obi = new SequenceHolder(l2);
try {
obi.writeSequenceList();
System.out.println(obi.loadSequenceList());
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
it is able to serialize and deserialize both and there is no problem.
Output it is printing is : [[abcfalse SeqModel ]str SeqData ] which includes everything as desired.
Please let me know if I am missing anything.