Java: Writing Variables to File, and Reading back - java

I am currently using Eclipse Java Neon for my builder, and I am trying to implement a save and load feature into a project i am currently working on. I know it requires me to use a Try/Catch block, but I have no idea how to really handle it. Not only that, but what I tried out is giving me a bit of an error:
try {
System.out.println("Writing to file...");
charWrite = new FileWriter("player.dat");
charWrite.write(player.getName()); //String
charWrite.write(player.getJob()); //String
charWrite.write(player.getLevel()); //Int
charWrite.write(player.getCurrency()); //Int
charWrite.write(player.getHealth()); //Int
charWrite.write(player.getExp()); //Int
}
catch (IOException excpt) {
System.out.println("Caught IOException: " + excpt.getMessage());
}
The system seems to recognize what is happening, but when I go to open it and see if it has written, the document is still blank.
And if I am this lost on writing, I am going to be so lost when reading to place it into the Class's parameters.
Thanks for the help.

You are trying to write an object of type java.lang.Class to a file. If you want the String representation of the class name use toString():
charWrite.write(player.getClass().toString());

Related

Is it possible to add a variable where code should be?

I am currently trying to create an automation framework using Java and Selenium.
I want to create a line of code which essentially can read any input and make it a line of runnable code. For example, in an external file, a user could post 'id' into a field, that field will then be read by my program and execute the line. driver.findElement(By.id(.......)
Currently I'm using a bunch of if statements to do this for each identifier e.g. id, cssSelector, Xpath etc etc but then I'll need to do the same for the actions used by the program .click, .sendKeys etc so the program will just keep expanding and look overall very messy.
Is there a solution that would allow me to do this in a nicer way or am I stuck with my original approach?
Reflection is probably the most direct way to solve this. It essentially allows classes and methods to be looked up by their string names.
Here's a fag-packet example of how you might approach this using the snippet you provided, but I suggest you read some documentation before diving in.
Element findElementReflectively(Driver driver, String elementType, String thingToSearchFor) {
try {
Method m = By.class.getMethod(elementType, String.class);
if(!Modifier.isStatic(m.getModifiers())) {
throw new NoSuchMethodException("'By' method is not static.");
}
return driver.findElement(m.invoke(null, thingToSearchFor));
} catch (IllegalAccessException | NoSuchMethodException e) {
throw new IllegalArgumentException("Unknown element type: " + elementType, e);
} catch (InvocationTargetException e) {
throw new RuntimeException("Failed to find requested element.", e.getCause());
}
}
It depends on what you actually want to do.
Reading an id from a file and then execute code can be achieved through config file with this : Properties
Or if you want to execute full input code just search a little bit more
How to execute console or GUI input as if it was actual Java code?

Access .tlb from JAVA

Currently trying to access a type library file from JAVA, I have tried the following with corresponding errors:
1- Com2Java: I receive this Error Each time I try to connect to my application:
Minidumps are not enabled by default on client versions of Windows
2- Com4j: It produces only interfaces and Couldn't understand how to use them (I can't find any classes, just interfaces)
3- After a small search, found out about Visual J++ but couldnt download it coz it was discontnued.
Could anyone give advice?
Thank you
I have not used Com2Java or Com4j before, but a long time ago I used a library called JavaCOMBridge (https://sourceforge.net/projects/jacob-project/).
The version of JavaCOMBridge I used cannot handle multiple inheritance, and I don't see how there can be a good way to do it.
Forget about Visual J++. It's an abomination created by Microsoft and was sued into oblivion.
If you are experienced in both C and Java, and the amount of APIs you have to bridge is not large, I'd recommend using JNI directly.
Edit
Here's an example using Excel:
package test;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
public class JaCoBTest {
public static void main(String[] args) {
String EXCEL_FILE = "FullPathOfAnExcelFile.xlsx";
// Using Excel as an example
ActiveXComponent app = new ActiveXComponent("Excel.Application");
// Modify a property, to show Excel window
app.setProperty("Visible", true);
// Get Excel workbook object
Dispatch workbook = app.getProperty("Workbooks").toDispatch();
// Call method, to open an Excel file
Dispatch.call(workbook, "Open", new Variant(EXCEL_FILE), new Variant("1"));
// Wait for 5 seconds
try {
Thread.sleep(1000);
} catch (InterruptedException iex) {
iex.printStackTrace();
}
// Close Excel without saving
workbook.call(workbook, "Close");
// Close is supposed to have three optional parameteters, but the line below is not working
//workbook.call(workbook, "Close", new Variant(false), Variant.DEFAULT, Variant.DEFAULT);
// Close Excel
Dispatch.call(app, "Quit");
}
}
There is one problem in the above code - I cannot get optional parameters to work. The function Workbook.Close is supposed to take three optional parameters, but the call always fail with invalid number of parameters.
I've also located the web page I used back then:
http://danadler.com/jacob/
The above page contains a link to a FAQ but it's slightly outdated.

I/O Not Working (Copy File, Paste It)

I'm trying to get this piece of code to work. It's a basic I/O system that copies one file and pastes it into the same directory with the chosen name. It should be simple but for some reason the program runs, it creates the second file but then it gets stuck. The CPU for Java process sits at around 5% and the file is never completed. It only copies over some of the data and then I'd imagine it's stuck in an infinite loop somewhere.
I've already compared my code with the Byte Streams tutorial on the Oracle website.
EXTRA: I just asked it to output what it was reading and it's stuck on an infinite loop reading the value 255. If that helps. Also, I compiled the code directly off the Oracle website and it does the same thing.
It appears consistent from what I can tell. Can anyone tell me what I'm doing wrong? Thank you.
(P.S: I'm Using Eclipse 4.2.0).
This is what I'm doing to copy the file:
package fileIO;
import java.io.*;
import system.Debug;
public class fileUtil {
public static void copyFileTo(String file2Copy, String file2Paste) {
FileInputStream fin = null;
FileOutputStream fout = null;
try {
fin = new FileInputStream(file2Copy);
fout = new FileOutputStream(file2Paste);
int aByte;
while ((aByte = fin.read()) != -1) {
fout.write(aByte);
}
} catch (FileNotFoundException e) {
Debug.out("Error: File Not Found: " + file2Copy);
} catch (IOException e) {
Debug.out("Error: File IO Exception Copying: " + file2Copy);
} catch (Exception e) {
Debug.out("Error: General Exception Closing Streams:" + file2Copy);
} finally {
try {
fin.close();
fout.close();
} catch (IOException e) {
Debug.out("Error: File IO Exception Closing Streams: " + file2Copy);
} catch (Exception e) {
Debug.out("Error: General Exception Closing Streams:" + file2Copy);
}
}
}
}
In my program main class I run this:
fileUtil.copyFileTo("google.bmp", "google(1).bmp");
Try to do fout.flush() before you close the OutputStream.
Okay, so I found out what was happening. Was a really nooby mistake.
I'll put my pride aside encase anyone else has this problem. It's not an infinite loop, it's just that copying using ByteStreams takes AGES. I was expecting a fast result from small image files but even small image files take a long long time to copy. I let it run for 30 seconds and the program terminated properly and I got my image copy just fine.
Thank god it's solved, I was beginning to worry.
... or do not invent bother re-inventing the wheel: use FileUtils.copyFile from the proven Apache commons-io which does it in one line.
(beware: this comment is not as innocent as it seems: File.rename does not work well on Windows shares - commons-io is always the safe bet to do these things)
Edit
Stackoverflow is not a goog place for "homework" - or you must at least say so. It is not that your problem is not real. It is that your objectives differ: you want to learn something, we want to make it work reliably with minimum maintenance.
...which leads to my second point: when you are in professional life, never program this again. As you discovered, even if you make it work, it may be extremely inefficient, handle errors incorrectly, etc.. This is particularly true with IO which is always more tricky than it seems.
Finally, since I gave you a link to a well trusted library under Apache 2.0 license, maybe you could have had a look at the source code ?

Create a database / execute a bunch of mysql statements from Java

I have a library that needs to create a schema in MySQL from Java. Currently, I have a dump of the schema that I just pipe into the mysql command. This works okay, but it is not ideal because:
It's brittle: the mysql command needs to be on the path: usually doesn't work on OSX or Windows without additional configuration.
Also brittle because the schema is stored as statements, not descriptively
Java already can access the mysql database, so it seems silly to depend on an external program to do this.
Does anyone know of a better way to do this? Perhaps...
I can read the statements in from the file and execute them directly from Java? Is there a way to do this that doesn't involve parsing semicolons and dividing up the statements manually?
I can store the schema in some other way - either as a config file or directly in Java, not as statements (in the style of rails' db:schema or database.yml) and there is a library that will create the schema from this description?
Here is a snippet of the existing code, which works (when mysql is on the command line):
if( db == null ) throw new Exception ("Need database name!");
String userStr = user == null ? "" : String.format("-u %s ", user);
String hostStr = host == null ? "" : String.format("-h %s ", host);
String pwStr = pw == null ? "" : String.format("-p%s ", pw);
String cmd = String.format("mysql %s %s %s %s", hostStr, userStr, pwStr, db);
System.out.println(cmd + " < schema.sql");
final Process pr = Runtime.getRuntime().exec(cmd);
new Thread() {
public void run() {
try (OutputStream stdin = pr.getOutputStream()) {
Files.copy(f, stdin);
}
catch (IOException e) { e.printStackTrace(); }
}
}.start();
new Thread() {
public void run() {
try (InputStream stdout = pr.getInputStream() ) {
ByteStreams.copy(stdout, System.out);
}
catch (IOException e) { e.printStackTrace(); }
}
}.start();
int exitVal = pr.waitFor();
if( exitVal == 0 )
System.out.println("Create db succeeded!");
else
System.out.println("Exited with error code " + exitVal);
The short answer (as far as i know) is no.
You will have to do some parsing of the file into separate statements.
I have faced the same situation and you can find many questions on this topic here on SO.
some like here will show a parser. others can direct to tools Like this post from apache that can convert the schema to an xml format and then can read it back.
My main intention when writing this answer is to tell that I chose to use the command line in the end.
extra configuration: maybe it is an additional work but you can do it by config or at runtime based on the system you are running inside. you do the effort one time and you are done
depending on external tool: it is not as bad as it seems. you have some benefits too.
1- you don't need to write extra code or introduce additional libraries just for parsing the schema commands.
2- the tool is provided by the vendor. it is probably more debugged and tested than any other code that will do the parsing.
3- it is safer on the long run. any additions or changes in the format of dump that "might" break the parser will most probably be supported with the tool that comes with the database release. you won't need to do any change in your code.
4- the nature of the action where you are going to use the tool (creating schema) does not suggest frequent usage, minimizing the risk of it becoming a performance bottle neck.
I hope you can find the best solution for your needs.
Check out Yank, and more specifically the code examples linked to on that page. It's a light-weight persistence layer build on top of DBUtils, and hides all the nitty-gritty details of handling connections and result sets. You can also easily load a config file like you mentioned. You can also store and load SQL statements from a properties file and/or hard code the SQL statements in your code.

Replace New with other solution?

This code has lot of trouble for my AIR 2.0 Native process which I tried to launch Java from AIR application, then the Java.exe terminate itself in the Windows Task manager, I found that new MidiTest() was the caused. Is there a better solution for new instance?
public static void main(String[] arg) {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
while (!(speed.equals(speed_stop))) {
try {
speed = in.readLine();
if(!(Global.newPlayer.equals("1"))){new MidiTest();}
} catch (IOException e) {
System.err.println("Exception while reading the input. " + e);
}
}
}
private MidiPlayer player;
public MidiTest() {
System.out.println("Start player");
// /*
}
There is no alternative to new.
This is the only way to instantiate an object. Even if you use reflection, you're still calling the constructor. You need to track down the problem. Find the exact exception that's being caused, and the exact line number, and then see what you need to do to fix that problem.
I can see that you didn't provide a complete copy of your code. There's an open comment before the close brace, and it's not right. So that means we can't help you any further with the information we have.
No, the only other option for creating a new instance of your class would be using reflection, which is a much more obscure and error prone choice than new. It should not be used unless one really needs to. And even that is loading the class and calling the object's constructor in the end, exactly the same way as new.
I suspect the problem lies somewhere in code you haven't shown to us. Does MidiTest have any (static or nonstatic) initializer blocks? Is that println() statement really the only code in its constructor?
Of course, it helped if you traced down what is the exact error/exception causing the termination and where exactly does it originate from :-)

Categories

Resources