Output/Input of Java Files via GUI - java

I have three classes libraryDB, libraryItems and libraryGUI. libraryDB() is essentially a hash map with the keys as book barcodes/ISBN's and the values are libraryItems, which consist of and therefore take two String parameters: Title and Author.
I have a JFileChooser all set up in the GUI to save, but my save() and open() methods are giving problems. I want it set up so that when it is saved each libraryDB object has its own 3 lines (one each for Barcode, Title, Author, respectively). I tried loading them back in by reading each individual line in, here is the code I wrote for that:
//Suppose to construct a LibraryDB by reading one from a previously-saved file.
public LibraryDB (File file) throws IOException {
Scanner readFile = new Scanner(file);
int barcode;
String title;
String author;
while (readFile.hasNext()){
barcode = Integer.parseInt(readFile.nextLine());
title = readFile.nextLine();
author = readFile.nextLine();
LibraryItem authorTitleValues = new LibraryItem(title,author);
this.libraryItems.put(barcode, authorTitleValues);
}
}
//Trying to save to text file, where for each object n there are 3n lines.
public void save(File file) throws IOException {
PrintStream writer = new PrintStream(file);
for (Iterator<Integer> localIterator = libraryItems.keySet().iterator();
localIterator.hasNext();){
int barcode = ((Integer)localIterator.next()).intValue();
writer.println(barcode);
writer.println((libraryItems.get(Integer.valueOf(barcode))).getTitle());
writer.println((libraryItems.get(Integer.valueOf(barcode))).getAuthor());
}
}
Any help or insight that you can provide that will aid me in successfully being able to save/open would be much appreciated! Thanks!
More explicity, whenever I save a libraryDB to a file I am unable to go back later and open up the file?

You should flush() and close() your PrintStream before ending the save function. I'm not sure that is the problem, since your description is not too accurate, but do it anyway.

File streams and writer have to be explicitly closed at the end of writing to them - otherwise they will lock the file.
public void save(File file) throws IOException {
PrintStream writer = new PrintStream(file);
try {
for (Iterator<Integer> localIterator = libraryItems.keySet().iterator(); localIterator.hasNext();) {
int barcode = ((Integer) localIterator.next()).intValue();
writer.println(barcode);
writer.println((libraryItems.get(Integer.valueOf(barcode))).getTitle());
writer.println((libraryItems.get(Integer.valueOf(barcode))).getAuthor());
}
writer.flush();
} finally {
writer.close();
}
}

So, I just forgot to redeclare libraryDB!? Grrr...lol I don't think the compiler will complain because it has already been declared. However, the information being read from the file was just going into oblivion or something because there was no object for it to be put into. At least, that is what I think was happening. Thanks for your help. Here is my solution:
public LibraryDB (File file) throws IOException {
//this next line was what I was missing...sigh.
this.libraryItems = new HashMap<Integer, LibraryItem>();
Scanner readFile = new Scanner(file);
int barcode;
String title;
String author;
while (readFile.hasNext()){
barcode = Integer.parseInt(readFile.nextLine());
title = readFile.nextLine();
author = readFile.nextLine();
LibraryItem authorTitleValues = new LibraryItem(title, author);
libraryItems.put(Integer.valueOf(barcode), authorTitleValues);
}
readFile.close();
}

Related

how can i write in particular location of a text file in java

The Problem is that i have four different array lists . And I want to insert the data of particular array list class depending on the input given by user.
How can i do that ??
import java.io.*;
import java.util.*;
public class acquaintances
{
public static void main(String args[])
{
Arraylist<relative>re=new Arraylisrt<relative>();
Arraylist<personalfriend> pf=new Arraylist<personalfriend>();
Arraylist<casualfriend> cf=new Arraylist<casualfriend>();
Arraylist<professionalfriend> prf=new Arraylist<professionalfriend>():
These are different arraylists .
Iwant to write different acquantances info in the order in the text file
casual friend 1
casual friend2
........
relative 1
relative 2
......
personalfriend1
personal friend2
personal friend3
...........
professionalfriend1
professionalfriend2
..................
Also if i delete particular detail . then how am i supposed to erase particular
detail from the file
String name=null,number=null,email=null;
File file = new File("Readme.txt");
if (!file.exists()) {
file.createNewFile();
}
Scanner sc=new Scanner(System.in);
int ch=0,chu=0;
String jaff=null,baff=null;
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
String cmet_why=null,cinfo=null,cdate=null;
while(1)
{
System.out.println("Enter name,number,email of acquaintance");
name=sc.nextLine();
number=sc.nextLine();
email=sc.nextLine();
System.out.println("1.Create 2.Delete 3.Display 4. DisplayAll 5.Search );
ch=sc.nextInt();
jaff=sc.nextLine();
Switch(ch):
{
case 1:
{
System.out.println("1.Casual friend 2.relative 3.personal friend 4. Professional friend");
chu=sc.nextInt();
baff=sc.nextLine();
if(chu==1)
{
System.out.println("Enter reasonto meet ,dateof meeting,info");
cmet_why=sc.nextLine();
cdate=sc.nextLine();
cinfo=sc.nextLine();
casualfriend cfriend=new casualfriend(name,number,email,cmet_why,cdate,cinfo);
here i added the class object to the casual friend list
and i want to write it to text file in the location.
the problem is that it is in the middle of the text file.
After this i have to write relatives,personal friends ,professional friends .
info line by line
cf.add(cfriend);
}
}
}
}
}
}
there are different switch cases. i want to write these in the order.
public static void writeWithRandmoAccessFile( String content, String filePath) {
try (RandomAccessFile randomAccessFile = new RandomAccessFile(new File(filePath), "rw")) {
// move the cursor to the end of the file
// you can move the cursor to any position inside the file or to write at random positions
randomAccessFile.seek(randomAccessFile.length());//random position
randomAccessFile.write(content.getBytes());
// alternatively you can use randomAccessFile.writeChars(content)
// or randomAccessFile.writeUTF(content);
} catch (IOException e) {
e.printStackTrace();
}
}

Method that Writes an array as text to file read by humans

I have a practice question that asks me to write a method that receives an array of employees and a file name. It writes the individual employee (salesman or technician) info as text to a file which can be read by humans. This is the code i have so far
public static void writeAsText (employees[], String fileName)throws IOException
{
// Write the text to the file
File myFile = new File("text.dat");
FileWriter myWriter = new FileWriter(myFile);
BufferedWriter myBufferOut = new BufferedWriter(myWriter);
//Loops through array
for (int i = 0; i < employees.length; i++)
{
myBufferOut.write(employees[i]+"");
}
myBufferOut.close();
}
Pls i just need your opinion to know if i have answered the question right. Thank you for your help in advance.

Problems with scanning

I'm studying Biomedical Informatics and I'm now doing my clinical practice, where I have to check that the charges made to hospitalized patients were performed correctly on supplies that are of unique charging (every procedure and supplies used have a codification).
I can import the Excel file on the software I'm doing but, I don't know now how to do the scan.
Here is the code (I'm doing it on NetBeans),
public class Portal extends javax.swing.JFrame {
private DefaultTableModel model;
public static int con = 0;
public ArrayList listas = new ArrayList();
public ArrayList listasr = new ArrayList();
public Portal() {
initComponents();
model = new DefaultTableModel();
jTable1.setModel(model);
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
JFileChooser examinar = new JFileChooser();
examinar.setFileFilter(new FileNameExtensionFilter("Archivos Excel", "xls", "xlsx"));
int opcion = examinar.showOpenDialog(this);
File archivoExcel = null;
if(opcion == JFileChooser.APPROVE_OPTION){
archivoExcel = examinar.getSelectedFile().getAbsoluteFile();
try{
Workbook leerExcel = Workbook.getWorkbook(archivoExcel);
for (int hoja=0; hoja<leerExcel.getNumberOfSheets(); hoja++)
{
Sheet hojaP = leerExcel.getSheet(hoja);
int columnas = hojaP.getColumns();
int filas = hojaP.getRows();
Object data[]= new Object[columnas];
for (int fila=0; fila < filas; fila++)
{
for(int columna=0; columna < columnas; columna++)
{
if(fila==0)
{
model.addColumn(hojaP.getCell(columna, fila).getContents());
}
System.out.println(hojaP.getCell(columna, fila).getContents());
if(fila>=1)
data[columna] = hojaP.getCell(columna, fila).getContents();
}model.addRow(data);
}
}
model.removeRow(0);
JOptionPane.showMessageDialog(null, "Excel cargado exitosamente");
}
}
}
Before you import the excel file save it as a csv(comma delimited) file(remeber to delete the headings). Then open the netbeans project folder under my documents, then open the your project folder and dump the csv file in their. Look at your project under files in netbeans open the folder and you will see the file in their. Now you said you want to read the file/ scan the file.
You can use my method at first, understand it and adapt to other scenarios you have in the future.
First create a class or use an readily created( you already created java class).
Declare arrays depending on how many rows you had in the excel file not the csv file and a counter.
Example two.
String [] patientsnamess;
int [] ages;
int count;
Now initiate the arrays in a deafault constructor(you don't have to because you can do it when you declare them but it is conventional). You can learn about constructors there are two I know of or there are only two but I will only show a default constructor.
It will look like this.
public yourClassName(){
patientsnames = new String[400];//the number in square brackets are an example it sets the size of the array. You can set the size according to how many patients there are or you could just use lists as the limit on the list as dependent on primary and virtual memory.
ages = new int[400];
count = 0;
}
now create the method two read the text file.
public void readFile(){
count = 0;//important
Scanner contents = null;
try{
contents = new Scanner(new FileReader("You file's name.txt");
while(contents.hasNext()){
String a = contents.nextLine();
String p[]= a.split("\\;");
patientsnames[count] = p[0];
ages[count] = p[1];
count++;//important
}
}
catch(FileNotFoundException e){
System.out.println(e.getMessage());
}
}
Now create get methods to call up the arrays with the values from the file.(Find out on rest of stackoverflow).
Remeber that field types link up with the data in the file.
I really hope this works for you. If not I am sorry but good luck with your Biochemical Informatics course.
Remeber to call the readFile method with an object in this case or it won't work.
Research the neccessary imports such as:
import java.io.*;
import java.util.*;

Appending String from a File into an Array and parsing it

I am trying to make a saving/loading of settings for my GUI.
So far, I've got saving, using Properties:
Properties prop = new Properties();
prop.setProperty("a", Boolean.valueOf(boxRandomMouse.isSelected()).toString());
prop.setProperty("b", listModelPath.toString());
The problem I've got here, is that I am saving listModelPath of my JList into String:
public static DefaultListModel<String> listModelPath;
In my file under property b. I can't find any way to load back and parse this listModelPath into my desired type, which is Position.
The class, Position, can be initialised with below constractor:
Position newPos = new Position(int x, int y, int z);
or for array:
public Position[] toTown = new Position[] {
new Position(3094, 3491, 0), new Position(3088, 3487, 0),
new Position(3080, 3475, 0)};
This is how the String of listModelPath looks when It's been saved into the file
c=[[x\=3094, y\=3491, z\=0], [x\=3092, y\=3491, z\=0], [x\=3090, y\=3491, z\=0], [x\=3088, y\=3490, z\=0], [x\=3086, y\=3488, z\=0], [x\=3084, y\=3486, z\=0], [x\=3082, y\=3484, z\=0], [x\=3081, y\=3482, z\=0], [x\=3080, y\=3481, z\=0], [x\=3080, y\=3479, z\=0], [x\=3080, y\=3477, z\=0], [x\=2045, y\=5194, z\=0], [x\=2044, y\=5192, z\=0], [x\=2042, y\=5190, z\=0], [x\=2041, y\=5189, z\=0]]
I need to figure out a way to parse the String above, into my Positions, or somehow find a way to save this array to a File, which I honestly have no idea how to do.
I've tried doing this numerously on different ways, always failing, so that's why I'm here.
Hopefully you guys knows how to handle a situation I have here.
PS. I have just started reading about serialization, perhaps it is the way to go? Would it allow me to save the array I have dynamically created in the application in the file without converting it to string and back from string?
You can serialize your listModelPath object sending it then to file as an Object which will then let you read it as an Object then cast it back to its real Class.
This can be done by chaining an ObjectOutputSteam to an underlying stream such as a FileOutputStream then writing the Obejet to it (Position[])
public void writePositions() throws IOException, ClassNotFoundException {
File file = new File("positions.ser");
FileOutputStream outFile = new FileOutputStream(file);
ObjectOutputStream outStream = new ObjectOutputStream(outFile);
public Position[] toTown = new Position[] {
new Position(3094, 3491, 0),
new Position(3088, 3487, 0),
new Position(3080, 3475, 0)};
outStream.writeObject(toTown);
outStream.close();
outFile.close();
}
You can the read your serialized array of Position back from the file it was written to, positions.ser like below:
public void readPositions() throws IOException, ClassNotFoundException {
File file = new File("positions.ser");
FileInputStream inFile = new FileInputStream(file);
ObjectInputStream inStream = new ObjectInputStream(inFile);
Position[] toTown = (Position[]) inStream.readObject());
for(int i = 0; i < toTown.length; i++) {
System.out.println(toTown[i]);
}
inStream.close();
inFile.close();
file.delete();
}
You should note that the Position class should be Serializable, otherwise the JVM won't let you send any object of this type back and forth to an in memory file or even through any stream.
I'm not really sure if I have well understood the main matter concerning the listModelPath and how it relates to the Position array but you shoul provide more informations, especially how you are creating the listModelPath instance.
Edit (Save many objects with different types):
You can, not only save one Object, but as many as you want and wathever type they are. When loading back the objects to the JVM, they should be read in the same order they were written in to avoid a ClassCastException:
public void writePositions() throws IOException, ClassNotFoundException {
...
public Position[] toTown = new Position[] {
new Position(3094, 3491, 0),
new Position(3088, 3487, 0),
new Position(3080, 3475, 0)};
outStream.writeObject(toTown); //Write the array of Position
boolean selected = boxRandomMouse.isSelected();
outStream.writeObject(selected); //Write the Boolean Object
...
}
public void readPositions() throws IOException, ClassNotFoundException {
...
Position[] toTown = (Position[]) inStream.readObject()); //Read the array of Position which was written first
for(int i = 0; i < toTown.length; i++) {
System.out.println(toTown[i]);
}
boolean selected = (boolean) inStream.readObject(); //Read the Boolean value which was written in the second order
// And so on
...
}
You can only have Strings in property files, so you have to find a way to convert listModelPath in a inversible way. I think that you could try json (Gson or Jackson) whose job is to serialize-deserialize objects to-from String.
I can do no more without source of your Position class.

saving random numbers in java

I'm doing an animation in Processing. I'm using random points and I need to execute the code twice for stereo vision.
I have lots of random variables in my code, so I should save it somewhere for the second run or re-generate the SAME string of "random" numbers any time I run the program. (as said here: http://www.coderanch.com/t/372076/java/java/save-random-numbers)
Is this approach possible? How? If I save the numbers in a txt file and then read it, will my program run slower? What's the best way to do this?
Thanks.
If you just need to be able to generate the same sequence for a limited time, seeding the random number generator with the same value to generate the same sequence is most likely the easiest and fastest way to go. Just make sure that any parallel threads always request their pseudo random numbers in the same sequence, or you'll be in trouble.
Note though that there afaik is nothing guaranteeing the same sequence if you update your Java VM or even run a patch, so if you want long time storage for your sequence, or want to be able to use it outside of your Java program, you need to save it to a file.
Here is a sample example:
public static void writeRandomDoublesToFile(String filePath, int numbersCount) throws IOException
{
FileOutputStream fos = new FileOutputStream(new File(filePath));
BufferedOutputStream bos = new BufferedOutputStream(fos);
DataOutputStream dos = new DataOutputStream(bos);
dos.writeInt(numbersCount);
for(int i = 0; i < numbersCount; i++) dos.writeDouble(Math.random());
}
public static double[] readRandomDoublesFromFile(String filePath) throws IOException
{
FileInputStream fis = new FileInputStream(new File(filePath));
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
int numbersCount = dis.readInt();
double[] result = new double[numbersCount];
for(int i = 0; i < numbersCount; i++) result[i] = dis.readDouble();
return result;
}
Well, there's a couple of ways that you can approach this problem. One of them would be to save the random variables as input into a file and pass that file name as a parameter to your program.
And you could do that in one of two ways, the first of which would be to use the args[] parameter:
import java.io.*;
import java.util.*;
public class bla {
public static void main(String[] args) {
// You'd need to put some verification code here to make
// sure that input was actually sent to the program.
Scanner in = new Scanner(new File(args[1]));
while(in.hasNextLine()) {
System.out.println(in.nextLine());
}
} }
Another way would be to use Scanner and read from the console input. It's all the same code as above, but instead of Scanner in = new Scanner(new File(args[1])); and all the verification code above that. You'd substitute Scanner in = new Scanner(System.in), but that's just to load the file.
The process of generating those points could be done in the following manner:
import java.util.*;
import java.io.*;
public class generator {
public static void main(String[] args) {
// You'd get some user input (or not) here
// that would ask for the file to save to,
// and that can be done by either using the
// scanner class like the input example above,
// or by using args, but in this case we'll
// just say:
String fileName = "somefile.txt";
FileWriter fstream = new FileWriter(fileName);
BufferedWriter out = new BufferedWriter(fstream);
out.write("Stuff");
out.close();
}
}
Both of those solutions are simple ways to read and write to and from a file in Java. However, if you deploy either of those solutions, you're still left with some kind of parsing of the data.
If it were me, I'd go for object serialization, and store a binary copy of the data structure I've already generated to disk rather than having to parse and reparse that information in an inefficient way. (Using text files, usually, takes up more disk space.)
And here's how you would do that (Here, I'm going to reuse code that has already been written, and comment on it along the way) Source
You declare some wrapper class that holds data (you don't always have to do this, by the way.)
public class Employee implements java.io.Serializable
{
public String name;
public String address;
public int transient SSN;
public int number;
public void mailCheck()
{
System.out.println("Mailing a check to " + name
+ " " + address);
}
}
And then, to serialize:
import java.io.*;
public class SerializeDemo
{
public static void main(String [] args)
{
Employee e = new Employee();
e.name = "Reyan Ali";
e.address = "Phokka Kuan, Ambehta Peer";
e.SSN = 11122333;
e.number = 101;
try
{
FileOutputStream fileOut =
new FileOutputStream("employee.ser");
ObjectOutputStream out =
new ObjectOutputStream(fileOut);
out.writeObject(e);
out.close();
fileOut.close();
}catch(IOException i)
{
i.printStackTrace();
}
}
}
And then, to deserialize:
import java.io.*;
public class DeserializeDemo
{
public static void main(String [] args)
{
Employee e = null;
try
{
FileInputStream fileIn =
new FileInputStream("employee.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
e = (Employee) in.readObject();
in.close();
fileIn.close();
}catch(IOException i)
{
i.printStackTrace();
return;
}catch(ClassNotFoundException c)
{
System.out.println(.Employee class not found.);
c.printStackTrace();
return;
}
System.out.println("Deserialized Employee...");
System.out.println("Name: " + e.name);
System.out.println("Address: " + e.address);
System.out.println("SSN: " + e.SSN);
System.out.println("Number: " + e.number);
}
}
Another alternative solution to your problem, that does not involve storing data, is to create a lazy generator for whatever function that provides you your random values, and provide the same seed each and every time. That way, you don't have to store any data at all.
However, that still is quite a bit slower (I think) than serializing the object to disk and loading it back up again. (Of course, that's a really subjective statement, but I'm not going to enumerate cases where that is not true). The advantage of doing that is so that it doesn't require any kind of storage at all.
Another way, that you may have not possibly thought of, is to create a wrapper around your generator function that memoizes the output -- meaning that data that has already been generated before will be retrieved from memory and will not have to be generated again if the same inputs are true. You can see some resources on that here: Memoization source
The idea behind memoizing your function calls is that you save time without persisting to disk. This is ideal if the same values are generated over and over and over again. Of course, for a set of random points, this isn't going to work very well if every point is unique, but keep that in the back of your mind.
The really interesting part comes when considering the ways that all the previous strategies I've described in this post can be combined together.
It'd be interesting to setup a Memoizer class, like described in the second page of 2 and then implement java.io.Serialization in that class. After that, you can add methods save(String fileName) and load(String fileName) in the memoizer class that make serialization and deserialization easier, so you can persist the cache used to memoize the function. Very useful.
Anyway, enough is enough. In short, just use the same seed value, and generate the same point pairs on the fly.

Categories