So, I've been trying to write a method where I can write fields of Item, Client and Order objects, but as I run this program it gives nullpointexception error and I have no idea what causes it. As an argument, I give path of a file, for example : "C:\Java\info.txt"
Any help regarding this issue would be grateful.
public class IO {
ItemClass item;
ClientClass client;
OrderClass order;
private static HashSet<ItemClass> Items;
private static HashSet<ClientClass> Orders;
private static HashSet<OrderClass> Clients;
public void writeToFile(String directory) throws IOException{
File file = new File(directory);
if(!file.exists()){
file.createNewFile();
}
BufferedWriter bufferedW = new BufferedWriter(new FileWriter(directory));
Orders=getOrders();
Iterator <OrderClass>iteratorOrders = Orders.iterator();
while(iteratorOrders.hasNext()){
order = iteratorOrders.next();
bufferedW.write(order.getIdNumber());
bufferedW.write(order.getPersonalID());
bufferedW.write(order.getAddress());
bufferedW.write(order.getCountry());
bufferedW.write(order.getStatus());
}
Clients=getClients();
Iterator <ClientClass>iteratorClients = Clients.iterator();
while(iteratorClients.hasNext()){
client = iteratorClients.next();
bufferedW.write(client.getPersonalID());
bufferedW.write(client.getName());
bufferedW.write(client.getSurname());
bufferedW.write(client.getBirthDate());
boolean active = client.getIsActive();
boolean activeOrder = client.getHasActiveOrder();
bufferedW.write(String.valueOf(active));
bufferedW.write(String.valueOf(activeOrder));
}
Items=getItems();
Iterator <ItemClass>iteratorItems = Items.iterator();
while(iteratorItems.hasNext()){
item = iteratorItems.next();
bufferedW.write(item.getItemID());
int amount = item.getAmount();
double price = item.getPrice();
bufferedW.write(String.valueOf(amount));
bufferedW.write(String.valueOf(price));
bufferedW.write(item.getName());
bufferedW.write(item.getType());
bufferedW.write(item.getMadeIn());
}
bufferedW.close();
}
}
Related
I am able to create 10 threads. But the problem is when I try to access individual page using those threads in parallel style. I have tried putting the private static PDFTextStripper instance into synchronized block as well. Still I get below exception:
COSStream has been closed and cannot be read. Perhaps its enclosing PDDocument has been closed?
trying to print first word from each page for first 10 pages, but its not working. This is my first experiment with Multithreading and PDF reading. Any help would be much appreciated.
public class ReadPDFFile extends Thread implements FileInstance {
private static String fileLocation;
private static String fileNameIV;
private static String userInput;
private static int userConfidence;
private static int totalPages;
private static ConcurrentHashMap<Integer, List<String>> map = null;
private Iterator<PDDocument> iteratorForThisDoc;
private PDFTextStripperByArea text;
private static PDFTextStripper pdfStrip = null;
private static PDFParser pdParser = null;
private Splitter splitter;
private static int counter=0;
private StringWriter writer;
private static ReentrantLock counterLock = new ReentrantLock(true);
private static PDDocument doc;
private static PDDocument doc2;
private static boolean flag = false;
List<PDDocument> listOfPages;
ReadPDFFile(String filePath, String fileName, String userSearch, int confidence) throws FileNotFoundException{
fileLocation= filePath;
fileNameIV = fileName;
userInput= userSearch;
userConfidence = confidence;
System.out.println("object created");
}
#Override
public void createFileInstance(String filePath, String fileName) {
List<String> list = new ArrayList<String>();
map = new ConcurrentHashMap<Integer, List<String>>();
try(PDDocument document = PDDocument.load(new File(filePath))){
doc = document;
pdfStrip = new PDFTextStripper();
this.splitter = new Splitter();
text = new PDFTextStripperByArea();
document.getClass();
if(!document.isEncrypted()) {
totalPages = document.getNumberOfPages();
System.out.println("Number of pages in this book "+totalPages);
listOfPages = splitter.split(document);
iteratorForThisDoc = listOfPages.iterator();
}
this.createThreads();
/*
* for(int i=0;i<1759;i++) { readThisPage(i, pdfStrip); } flag= true;
*/
}
catch(IOException ie) {
ie.printStackTrace();
}
}
public void createThreads() {
counter=1;
for(int i=0;i<=9;i++) {
ReadPDFFile pdf = new ReadPDFFile();
pdf.setName("Reader"+i);
pdf.start();
}
}
public void run() {
try {
while(counter < 10){
int pgNum= pageCounterReentrant();
readThisPage(pgNum, pdfStrip);
}
doc.close();
}catch(Exception e) {
}
flag= true;
}
public static int getCounter() {
counter= counter+1;
return counter;
}
public static int pageCounterReentrant() {
counterLock.lock();
try {
counter = getCounter();
} finally {
counterLock.unlock();
}
return counter;
}
public static void readThisPage(int pageNum, PDFTextStripper ts) {
counter++;
System.out.println(Thread.currentThread().getName()+" reading page: "+pageNum+", counter: "+counter);
synchronized(ts){
String currentpageContent= new String();
try {
ts.setStartPage(pageNum);
ts.setEndPage(pageNum);
System.out.println("-->"+ts.getPageEnd());
currentpageContent = ts.getText(doc);
currentpageContent = currentpageContent.substring(0, 10);
System.out.println("\n\n "+currentpageContent);
}
/*
* further operations on currentpageContent here
*/
catch(IOException io) {
io.printStackTrace();
}finally {
}
}
}
public static void printFinalResult(ConcurrentHashMap<Integer, List<String>> map) {
/*
* simply display content of ConcurrentHashMap
*/
}
public static void main(String[] args) throws FileNotFoundException {
Scanner sc = new Scanner(System.in);
System.out.println("Search Word");
userInput = sc.nextLine();
System.out.println("Confidence");
userConfidence = sc.nextInt();
ReadPDFFile pef = new ReadPDFFile("file path", "file name",userInput, userConfidence);
pef.createFileInstance("file path ","file name");
if(flag==true)
printFinalResult(map);
}
}
If I read each page in a for loop sequentially using one thread then it is able to print the content, but not with multithreads. You can see that code commented in void createFileInstance(), after this.createThreads(); I wish to get string content of each pdf page individually, using threads, and then perform operation on it. I have the logic to collect each word token into List but before moving ahead, I need to solve this problem.
Your code looks like this:
try(PDDocument document = PDDocument.load(new File(filePath))){
doc = document;
....
this.createThreads();
} // document gets closed here
...
//threads that do text extraction still running here (and using a closed object)
These threads use doc to extract the text (ts.getText(doc)). However at this time, the PDDocument object is already closed due to the usage of try-with-resources, and its streams also closed. Thus the error message "Perhaps its enclosing PDDocument has been closed?".
You should create the thread before closing the document, and waiting for all threads to finish before closing it.
I'd advise against using multithreading on one PDDocument, see PDFBOX-4559. You could create several PDDocuments and then extract on these, or not do it at all. Text extraction works pretty fast in PDFBox (compared to rendering).
I am trying to create a file that stores high scores for a game that I am making. I am using a serializer to write my arrays into a file. The file is created upon running my code but the file is empty (0 bytes). I'm not getting any errors. Can anyone tell me why the file does not contain my data?
public class BestTimes implements Serializable
{
BestTimes[] beginner = new BestTimes[2];
public static void main(String args[]) throws IOException {
BestTimes bestTimes = new BestTimes();
bestTimes.outputToFile();
}
public BestTimes() {
beginner[0] = new BestTimes(1, "John", 10.5);
beginner[1] = new BestTimes(2, "James", 20.3);
}
public int ranking;
public String playerName;
public double time;
public BestTimes(int r, String p, double t)
{
ranking = r;
playerName = p;
time = t;
}
public void outputToFile() throws IOException {
try(FileOutputStream f = new FileOutputStream("bestTimes.txt")) {
ObjectOutputStream s = new ObjectOutputStream(f);
s.writeObject(beginner);
s.flush();
s.close();
} finally {
FileOutputStream f = new FileOutputStream("bestTimes.txt");
f.close();
}
}
}
Of course it's empty. You created a new one in the finally block.
Just remove that code.
I have created an object that i then added into an ArrayList. I then saved this arraylist into a .dat file using ObjectOutputStream. I know that the object has been created correctly because the next screen in the program loads directly from the object and the object can be read correctly from the file afterwards. The issue I am running into is that it appears that the object is saving, but it is not willing to be edited. Instead of editing the object in the arraylist, it is creating a new object and saving it again each time.
The code below shows the save function that is performed every time someone finishes the last screen. I am trying to make it so it will check to see if the student exists already in the array, and if so just edit the object. If the student doesn't exist, I want it to take selectedStudent (the object used for all GUI functions) and add it to the array "students" and write the array to the file, overwriting all previous data.
#SuppressWarnings("unchecked")
public static void saveNew() throws ClassNotFoundException, IOException{
int exists = -1;
try{
FileInputStream fis = new FileInputStream("records.dat");
ObjectInputStream in = new ObjectInputStream(fis);
students = (ArrayList<Student>) in.readObject();
in.close();
fis.close();
}
catch(IOException e){
e.printStackTrace();
}
try{
FileOutputStream fos = new FileOutputStream("records.dat", false);
ObjectOutputStream out = new ObjectOutputStream(fos);
for(int i = 0; i<students.size(); i++){
if(students.get(i).getID().equals(selectedStudent.getID())){
exists = i;
}
}
if(exists<0){
students.add(selectedStudent);
}
else{
students.set(i, selectedStudent);
}
out.writeObject(students);
out.close();
}
catch(IOException e){
e.printStackTrace();
}
}
Edit: I noticed that the variable exists was not being used to search for the object which was mistake number one, but I still have the issue where the saved object will not be changed until the method is called a second time. It seems to find it when it is run again, but when it is run the first time it will just create a new student with the edited name.
For example, the first student is created and saved. A second student is the created and saved. When the second student is being edited (without closing the program and restarting) it will, instead of editing the object in the file, create a new student object with the same information directly below the first. If the edit function is run a second time, the second student file is edited correctly but leaves the first as it was.
For a start I would edit these lines
if(students.get(i).getID().equals(selectedStudent.getID())){
exists = i;
}
to
if(students.get(i).getID().equals(selectedStudent.getID())){
System.out.println ("Got it");
exists = i;
break;
}
just to make sure it is working.
Also, you want to change the use of i to exists
else{
students.set(i, selectedStudent); // change to exists
}
I think you must check your variables (if you're reusing any) and initialization code.
The snippet you've posted seems to be fine, so I can't find the error on it.
Here goes a quite similar code that works. I hope it helps.
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
public class Persistence {
public static void main(String[] args) throws Exception {
File f = new File("records.dat");
// f.delete();
if (!f.exists()){
f.createNewFile();
}
Persistence p = new Persistence();
if (p.peek() == null){
p.init(); //persist an empty list
}
p.saveNew(new Student("ID1","Some Value")); //must insert
p.saveNew(new Student("ID1","Some Other Value")); //must edit
p.saveNew(new Student("ID2","Some Value")); //must insert
ArrayList<Student> list = p.peek();
System.out.println(list);
}
private void save(ArrayList<Student> list) throws Exception{
FileOutputStream fos = new FileOutputStream("records.dat",false);//don't append
ObjectOutputStream out = new ObjectOutputStream(fos);
out.writeObject(list);
out.flush();
out.close();
fos.close();
}
private void init() throws Exception{
save(new ArrayList<Student>());
}
private ArrayList<Student> peek() throws Exception{
FileInputStream fis = new FileInputStream("records.dat");
try{
ObjectInputStream in = new ObjectInputStream(fis);
ArrayList<Student> students = (ArrayList<Student>) in.readObject();
return students;
}catch(EOFException eof){
return null;
}finally{
fis.close();
}
}
public void saveNew(Student s) throws Exception {
ArrayList<Student> students = peek();
int editIndex = -1;
for(int i=0;i<students.size();i++){
if (students.get(i).getID().equals(s.getID())){
editIndex = i;
break;
}
}
if (editIndex != -1){
students.set(editIndex, s); //replace
}else{
students.add(s); //add
}
save(students);
}
}
where
import java.io.Serializable;
public class Student implements Serializable{
private static final long serialVersionUID = 1L;
private String ID;
private String s;
public Student(String ID, String s) {
this.ID = ID;
this.s = s;
}
public String getID() {
return ID;
}
public void setID(String iD) {
ID = iD;
}
public String getS() {
return s;
}
public void setS(String s) {
this.s = s;
}
#Override
public String toString() {
return "Student [ID=" + ID + ", s=" + s + "]";
}
}
I am working on an android project that loads data remotely, saves it into an array (if the data is new), writes it to disk as a serializeable, then reads it from disk to load an ArrayList.
Sometimes the ArrayList populates with the data, sometimes it doesn't and the program crashes.
I receive a runtime exception stating: java.land.ClassCastException: java.lang.String cannot be cast to java.io.ObjectStreamClass.
Sometimes I also receive a java.io.StreamCorruptedException, and sometimes I receive and EOFException.
Going through the exception tree, it seems to be originating from this call:
personsArray = (ArrayList<Person>) in.readObject();
Now, sometimes the data loads fine without issues, most of the time the program crashes.
Here is the code that saves the data to disk:
public static boolean saveFromRemoteSource(Context c, ArrayList<?> source){
//Save context
context = c;
//Save source to local file
File file = context.getFileStreamPath(PERSONS_FILE);
//Status if successful in saving
boolean savedStatus = false;
try {
if(!file.exists()){
file.createNewFile();
}else{
//file already exists so don't do anything
}
//now load the data into the file
FileOutputStream fos = context.openFileOutput(PERSONS_FILE, Context.MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(source);
oos.close();
savedStatus = true;
} catch(IOException e){
e.printStackTrace();
savedStatus = false;
}
return savedStatus;
}
Here is the code that reads the data from disk:
public static boolean loadPersonsArray(Context c){
context = c;
boolean loadStatus = false;
File file = context.getFileStreamPath(PERSONS_FILE);
try{
if(!file.exists()){
file.createNewFile();
}else {
//File is already created, do nothing
}
BufferedReader br = new BufferedReader(new FileReader(file));
if (br.readLine() != null) {
FileInputStream fis = context.openFileInput(PERSONS_FILE);
ObjectInputStream in = new ObjectInputStream(fis);
personsArray = (ArrayList<Person>) in.readObject();
in.close();
fis.close();
loadStatus = true;
}
br.close();
} catch(IOException e){
e.printStackTrace();
Log.d("TAG", "IOException PERSONS_FILE file: " + e);
loadStatus = false;
} catch (ClassNotFoundException e) {
e.printStackTrace();
Log.d("TAG", "ClassNotFoundException PERSONS_FILE file classnotfound: " + e);
}
return loadStatus;
}
This is the Person class:
import java.io.Serializable;
public class Person implements Serializable, Comparable<Person>{
//Person class
private static final long serialVersionUID = 1L;
private String personID;
private String personName;
private boolean displayPerson;
//default constructor
public Person(){
super();
}
public Person(String personID,
String personName,
boolean displayPerson){
super();
this.personID = personID;
this.personName = personName;
this.displayPerson = displayPerson;
}
//Accessor Methods
public String getPersonID(){
return personID;
}
public String getPersonName(){
return personName;
}
public boolean getDisplayPerson(){
return displayPerson;
}
//setter methods
public void setPersonID(String personID){
this.personID = personID;
}
public void setPersonName(String personName){
this.personName = personName;
}
public void setDisplayPerson(boolean displayPerson){
this.displayPerson = displayPerson;
}
#Override
public String toString(){
return this.getPersonName().replaceAll("[^A-Za-z0-9]", "") + this.getDisplayPerson();
}
public int compareTo(Person otherPerson) {
if(!(otherPerson instanceof Person)){
throw new ClassCastException("Not a valid Person object!");
}
Person tempPerson = (Person)otherPerson;
if(this.getPersonName().compareToIgnoreCase(tempPerson.getPersonName()) > 0){
return 1;
}else if(this.getPersonName().compareToIgnoreCase(tempPerson.getPersonName()) < 0){
return -1;
}else{
return 0;
}
}
}
Where the data comes from to be written to the file
private void downloadPersons(){
HashMap<String, String> params = new HashMap<String, String>();
Kumulos.call("selectAllPersons", params, new ResponseHandler() {
#Override
public void didCompleteWithResult(Object result) {
ArrayList<Object> personsList = new ArrayList<Object>();
for(Object o : (ArrayList<?>)result){
Person person = new Person();
person.setPersonID(replaceNandT((String) ((HashMap<?,?>) o).get("personID")));
person.setLawName(replaceNandT((String) ((HashMap<?,?>) o).get("personName")));
person.setDisplayLaw(stringToBool((String)((HashMap<?,?>) o).get("displayPerson")));
if(person.getDisplayPerson()==true){
personsList.add(person);
}
}
//Save personsList to a file
if(PersonsLoader.saveFromRemoteSource(context, personsList)){
updateVersionNumber();
isFinished=true;
Log.d("TAG", "PersonsLoader.saveFromRemoteSource(context, personsList) success");
}
}
});
}
So what do you think is happening at this call?
Get rid of both the blocks that test File.exists(), and the File.createNewFile() calls.
Opening the file for output will create it if necessary.
When opening the file for reading, if the file doesn't exist a FileNotFoundException will be thrown. There's no point in creating an empty file to avert this: it just leads to other problems.
And get rid of the BufferedReader and readLine() calls too. They serve no useful purpose. There are no lines in an object output stream.
I have looked at How to access resources in JAR file? and How do I copy a text file from a jar into a file outside of the jar? and many other questiions but couldnt actually get an answer. What I'm trying to do is copy contents of a file in res/CDC.txt that is in jar, to somewhere out of a jar. Now, on my computer it works but when I try it on different computer I get FileNotFoundException. So, I figured out why it works on mine. I have a CLASSPATH set to .;D:\myname\Java\JavaFiles where all my java files are located in packages. In "JavaFiles" directory there is also "res/CDC.txt". So, when I start my application, it first checks the current directory myapp.jar is located in for "res/CDC.txt", and then it checks "JavaFiles" and finds it. Other computers do not have it. So, this was my initial code:
public final class CT
{
//Other fields
private static CT ct;
private NTSystem nts;
private File f1;
private File f6;
private PrintWriter pw1;
private BufferedReader br1;
//Other fields
public static void main(String[] args)
{
try
{
showMessage("Executing program...");
ct = new CT();
ct.init();
ct.create();
ct.insertData();
//Other code
showMessage("Program executed!");
}
catch(Exception e)
{
showMessage("An exception occured! Program closed.");
e.printStackTrace();
System.exit(0);
}
}
private void init()
throws IOException
{
//Other initialization
nts = new NTSystem();
f1 = new File("C:\\Users\\" + nts.getName() + "\\blahblah");
f6 = new File("res\\CDC.txt");
br1 = new BufferedReader(new FileReader(f6));
//Other initialization
showMessage("Initialized");
}
private void create()
throws IOException
{
//Makes sure file/dir exists, etc
pw1 = new PrintWriter(new BufferedWriter(new FileWriter(f1)), true);
//Other Stuff
showMessage("Created");
}
private void insertData()
throws IOException
{
String line = br1.readLine();
while(line != null)
{
pw1.println(line);
line = br1.readLine();
}
//Other stuff
showMessage("Data inserted");
}
private static void showMessage(String msg)
{
System.out.println(msg);
}
}
which I changed to
public final class CT
{
//Other fields
private static CT ct;
private NTSystem nts;
private byte[] buffer;
private File f1;
private URL url1;
private FileOutputStream fos1;
private InputStream is1;
//Other fields
public static void main(String[] args)
{
try
{
showMessage("Executing program...");
ct = new CT();
ct.init();
ct.create();
ct.insertData();
//Other code
showMessage("Program executed!");
}
catch(Exception e)
{
showMessage("An exception occured! Program closed.");
e.printStackTrace();
System.exit(0);
}
}
private void init()
throws IOException
{
//Other initialization
nts = new NTSystem();
buffer = new byte[4096];
f1 = new File("C:\\Users\\" + nts.getName() + "\\blahblah");
url1 = getClass().getClassLoader.getResource("res\\CDC.txt"); //Also tried url1 = ct.getClass().getClassLoader.getResource("res\\CDC.txt"); or url1 = this.getClass().getClassLoader.getResource("res\\CDC.txt"); or url1 = CT.getClass().getClassLoader.getResource("res\\CDC.txt");
is1 = url1.openStream();
//Other initialization
showMessage("Initialized");
}
private void create()
throws IOException
{
//Makes sure file/dir exists, etc
pw1 = new PrintWriter(new BufferedWriter(new FileWriter(f1)), true);
//Other Stuff
showMessage("Created");
}
private void insertData()
throws IOException
{
int read = is1.read(buffer);
while(line != null)
{
fos1.write(buffer, 0, read);
read = is1.read(buffer);
}
//Other stuff
showMessage("Data inserted");
}
private static void showMessage(String msg)
{
System.out.println(msg);
}
}
And this time I always get NullPointerException. So, how to read folders and files that are within jar?
Thanks
You will want to use getSystemResourceAsStream() to read the contents from files in a jar.
This of course is assuming the file is actually on the classpath of the other users computers.