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
Related
I have successfully added Csv reading functionality to my application. The setup that work is I have a base class called CSVReader. For each csv file, I create A new Class and it extends from CSVReader. The setup I am currently working on is to have only one class that can be used for any csv file. SO far my code seems to make sense, but clearly is not working therefore I need to fix something.
Here is the base CSVReader
package com.kbs.utilities.csvReader;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
public class CSVReader {
public ArrayList<String[]> readCsvFile(String filePath, boolean headerExists) { //Transfers info from CsvFile to an arraylist of string arrays
String line = "";
BufferedReader br = null;
ArrayList<String[]> arrayClone = new ArrayList<String[]>(); //Container to store contents of String array
try {
FileReader fileReader = new FileReader(filePath); //creates file reader object in the specified csv FIle
br = new BufferedReader(fileReader);
if(headerExists) { //if CSVFile has header then read the first line and put it into a variable
String headerLine = br.readLine();
headerLine.chars(); //pointless line of code, just here to remove the warning of unused variable
}
while((line = br.readLine())!= null) {
String[] currentRow = line.split(",");
arrayClone.add(currentRow);
}
} catch (FileNotFoundException e) {
// Error handling statement for throwing exception in case File isn't found
e.printStackTrace();
} catch(IOException e) {
//// Error handling statement for throwing exception in case File can't be accessed using BufferedReader object
e.printStackTrace();
}
finally {
if(br != null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return arrayClone;
}
}
This is the Class that extends CSVReader and is used to initiate the data from the specified csv
public class InitializeCSV extends CSVReader{
public ArrayList<Object> initCSV() {
String csvFile = "C:\\Users\\kamalu\\Desktop\\Developer\\misc\\sandbox\\kbs-petshop\\trunk\\WebContent\\WEB-INF\\data\\"+csvFileName+".csv";
boolean header = true;
ArrayList<String[]> csvStringArray = readCsvFile(csvFile, header); /
ArrayList<Object> list = new ArrayList<Object>();
for(String[] iteration : csvStringArray) {
Object[] iterationCopy = (Object[]) new Object();//Initializing using the array[] constructor
list.add(iterationCopy);
}
return list;
}
}
I've been stuck on this problem for a few weeks now with no avail.
I am saving the contents of an array-list to a text file so that when the user opens the activity, the array list loads itself up for the user.
When i try to read the text file, and add the contents to the array-list, I get the following input inside the arraylist "Java.io.ObjectInputStream#b37391"
My array list will then look like this
[hello , leon, java.io.ObjectInputStream#b373791]
How can I read the text from the text file and display its contents on the array list
I have supplied the code used below, I have read many tutorials and stackoverflow questions but nothing seems to work. Some advice will be greatly appreciated.
try {
File f = new File(getFilesDir(), "anxfile.txt");
FileInputStream readtheting = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(readtheting);
ois.readObject();
arrayList.add(String.valueOf(ois));
adapter.notifyDataSetChanged();
ois.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Could you use this for reading:
List<String> strings = Files.readAllLines(new File(getFilesDir(), "anxfile.txt").toPath());
and this one for writing:
Files.write(new File(getFilesDir(), "anxfile.txt").toPath(), <someArray>);
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
After importing these then:
public class ReadFile{
public static void main(String[] args){
try {
BufferedReader reader = new BufferedReader(new FileReader("C:\\Users\\tmotswagole\\My Documents\\Example.txt"));
List<String> lines = new ArrayList<String>();
String line = null;
while ((line = reader.readLine()) != null)
{
lines.add(line);
}
reader.close();
for (int i =0; i<lines.size(); i++) {
String[] items = lines.get(i).split("", 1);
for (String s: items) {
System.out.println(s);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
This is how you would execute that code fully
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 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) {
}
I need to make my program read a file, then take the numbers in the string and sort them into an array. I can get my program to read the file and put it to a string, but that's where I'm stuck. All the numbers are on different lines in the file, but appear as one long number in the string. This is what I have so far:
public static void main(String[] args) {
String ipt1;
Scanner fileInput;
File inFile = new File("input1.dat");
try {
fileInput = new Scanner(inFile);
//Reads file contents
while (fileInput.hasNext()) {
ipt1 = fileInput.next();
System.out.print(ipt1);
}
fileInput.close();
}
catch (FileNotFoundException e) {
System.out.println(e);
}
}
I recommend reading the values in as numeric types using fileInput.nextInt() or whatever type you want them, putting them in an array and using a built in sort like Arrays.sort. Unless I'm missing a more subtle point about the question.
If your task is just to get input from some file and you're sure the file has integers, use an ArrayList.
import java.util.*;
Scanner fileInput;
ArrayList<Double>ipt1 = new ArrayList<Double>();
File inFile = new File("input1.dat");
try {
fileInput = new Scanner(inFile);
//Reads file contents
while (fileInput.hasNext()){
ipt1.add(fileInput.nextDouble()); //Adds the next Double to the ArrayList
System.out.print(ipt1.get(ipt1.size()-1)); //Prints out what you just got.
}
fileInput.close();
}
catch (FileNotFoundException e){
System.out.println(e);
}
//Sorting time
//This uses the built-in Array sorting.
Collections.sort(ipt1);
However, if you DO need to come up with a simple array in the end, but CAN use ArrayLists, you can add the following:
Double actualResult[] = new Double[ipt1.size()]; //Declare array
for(int i = 0; i < ipt1.size(); ++i){
actualResult[i] = ipt1.get(i);
}
Arrays.sort(actualResult[]);
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
public class SortNumberFromFile {
public static void main(String[] args) throws IOException {
BufferedReader br = null;
try {
System.out.println("Started at " + LocalDateTime.now());
br = new BufferedReader(new FileReader("/folder/fileName.csv"));//Read data from file named /folder/fileName.csv
List<Long> collect = br.lines().mapToLong(a -> Long.parseLong(a)).boxed().collect(Collectors.toList());//Collect all read data in list object
Collections.sort(collect);//Sort the data
writeRecordsToFile(collect, "/folder/fileName.txt");//Write sorted data to file named /folder/fileName.txt
System.out.println("Ended at " + LocalDateTime.now());
}
finally {
br.close();
}
}
public static <T> void writeRecordsToFile(Collection<? extends T> items, String filePath) {
BufferedWriter writer = null;
File file = new File(filePath);
try {
if(!file.exists()) {
file.getParentFile().mkdirs();
file.createNewFile();
}
writer = new BufferedWriter(new FileWriter(filePath, true));
if(items != null && items.size() > 0) {
for(T eachItem : items) {
if(eachItem != null) {
writer.write(eachItem.toString());
writer.newLine();
}
}
}
} catch (IOException ex) {
}finally {
try {
writer.close();
} catch (IOException e) {
}
}
}
}