Using "pathdir" on Java Applications - java

First, i'm using Ubuntu! :)
I need some help here,
I built a Java App, i want to set a default path tree, like this:
> cd /anyDirectory/meuRestaurante
> ls
bin/ data/
> cd bin
> ls
meuRestaurante.jar
> cd ..
> cd data
> ls
Cartoes.txt Clientes.txt
I want that my Java App save these txt's files on /data directory, while is on /bin directory.
Exctaly, how should be if i use these functions to read/save the txt's files.:
public static String readFile(String fileName) {
try {
File file = new File("."+fileName);
FileReader reader = new FileReader(file);
BufferedReader in = new BufferedReader(reader);
String string;
String returnString = "";
while ((string = in.readLine()) != null) {
returnString = "" + returnString + string;
}
in.close();
return returnString;
} catch (IOException e) {
System.err.println("readFile " + e.getMessage());
return null;
}
}
public static boolean writeFile(String fileName, String newContent){
try {
BufferedWriter out = new BufferedWriter(new FileWriter(fileName, true));
out.write(newContent);
out.close();
return true;
}catch(IOException e){
System.err.println("writeFile " + e.getMessage());
return false;
}
}
How should be the fileName?
Anyone has a tip ?

Try this:
data/Cartoes.txt

If these files are intended to be read only, put them in a Jar, add the Jar to the applications run-time class-path and access them using getResource().
If the files are intended to be written to (read/write), avoid attempting to save files in a location relative to the application executable(1). This will lead to no end of frustration later.
Instead, put the data files in a sub-directory of ${user.home}. The sub-directory is to help ensure that applications do not overwrite each others files. The sub-directory might be based on the package name of the main class of the app., which should be unique to your organization.
(1)
Neither applets nor apps. launched using Java Web Start are able to discover the location the app. is stored on the local disk.
Microsoft has been telling developers for years not to save program settings in the 'Program Files' folder.
While an app. is almost guaranteed of being able to write to/read from user home, the tightening of security in recent times means that other locations are much less reliable.

Related

Execute file from Android device programatically

I have finished my Chess UI application and now want to load a chess engine to test if my UI truly is UCI-compatible. The chess engine is inside the Download folder of the Android device ('/storage/emulated/0/Download'). This is the code that is run:
try {
File f = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
String path = f.getAbsolutePath();
String stockfishPath = path + "/Stockfish-9-armv64v8";
engineProcess = Runtime.getRuntime().exec(stockfishPath);
processReader = new BufferedReader(new InputStreamReader(
engineProcess.getInputStream()));
String sCurrentLine;
ArrayList<String> output = new ArrayList<>();
while ((sCurrentLine = processReader.readLine()) != null) {
output.add(sCurrentLine);
}
processWriter = new OutputStreamWriter(
engineProcess.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
}
When I run this it fails on the exec() method because it claims it cannot find the file, even though the file exists on the Android device. I tried running the "ls" command on the exec() method, but the folder inside "emulated" is empty. The obvious reason for this is probably because I do not have permission to view/access these files, but I need to know how I can do that (despite adding the READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE in the manifest file).
Is it maybe possible to embed the engine somewhere in the project (in resources?) and somehow adb-shell into that?
you cannot do that, simply because the SD card is being mounted with -noexec flag.
using the internal storage with chmod +x would be the only option available.

Creating temporary file and rename to actual file

I am trying to create a temporary file and then rename it to a usable file. The temp file is getting created in %temp% but not getting renamed:-
static void writeFile() {
try {
File tempFile = File.createTempFile("TEMP_FAILED_MASTER", "");
PrintWriter pw = new PrintWriter(tempFile);
for (String record : new String[] {"a","b"}) {
pw.println(record);
}
pw.flush();
pw.close();
System.out.println(tempFile.getAbsolutePath());
File errFile = new File("C:/bar.txt");
tempFile.renameTo(errFile);
System.out.println(errFile.getAbsolutePath());
System.out.println("Check!");
} catch (Exception e) {
e.printStackTrace();
}
}
There are a few reasons why a rename can fail. The common ones are:
You don't have write permission for the source or destination directory.
The file you are renaming is open (on Windows)
You are attempting to rename across different file systems.
It can be difficult to diagnose these (and other) failure reasons if you are using File.renameTo because all you get is a boolean return value.
I recommend using Files.move instead. It can cope with moving files between file systems, and will throw an exception if the file cannot be renamed.

Reading a TXT file in Java [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 7 years ago.
I keep getting a java.lang.NullPointerException when trying to open a txt file in eclipse. Basically, this is a main menu, and when you click the "Rules" button, the rules text file should open. Currently, the txt file is located in a package called "Resources" (which is where all of the other img files I've used in making the game are). Here's the code:
private List<String> readFile(String filename)
{
List<String> records = new ArrayList<String>();
try
{
BufferedReader buff = new BufferedReader(new InputStreamReader(
Configuration.class.getResourceAsStream(filename)));
String line;
while ((line = buff.readLine()) != null)
{
records.add(line);
}
buff.close();
return records;
}
catch (Exception e)
{
System.err.format("Exception occurred trying to read '%s'.", filename);
e.printStackTrace();
return null;
}
}
//action performed
public void actionPerformed(ActionEvent ae) {
JButton b = (JButton)ae.getSource();
if( b.equals(newGameButton) )
{
flag = true;
controller.startGame();
buttonPressed = "newGameBtn";
}
if(b.equals(quitButton))
{
System.exit(0);
}
if(b.equals(ruleButton)){
readFile("../resource/riskRules.txt");
}
}
Appreciate the help!
If "Resources" it's marked as resource in Eclipse. The txt file should be copied to your class path when you build.
As per what I can guess from your code you should be doing something like
Configuration.class.getResourceAsStream("riskRules.txt")
Since your file will be at the root level of your class path.
If for example the file is withing a dir called "text" in your resources you would use something like
Configuration.class.getResourceAsStream("text/riskRules.txt")
There needs to be some level of rudimentary error checking on the result returned from getResourceAsStream before you attempt to use it. Is there a reason you're using getResourceAsStream instead of getResource? If the file exists on disk (I see from your OP that it's because it's in a package, and may not physically exist on the disk), then you can just use that to return the path to it, and create a file object from it.
String path = "/path/to/resource"; // note the leading '/' means "search from root of classpath"
URL fileUrl = getClass().getResource(path);
if (fileUrl != null ) {
File f = new File(fileUrl.toURI());
BufferedReader = new BufferedReader(new FileReader(f));
// do stuff here...
}
else {
// file not found...
}
If you need to pull the file out of the JAR archive, then you can do this:
String path = "/path/to/resource"; // note the leading '/' means "search from root of classpath"
InputStream is = getClass().getResourceAsStream(path);
if (is != null ) {
BufferedReader = new BufferedReader(new InputStreamReader(is));
// do stuff here...
}
else {
// file not found...
}
In the event your resource is not found, you will avoid the NPE and you can properly account for the fact that it's missing.
Note that if you do have your resources in a package (jar), then you cannot use a path to locate it that uses "..", since there is no "relative path" in a jar archive, it's not actually a file on the filesystem.
Your "resources" are located by the relative path you specify in the getResource... method. A leading "/" means to look at the root of your classpath for locating the resource. No leading "/" means to look relative to the location of the class file that you're using to locate the resource.
If your file is in a location called "com.program.resources", and you're trying to locate it from a class called "com.program.someotherpackage.MyClass", then you'd use:
getClass().getResourceAsStream("/com/program/resources/<file.txt>");
to find it.
Here's my example illustrated:
<classpath root>
com
program
resources
file.txt
img.png
someotherpackage
MyClass.class
Generally, it's common practice to leave resources outside your package structure, to avoid confusion when locating them later. Most IDE's have a way to mark your directories as resources, so when the program is compiled, they will be copied to the proper location in the classpath root, and can be found by any class asking for them.

How to read from a file not in Eclipse in Java

I have a file which is needed for running tests - this file needs to be personalized (name and password) by whomever is running the test. I do not want to store this file in Eclipse (since it would need to be changed by whomever runs the test; also it would be storing personal info in the repo), so I have it in my home folder (/home/conrad/ssl.properties). How can I point my program to this file?
I've tried:
InputStream sslConfigStream = MyClass.class
.getClassLoader()
.getResourceAsStream("/home/" + name + "/ssl.properties");
I've also tried:
MyClass.class.getClassLoader();
InputStream sslConfigStream = ClassLoader
.getSystemResourceAsStream("/home/" + name + "/ssl.properties");
Both of these give me a RuntimeException because the sslConfigStream is null. Any help is appreciated!
Use a FileInputStream to read data from a file. The constructor takes a string path (or a File object, which encapsulates string path).
Note 1: A "resource" is a file which is in the classpath (alongside your java/class files). Since you don't want to store your file as a resource because you don't want it in your repo, ClassLoader.getSystemResourceAsStream() is not what you want.
Note 2: You should use a cross-platform way of getting a file in a home directory, as follows:
File homeDir = new File(System.getProperty("user.home"));
File propertiesFile = new File(homeDir, "ssl.properties");
InputStream sslConfigStream = new FileInputStream("/home/" + name + "/ssl.properties")
You can simplify your work, using Java's 7 method:
public static void main(String[] args) {
String fileName = "/path/to/your/file/ssl.properties";
try {
List<String> lines = Files.readAllLines(Paths.get(fileName),
Charset.defaultCharset());
for (String line : lines) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
You can also improve your way of reading properties file, using Properties class and forget about reading and parsing your .properties file:
http://www.mkyong.com/java/java-properties-file-examples/
Is this a graphics program (ie. using the Swing library)? If so it is a pretty simple task of using a JFileChooser.
http://docs.oracle.com/javase/6/docs/api/javax/swing/JFileChooser.html
JFileChooser f = new JFileChooser();
int rval = f.showOpenDialog(this);
if (rval == JFileChooser.APPROVE_OPTION) {
// Do something with file called f
}
You can also use Scanner to read the file.
String fileContent = "";
try {
Scanner scan = new Scanner(
new File( System.getProperty("user.home")+"/ssl.properties" ));
while(scan.hasNextLine()) {
fileContent += scan.nextLine();
}
scan.close();
} catch(FileNotFoundException e) {
}

Java: Error when save file in Resource after Deployment

My program has a function that read/write file from resource. This function I have tested smoothly.
For example, I write something to file, restart and loading again, I can read that data again.
But after I export to jar file, I faced problems when write file. Here is my code to write file:
URL resourceUrl = getClass().getResource("/resource/data.sav");
File file = new File(resourceUrl.toURI());
FileOutputStream output = new FileOutputStream(file);
ObjectOutputStream writer = new ObjectOutputStream( output);
When this code run, I has notice error in Command Prompt:
So, My data cannot saved. (I know it because after I restarted app, nothing changed !!!)
Please help me solve this problem.
Thanks :)
You simply can't write files into a jar file this way. The URI you get from getResource() isn't a file:/// URI, and it can't be passed to java.io.File's constructor. The only way to write a zip file is by using the classes in java.util.zip that are designed for this purpose, and those classes are designed to let you write entire jar files, not stream data to a single file inside of one. In a real installation, the user may not even have permission to write to the jar file, anyway.
You're going to need to save your data into a real file on the file system, or possibly, if it's small enough, by using the preferences API.
You need to read/write file as an input stream to read from jar file.
public static String getValue(String key)
{
String _value = null;
try
{
InputStream loadedFile = ConfigReader.class.getClassLoader().getResourceAsStream(configFileName);
if(loadedFile == null) throw new Exception("Error: Could not load the file as a stream!");
props.load(loadedFile);
}
catch(Exception ex){
try {
System.out.println(ex.getMessage());
props.load(new FileInputStream(configFileName));
} catch (FileNotFoundException e) {
ExceptionWriter.LogException(e);
} catch (IOException e) {
ExceptionWriter.LogException(e);
}
}
_value = props.getProperty(key);
if(_value == null || _value.equals("")) System.out.println("Null value supplied for key: "+key);
return _value;
}

Categories