I have a text file that gets written to a network folder and I want my users to be able to click on a jar file which will read in the text file, sort it, and output a sorted file to the same folder. But I'm having trouble formatting the syntax of the InputStream to read the file in.
When I use a FileReader instead of an InputStreamReader the following code works fine in eclipse, but returns empty when run from the jar. When I change it to InputStream like my research suggests - I get a NullPointerException like it can't find the file.
Where did I go wrong? :)
public class sort {
/**
* #param args
*/
public static void main(String[] args) {
sort s = new sort();
ArrayList<String> farmRecords = new ArrayList<String>();
farmRecords = s.getRecords();
String testString = new String();
if(farmRecords.size() > 0){
//do some work to sort the file
}else{
testString = "it didn't really work";
}
writeThis(testString);
}
public ArrayList<String> getRecords(){
ArrayList<String> records = new ArrayList();
BufferedReader br;
InputStream recordsStream = this.getClass().getResourceAsStream("./input.IDX");
try {
String sCurrentLine;
InputStreamReader recordsStreamReader = new InputStreamReader(recordsStream);
br = new BufferedReader(recordsStreamReader);
while ((sCurrentLine = br.readLine()) != null) {
System.out.println(sCurrentLine);
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
return records;
}
private static void writeThis(String payload){
String filename = "./output.IDX";
try {
BufferedWriter fr = new BufferedWriter(new FileWriter(filename));
fr.write(payload);
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
getResourceAsStream() loads files from the classpath. If you are running this from the command line, you would need the current directory (.) on the classpath. If you want to load arbitrary files from the file system, you should use FileInputStream (or FileReader to save having to subsequently wrap the input stream in a reader).
Using a FIS to get a file inside a jar will not work since the file is not on the file system per se. You should use getResrouceAsStream() for that.
Also, to access a file inside a jar, you must add an "!" to the file path. Is the file inside the jar? If not, then try a script to start the jar after passing the classpath:
start.sh
java -cp .:your.jar com.main.class.example.run
Execute this script (on linux) or modify it as per your platform.
Also, you can use the following code to print out the classpath. This way you can check whether your classpath contains the file?
ClassLoader sysClassLoader = ClassLoader.getSystemClassLoader();
// Get the URLs
URL[] urls = ((URLClassLoader) sysClassLoader).getURLs();
for (int i = 0; i < urls.length; i++) {
System.out.println(urls[i].getFile());
}
}
Related
In my program I made a saving and loading system for text files. The Save function works perfectly as intended but the Load gives a NullPointerException.
Here's the load function
String path = "C:\\Levels\\File.txt";
LevelHandler.loadLevel(path);
Here's the loadLevel function
public static void loadLevel(String file){
String level = LevelLoader.loadFileAsString(file);
//other, unimportant, code
}
And here's the loadFileAsString function
public static String loadFileAsString(String file){
StringBuilder builder = new StringBuilder();
try {
InputStream in = LevelLoader.class.getResourceAsStream(file);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in));
String line;
while((line = bufferedReader.readLine()) != null){
builder.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
}
return builder.toString();
}
It's failing because it's looking for the file in the class folder regardless of what directory I pass in. How can I get the location of the .jar regardless of where the user places it on their computer?
you can get the .jar related location using ./
./ provides related path of your jar
The fix I came up with was to remove the InputStreamreader
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
This will be able to read files from any specified location on the computer, but still not from inside the jar. However it works perfectly fine with pretty much any other specified location.
So, here's the problem: I'm working on a Java program that reads from a .csv file, and constructs objects out of it. I'm using InputStream, InputStreamReader, and BufferedReader to read the file. The IDE I'm using is NetBeans and the file being read is in the src directory. A quick note, for your convenience, I hardcoded the filename, so that you would understand how it's actually being read. In my actual program, the filename is being passed in as a parameter of the method. Anyways, it seems to work fine in the IDE. But when I create a JAR, it doesn't do what I want it to do.
public void readFile(filename) throws IOException, FileNotFoundException {
is = getClass().getResourceAsStream("file.csv");
isr = new InputStreamReader(is);
//fr = new FileReader(filename);
br = new BufferedReader(isr);
String info;
while ((info = br.readLine()) != null)
{
String[] tokens = info.split(",");
Object object = new Object();
object.setProperty(tokens[0]);
object.setAnotherProperty(tokens[1]);
object.setSomeOtherProperty(tokens[2]);
}
}
catch (FileNotFoundException f)
{
f.getMessage();
}
catch (IOException ioe)
{
ioe.getMessage();
}
catch (ArrayIndexOutOfBoundsException oob)
{
//;
}
catch (NullPointerException npe)
{
//;
}
finally
{
br.close();
isr.close();
is.close();
}
My method to update the file looks like this(once again, the filename has been hardcoded so you could better understand what's going on):
public void updateRoom(String filename, String property1, string property2, string property3) throws FileNotFoundException
{
for (Objects o : objects)
{
if (o.getProperty().equals(property1))
{
o.setProperty(property1);
o.setAnotherProperty(property2);
o.setSomeOtherProperty(property3);
}
}
File file = new File("file.csv");
PrintWriter pr = new PrintWriter(file);
for (Object o : objects)
{
pr.println(o.getProperty() + "," +
o.getAnotherProperty() + "," +
o.getSomeOtherProperty())
}
pr.close();
}
The problem is that the .JAR reads the file when I run it, but instead of writing to the SAME file, it simply creates a new one and writes to that one. It's a problem because every time I run the program again, the properties and values remain unchanged. It's NOT reading from the newly-created file. It's still reading from the original file, but it's writing to a new file.
I want to READ AND WRITE to the same file. That way, if I close the program and run it again, it will have the new properties/values already loaded in.
So the problem is I try to read the configuration file that is packed inside the .jar which works fine but then when it comes to writing to the file the file can not be found yet they are using the same
getClass().getResource(Path);
it only seems to work with the input stream.
Here is all the code of my IO class.
package com;
public class IO {
public boolean CheckStream () {
String LineRead;
try {
InputStream IS = getClass().getResourceAsStream("Config.txt");
InputStreamReader ISR = new InputStreamReader (IS,Charset.forName("UTf-8"));
BufferedReader BR = new BufferedReader(ISR);
if ((LineRead = BR.readLine()) != null) {
BR.close();
return true;
}
IS.close();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
public void Write (String Path, String [] ThingsToWrite) throws FileNotFoundException {
OutputStream Out = new FileOutputStream (getClass().getResource(Path).getPath());
PrintStream PS = new PrintStream (Out);
for (int i = 0; i < ThingsToWrite.length; i ++) {
PS.print(ThingsToWrite[i]);
}
PS.close();
}
}
Any Help is greatly appreciated thanks.
You can't just write to a file within a jar file - it's not a file in the regular sense.
While you could unpack the whole jar file, write the new content, then pack it up again, it would be better to redesign so that you don't need to update the jar file.
For example, you might have a regular local file which is used if it's present, but then fall back to reading from the jar file otherwise. Then you only need to write to the local file.
Goal: to read contents of a file that is in my root directory. Eventually I want to be able to read a .conf file, but right now I am testing with a .txt file since it seems easier to begin with..
I am using the open source Shell file from an XDA video to navigate to my root directory. For reference, the file is located at: "/data/misc/joke.txt"
This is the code in my main method:
String command[]={"su","-c","ls /data/misc"};
Shell shell = new Shell();
String output = shell.sendShellCommand(command);
try {
read(output);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
So basically all that is doing is granting SU permission, and then navigating to the /data/misc folder. Then in the Shell() class, I scan through each file and search for the text file I want. This might be redundant since I expect the text file to be "joke.txt" EVERYTIME. Anyways, I am having an issue with this block of code, the read() method:
public void read(String out) throws Exception{
File yourFile = new File("/data/misc", out);
FileReader file = new FileReader(yourFile);
BufferedReader reader = new BufferedReader(file);
String line;
String text = "";
line = reader.readLine();
while (line != null) {
text += (line);
line = reader.readLine();
}
setNewTextInTextView(text);
}
It crashes at this line:
FileReader file = new FileReader(yourFile);
Any tips?
I have an eclipse project and in one folder there is a text file "conf.txt". I can read and write the file when I use the path on my Computer. But I have to write my own folders there as well, not only the workspace folders.
So know I want to commit the program for others, but then the path I put in the program won't work, because the program is running on a different computer.
What I need is to be able to use the file with only the path in my workspace.
If I just put in the path, which is in the workspace it won't work.
This is how my class File looks like.
public class FileUtil {
public String readTextFile(String fileName) {
String returnValue = "";
FileReader file = null;
try {
file = new FileReader(fileName);
BufferedReader reader = new BufferedReader(file);
String line = "";
while ((line = reader.readLine()) != null) {
returnValue += line + "\n";
}
reader.close();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (file != null) {
try {
file.close();
} catch (IOException e) {
// Ignore issues during closing
}
}
}
return returnValue;
}
public void writeTextFile(String fileName, String s) throws IOException {
BufferedWriter output = new BufferedWriter(new FileWriter(fileName));
try {
output.write(s);
}
finally {
output.close();
}
}
}
I hope someone knows what to do.
Thanks!
I am not sure but I attached the screen shot with little bit explanation. Let me know if you have any question.
Your project is root folder here and images as resources folder from where you can access the file using relative path.
// looks for file in root --> file.txt
scan = new Scanner((new File("file.txt")));
// looks for file in given relative path i.e. root--> images--> file.txt
scan = new Scanner((new File("images/file.txt")));
If you want your configuration file to be accessed through a relative path, you shouldn't need to add anything to the front of it. Assuming you're using a bufferedReader, or something of the sort it would look as simple as: br = new BufferedReader(new FileReader("config.txt"));
This will cause a search of the runtime directory, making it so you don't have to fully qualify the path to your file. That being said you have to ensure your config.txt is within the same directory as your executable.