Java Save and Load Program's State - java

in my java Project I have several classes/java files but is in Menu class that is stored all the lists of stuff that is used. In terms of data I store 6 Lists(2 ArrayLists and 4 HashMaps) which 1 is defined in Menu class and others are in different classes.
So I need to create a savestate and a loadstate to when I close the program to restore the previous state. All the Lists are implemented with Serializable
Is it possible to save all the Menu's state and reload it or I've to save all the lists individually? Save all in one file would be great.
Here is the function I have, works(no warnings/errors) and compiles but doesn't creates the file "datafiles".
Any ideas?
private void MenuSave(){
String wd = System.getProperty("user.dir");
JFileChooser fc = new JFileChooser(wd);
int rc = fc.showDialog(null, "Select Data File Location to Save");
if (rc == JFileChooser.APPROVE_OPTION)
{
File file = fc.getSelectedFile();
String filename = file.getAbsolutePath();
savestate(lf, lc, lv, lcl,filename);}
}
public void savestate(Cars la, Bikes l2, Motos l3, Planes l4, People n1, Food n2, String filename){
int i;
File out = new File(filename);
ObjectOutputStream output = null;
try{
output = new ObjectOutputStream(new FileOutputStream(filename));
for(Car c : la.getCars().values()){
output.writeObject(c);
}
for(Bike b : l2.getBikes().values()){
output.writeObject(b);
}
for(Moto m : l3.getMotos().values()){
output.writeObject(m);
}
for(i=0;i<n1.size();i++)
{output.writeObject(n1.get(i)));
}
for(i=0;i<n2.size();i++)
{output.writeObject(n2.get(i)));
}
}catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
if (output != null) {
output.flush();
output.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}

doesn't creates the file "datafiles".
I'll bet that it does, just not where you are expecting to find it. Don't "drop your files wherever they fall", put them some place that is read/writable, logical and reproducible.
String filename = "datafiles";
File out = new File(System.getProperty("user.home"), filename);
// ...
output = new ObjectOutputStream(new FileOutputStream(out));
Then look in user home for the datafiles (why does it have no file type/extension?) file.
The File constructor that accepts 2 String (parent & name) parameters uses the correct File separator for the OS.
user.home is a system property that points to a stable, reproducible path that has read/write access.

So as I thought I just need to save the lists individually without that for .
1-Choose where to save the file, then save the Classes in there.
2-To read just parse the input and store replacing the current Classes.
...
String wd = System.getProperty("user.dir");
this.setAlwaysOnTop(false);
JFileChooser fc = new JFileChooser(wd);
fc.setDialogType((int)JFileChooser.SAVE_DIALOG);
int rc = fc.showDialog(null, "Select Data File");
this.setAlwaysOnTop(true);
if (rc == JFileChooser.APPROVE_OPTION)
{
File file = fc.getSelectedFile();
ObjectOutputStream output = null;
try{
output = new ObjectOutputStream(new FileOutputStream(file));
output.writeObject(list1);
output.writeObject(list2);
output.writeObject(list3);
....
output.close();
}catch (IOException x){
....
}catch(NullPointerException n){
....
}}
to read is just the same:
String wd = System.getProperty("user.dir");
this.setAlwaysOnTop(false);
JFileChooser fc = new JFileChooser(wd);
fc.setDialogType((int)JFileChooser.OPEN_DIALOG);
int rc = fc.showDialog(null, "Select Data File to Load");
this.setAlwaysOnTop(true);
if (rc == JFileChooser.APPROVE_OPTION)
{
File file = fc.getSelectedFile();
String filename = file.getAbsolutePath();
ObjectInputStream input = null;
try{
input = new ObjectInputStream(new FileInputStream(file));
this.list1=(ListType1)input.readObject();
this.list2=(ListType2input.readObject();
....
}catch (IOException x){
...
}catch(ClassNotFoundException x){
...
}
}

Related

My File Clears Everytime I Run My Code - Java

I have Server-Client messenger - not important - and I have a settings file to store the settings, but for some reason when I run the code, the settings file clears.
Here is the code that makes the settings file and directory:
boolean exists = new File(System.getProperty("user.home")+"\\Documents\\Messenger Server").mkdir();
File directory = new File(System.getProperty("user.home")+"\\Documents\\Messenger Server");
File settingsFile = new File(System.getProperty("user.home")+"\\Documents\\Messenger Server\\settings.txt");
if(exists){
try {
directory.createNewFile();
System.out.println("Created");
} catch (IOException e) {
e.printStackTrace();
}
}
if(!settingsFile.exists()){
try {
settingsFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Created Settings.txt");
System.out.println(settingsFile.getAbsolutePath());
}
And this is the code that reads and writes to the file:
try {
FileReader fileReader = new FileReader(settingsFile);
FileWriter fileWriter = new FileWriter(settingsFile);
BufferedReader bf = new BufferedReader(fileReader);
BufferedWriter bw = new BufferedWriter(fileWriter);
}catch(IOException b){
b.printStackTrace();
}
ArrayList<String> settingList = new ArrayList<String>();
for (int i = 0; i < 6; i++) {
try {
settingList.add(bf.readLine());
} catch (IOException ex) {
ex.printStackTrace();
}
}
if(!settingList.get(0).equals("alwaysOnTop=true")&&!settingList.get(0).equals("alwaysOnTop=false")){
try {
bw.write("alwaysOnTop=false");
} catch (IOException ex) {
ex.printStackTrace();
}
}
The FileWriter constructor can take a boolean argument ( FileWriter(File file, boolean append) ), which if true makes the FileWriter append to the file instead of overwriting it every time. Like this:
FileWriter fileWriter = new FileWriter(settingsFile, true);
The answer from #JustusG is correct.
Still, I would not recommend using .txt files to keep the settings of your app.
Since they are hard to maintain, you may have duplicate settings (because of appending...) and so on.
I would recommend using .properties files. At the end of the day they do the same thing, it's just that .properties files have classes to read and to write your settings/properties.
Here is an example:
Properties prop = new Properties();
File propFile = new File("path/to/app.properties");
InputStream in = new FileInputStream(propFile); // Open the prop file
prop.load(in); // Load it in the Properties object
prop.setProperty("setting1", "value1"); // Setting a new setting to what you need OR setting an old setting to a new value.
String value2 = prop.getProperty("setting2"); // Reading a property
//And at the end, writing the properties that you changed (without duplicates)
prop.store(new FileOutputStream("xyz.properties"), null);

How to duplicate a file given a different name in the same directory in windows

I have been trying to duplicate a file but change the name of it in the same windows directory but I got not luck.
I cant just copy the file in the same directory because of the windows rule that two files cannot have the same name in the same directory.
I am not allowed to copy it to another directory then rename it, and then move it back in the same directory.
And I don't see any helpful implementation in the File.class.
Tried something like that but it didnt work:
File file = new File(filePath);
File copiedFile = new File(filePath);
//then rename the copiedFile and then try to copy it
Files.copy(file, copiedFile);
An initial attempt would be using Path as suitable:
Path file = Paths.get(filePath);
String name = file.getFileName().toString();
String copiedName = name.replaceFirst("(\\.[^\\.]*)?$", "-copy$0");
Path copiedFile = file.resolveSibling(copiedName);
try {
Files.copy(file, copiedFile);
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
You could create a new file in the same directory and then just copy the contents of the original file to the duplicate
See: Java read from one file and write into another file using methods
For more info
you can also use this snippet from https://www.journaldev.com/861/java-copy-file
private static void copyFileUsingStream(File source, File dest) throws IOException {
InputStream is = null;
OutputStream os = null;
try {
is = new FileInputStream(source);
os = new FileOutputStream(dest);
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
} finally {
is.close();
os.close();
}
}
#Pierre his code is perfect, however this is what I use so I won't be able to change the extension:
public static void copyWithDifferentName(File sourceFile, String newFileName) {
if (sourceFile == null || newFileName == null || newFileName.isEmpty()) {
return;
}
String extension = "";
if (sourceFile.getName().split("\\.").length > 1) {
extension = sourceFile.getName().split("\\.")[sourceFile.getName().split("\\.").length - 1];
}
String path = sourceFile.getAbsolutePath();
String newPath = path.substring(0, path.length() - sourceFile.getName().length()) + newFileName;
if (!extension.isEmpty()) {
newPath += "." + extension;
}
try (OutputStream out = new FileOutputStream(newPath)) {
Files.copy(sourceFile.toPath(), out);
} catch (IOException e) {
e.printStackTrace();
}
}

Can not read any text file

First of all, I would like you to say that I am quite new here and I'm also a beginner in Android Studio and Java.
My problem/question is:
I have an App in Android Studio which should write a string to a text file at a specific point and also should read the same file on App startup.
Writing to the file is working but not reading. When I create a text file manually, and insert it manually to the folder it reads the string.
I already added permissions and try to find my error with LogCat but I have no clue at the moment what could be wrong.
Variables:
File root = android.os.Environment.getExternalStorageDirectory();
File dir = new File(root.getAbsolutePath() + "/myApp");
My reading function:
String myData = "";
try {
FileReader fileIn = new FileReader(dir + "/data.txt");
Scanner input = new Scanner(fileIn);
while (input.hasNextLine()) {
String line = input.nextLine();
myData = myData + line;
}
input.close();
} catch (Exception ex) {
ex.printStackTrace();
}
My writing function:
try {
File file = new File(dir, "data.txt");
FileOutputStream f = new FileOutputStream(file);
PrintWriter pw = new PrintWriter(f);
pw.println("answer42");
pw.flush();
pw.close();
f.close();
} catch (Exception ex) {
ex.printStackTrace();
}

readUTF not reading from second time in socket file transfer JAVA

i am trying to transfer files via socket. I've used only a single socket for communication( not according to FTP protocol i guess). The following code will transfer the first file successfully but is not able to tra nsfer second file as the filename doesn't change but the server gets the read bytes of the new data file. I think the problem is of the readUTF and writeUTF.
Here is my server side code. Remember this accepts the file.Not send file.
public int listenPort() throws IOException{
System.out.println("LISTENING");
try{
//this.dis = new DataInputStream(this.socketClient.getInputStream());
if( this.dis.available() != 0 ){
String filename = this.dis.readUTF();
this.fos = new FileOutputStream("/home/ankit07/" + filename);
int bytesRead = (int) IOUtils.copyLarge(this.dis,this.fos); //no of bytes copied
return bytesRead;
}else{
return 0;
}
}finally{
}
}
Here is my client side. Remember this side sends the file. Not accept
public void getFile(String filename) throws IOException{
try{
this.file = this.window.file;
DataOutputStream dos = new DataOutputStream(this.socketClient.getOutputStream());
dos.writeUTF(filename);
FileInputStream fis = new FileInputStream(this.file);
int readByte = (int) IOUtils.copyLarge(fis, dos);
System.out.println("FILE SENT : " + filename + " Bytes :" + readByte);
//this.socketClient.close();
}finally{
//if( this.os!=null) this.os.close();
if( this.window.file != null) this.window.file = null;
if( this.file != null) this.file = null;
//if( this.socketClient!=null) this.socketClient.close();
}
}
The file selections are done in other class window.
The method to select the file is in the window class. This has a public File property to hold the file and then i've called the getFile(String filename) to send the file name and to refer to the selected file, the client has File property to refer to the same file.
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
Object src = e.getSource();
if( src instanceof JButton ){ //Browse clicked
JFileChooser fc = new JFileChooser();
int returnVal = fc.showDialog(null, "SELECT FILE");
if( returnVal == JFileChooser.APPROVE_OPTION){
this.file = fc.getSelectedFile();
try {
this.sc.getFile(this.file.getName());
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}else{
//unable to select file
}
}
}
Also i am not able to transfer large files like mp3 and video besides my initial problem. It would be helpful if you'd know any solutions.
Thanks you !!!!
You're sending filename, but then you're sending this.file. There's nothing here to show that they're always referring to the same file. Indeed you have a RS file, in this.window.file. You need to sort out all this confusion.

Test if file exists

I'm trying to open a file in android like this :
try
{
FileInputStream fIn = context.openFileInput(FILE);
DataInputStream in = new DataInputStream(fIn);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
if(in!=null)
in.close();
}
catch(Exception e)
{ }
, but in case the file does not exists a file not found exception is thrown . I'd like to know how could I test if the file exists before attempting to open it.
I think the best way to know if a file exists, without actually trying to open it, is as follows:
File file = getContext().getFileStreamPath(FILE_NAME);
if(file.exists()) ...
The documentation says Context.openFileInput either returns an inputStream (file found) or throws a FileNotFoundException (not found)
http://developer.android.com/reference/android/content/Context.html#openFileInput(java.lang.String)
So it looks like the exception is your "test".
You could also try using standard
java.io.File file = new java.io.File(PATHTOYOURCONTEXT , FILE);
if (file.exists()) {
FileInputStream fIn = new FileInputStream(file);
}
But that is not recommended. Context.openFileInput() and Context.openFileOutput() make sure you stay in your applications storage context on the device, and that all of your files get
deleted when your app gets uninstalled.
With the standard java.io.File this is the function I have created, and works correctly:
private static final String APP_SD_PATH = "/Android/data/com.pkg.myPackage";
...
public boolean fileExistsInSD(String sFileName){
String sFolder = Environment.getExternalStorageDirectory().toString() +
APP_SD_PATH + "/Myfolder";
String sFile=sFolder+"/"+sFileName;
java.io.File file = new java.io.File(sFile);
return file.exists();
}
why dont you just catch the FileNotFound exception and take that as the file not being present.
If you want to ensure a file exists (i.e. if it doesn't exist create a new one, if it does then don't erase it) then use File.createNewFile:
https://docs.oracle.com/javase/7/docs/api/java/io/File.html#createNewFile()
e.g.
{
String pathName = <file path name>
File file = new File (pathName);
Uri pathURI = Uri.fromFile (file);
boolean created;
String mIOException = "";
String mSecException = "";
try
{
created = file.createNewFile();
if (created)
{
ctxt.sendBroadcast (new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, pathURI));
}
}
catch (IOException ioex)
{
mIOException = ioex.getMessage();
}
catch (SecurityException sex)
{
mSecException = sex.getMessage();
}
}
If you want to open a file in any case (i.e. if it doesn't exist create a new one, if it does append to the old one) you can use this, no testing necessary:
public static void write_custom_log(String message){
File root = Environment.getExternalStorageDirectory();
try{
BufferedWriter fw = new BufferedWriter(new FileWriter(new File("/mnt/sdcard/tjb_tests/tjb_log_file.txt"),true));
if (root.canWrite()){
fw.write(message);
fw.close();
}
} catch (IOException e) {
Log.e("One", "Could not write file " + e.getMessage());
}
}
My suggestion is to check length of the file. if file.length() returns 0 that means file doesn't exist.

Categories