About citing external files in java application - java

I am writing a java application, in which I am automatically importing external csv files in background to do the computation. But the problem is that I am using "absolute" file path in my java program, the generated jar file will not work in another computer. Is there anyway in java to use a kind of "working directory path" so that I can still run the jar file in another computer as long as I put the csv files I'd like to import in the same folder with the jar file?
Thanks!

You can read a file using its name like
try (BufferedReader br = new BufferedReader(new FileReader("text.txt"))) {
String line;
while ((line=br.readLine())!=null) {
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
Here text.txt should be in the same working directory where the jar was executed.
You can also read the directory name from the command line, using the command line arguments like
public static void main(String[] args) {
//check if there were any command line arguments
if (args.length > 0) {
// args[0] is the first command line argument unlike C where args[0] would give u the executable's name
} else {
System.err.println("Usage: java -jar <jar_name> [directory_names..]");
}
}
You can also have a configuration file such as a properties file to read the directory names.

new File(".") give you the relative path
you can write relative path like that :
File file = new File(".\\CSVs\\myfile.csv");

System.getProperty("user.dir") will return you the working directory.
System.getProperty("user.dir")+"\\myfile.txt"
More informations here :system properties, oracle docs

Related

java - reading config file in same directory as jar file

I have a simple program in Intellij that I made just to test out reading file path of config file.
I created a simple test case where I would use a timer to print "Hello world" periodically in N intervals where N is in milliseconds and N is configurable.
This is the code:
public void schedule() throws Exception {
Properties props=new Properties();
String path ="./config.properties";
FileInputStream fis=new FileInputStream(path);
BufferedReader in1=new BufferedReader(new InputStreamReader(fis));
// InputStream in = getClass().getResourceAsStream("/config.properties");
props.load(in1);
in1.close();
int value=Integer.parseInt(props.getProperty("value"));
Timer t=new Timer();
t.scheduleAtFixedRate(
new TimerTask() {
#Override
public void run() {
// System.out.println("HELEOELE");
try {
// test.index();
System.out.println("hello ");
} catch (Exception e) {
e.printStackTrace();
}
}
},
0,
value);
}
What I did was I set value as N in a config file where it can be changed by anyone without touching the actual code. So I compiled the jar file, and I placed both config.properties and jar file in same folder or directory. I want to be able to change make N changeable so I don't need to re-compile the jar again and again everytime.
Note: the config properties file is created manually and placed in same directory as the jar. And I am executing the jar in command prompt.
However, it seems when I try to run it, it doesn't recognize the file path.
"main" java.io.FileNotFoundException: .\config.properties (The system cannot find the file specified)
I've looked into many issues regarding reading config files outside of jar file and none of them worked for me. Am I doing any mistake here?
./config.properties is a relative path that points to a config.properties file in the current working directory.
The current working directory, unless changed by System.setProperty("user.dir", newPath), will be the directory from which you launched the JVM currently handling your code.
To get your jar to work as it currently is, you have two ways available :
copy the config.properties file to the directory you are executing java from
change the directory you are running java from to the one that contains the config.properties
You may also consider letting the user specify where to get the properties file from :
String path = System.getProperty("propertiesLocation", "config.properties");
You would then be able to specify a location for the property file when calling your jar :
java -jar /path/to/your.jar -DpropertiesLocation=/path/to/your.properties
Or call it as you did before to search for the properties at its default location of config.properties in the current working directory.

Inputting file name through main function argument (args[0])

EDIT: to run my code i am using "java filename.java input1.txt" is this correct?
I am creating a program where i have to tokenize a string into separate words and that string is in a text file. I have to specify the text file name in the terminal through command line arguments (args[0], etc). I am able to scan and print the content of the text file if i specify through paths but when i try to do it using args[0] it doesn't seem to work. I am using net beans. I will attach my section of code here:
public static void main(String[] args) {
try {
File f = new File(args[0]);
//using this commented out section using paths works File f = new
//File("NetBeansProjects/SentenceUtils/src/input1.txt");
Scanner input = new Scanner(new FileInputStream(f));
while(input.hasNext()) {
String s = input.next();
System.out.println(s);
}
} catch(FileNotFoundException fnfe) {
System.out.println("File not found");
}
SentenceUtils s = new SentenceUtils();
}
java filename.java input1.txt
is not correct for running a java program, you need to compile the *.java file to get a *.class file which you can then run like:
java filename input1.txt
assuming your class is in the default package and you are running the command in the output directory of your compile command, or using the fully qualified class name of the class, i.e. including the package name. For example if your class is in the package foo/bar/baz (sub folders in your source folder) and has the package declaration package foo.bar.baz;, then you need to specify your class like this:
java [-cp your-classpath] foo.bar.baz.filename input1.txt
for input1.txt to be found it has to be in the same directory where you run the command.
your-classpath is a list of directories separated by a system dependent delimiter (; for windows, : for linux, ...) or archives which the java command uses to look up the class to run specified and its dependencies.
NetBeansProjects/SentenceUtils/src/input1.txt is a relative path.
File f = new File("NetBeansProjects/SentenceUtils/src/input1.txt");
if this works then it means that the current working directory (i.e. the directory from which all relative paths are calculated) is the the rectory named NetBeansProjects.
You get FileNotFoundException because your file is expected to be in
NetBeansProjects/input1.txt
To find out which is the current working directory for your running program you can add the following statement:
System.out.println(new File("").getAbsolutePath());
Place input.txt in that directory and it will be found.
Alternatively you can pass the absolute path of your input file. an absolute path is a path that can be used to locate your file from whatever location your program is running from on your local filesystem. For example:
java -cp <your-classpath> <fully-qualified-name-of-class> /home/john/myfiles/myprogects/...../input1.txt
To sum up, what you need to know/do is the following:
the location of your program class and its package (filename)
the location of your input file (input.txt)
pass the correct argument accordingly

Can't load in txt file on the command line

I am unable to load in a txt file on the command line but in eclipse it loads fine. Below is the code that loads in the file.
try{
BufferedReader in =
new BufferedReader(new FileReader("piratewords.txt"));
int count = 0;
while (in.ready()) { //while there is another line in the input file
game.puzzles[count] = in.readLine(); //get line of data
count++; //Increment CWID counter
}
in.close();
}
catch(IOException e){
System.out.println("Error during reading/writing");
}
Kindly give the absolute path of file in FileReader("absolute path").Or place the txt file where your java source file is present.
piratewords.txt file should be available inside a classpath or else we need to specify
full absolute path of the location where the file is.
looks like when you are running it from command line, you are not keeping this file
in the required classpath.
better give absolute path of the file and check it.
absolute path like below
BufferedReader in = new BufferedReader(
new FileReader("C:/Users/karibasappagc/Desktop/piratewords.txt"));
and make sure file existence in the specified path.
This happens because the file is not in the classpath of your JVM.
Check Eclipse running classpath or use absolute path for your piratewords.txt. The file should at least be in your classes folder or you should add the folder it's in, in your classpath.

How to create a working .jar for a java project w/ excel input and System.out.print output?

I created this java project that basically gets data from an user determined excel file and uses Syste.out.println() to display the results. It works as I want it to in eclipse, however when I exported is as a .jar file, it doesn't work properly. It prompts for the excel file location to be entered, however, does not display the output, not even an error. I do not know how to do it from the terminal so I'm running it by double-clcking it. Also, I want the user to choose any excel file they want, so what should they write down as the location when prompted to do so? Right now, the excel file is in the same directory as the project. So just the name of the excel file is enough input, but what if it is not in the directory, how do i show it's location then?
Thank you
First of all, in your JAR file the file META-INF/MANIFEST.MF must contain your main class (i.e. the class with the main() method), with a line like this:
Main-Class: mypackage.MyMainClass
Make sure your settings in Eclipse are generating this line when generating the JAR file.
You can run it from the terminal with java -jar yourapp.jar however I presume that you have some extra libraries you need to include in the classpath with the -cp switch.
The working directory is normally the directory from where you are running the application. If you want to specify a different path it has to be either relative to that, or absolute.
An absolute path in windows would be something like: "C:\mydatafolder\myexcelsheet.xls"
An absolute path in Unix would be something like: "/home/myaccount/mydatafolder/myexcelsheet.xls"
You need to read System.in to get the file path, with a function like this:
private static String getFilePath () {
String filePath = null;
while (true) {
System.out.println("Please input the path of the file:");
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
filePath = br.readLine();
File file = new File(filePath);
if (!file.exists()) {
System.out.println("Sorry, invalid file path. Please try again.");
} else {
return filePath;
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("Sorry, unexpected error happened, Please try again.");
}
}
}

How to pass a text file as a argument?

Im trying to write a program to read a text file through args but when i run it, it always says the file can't be found even though i placed it inside the same folder as the main.java that im running.
Does anyone know the solution to my problem or a better way of reading a text file?
Do not use relative paths in java.io.File.
It will become relative to the current working directory which is dependent on the way how you run the application which in turn is not controllable from inside your application. It will only lead to portability trouble. If you run it from inside Eclipse, the path will be relative to /path/to/eclipse/workspace/projectname. If you run it from inside command console, it will be relative to currently opened folder (even though when you run the code by absolute path!). If you run it by doubleclicking the JAR, it will be relative to the root folder of the JAR. If you run it in a webserver, it will be relative to the /path/to/webserver/binaries. Etcetera.
Always use absolute paths in java.io.File, no excuses.
For best portability and less headache with absolute paths, just place the file in a path covered by the runtime classpath (or add its path to the runtime classpath). This way you can get the file by Class#getResource() or its content by Class#getResourceAsStream(). If it's in the same folder (package) as your current class, then it's already in the classpath. To access it, just do:
public MyClass() {
URL url = getClass().getResource("filename.txt");
File file = new File(url.getPath());
InputStream input = new FileInputStream(file);
// ...
}
or
public MyClass() {
InputStream input = getClass().getResourceAsStream("filename.txt");
// ...
}
Try giving an absolute path to the filename.
Also, post the code so that we can see what exactly you're trying.
When you are opening a file with a relative file name in Java (and in general) it opens it relative to the working directory.
you can find the current working directory of your process using
String workindDir = new File(".").getAbsoultePath()
Make sure you are running your program from the correct directory (or change the file name so that it will be relative to where you are running it from).
If you're using Eclipse (or a similar IDE), the problem arises from the fact that your program is run from a few directories above where the actual source is located. Try moving your file up a level or two in the project tree.
Check out this question for more detail.
The simplest solution is to create a new file, then see where the output file is. That is the correct place to put your input file into.
If you put the file and the class working with it under same package can you use this:
Class A {
void readFile (String fileName) {
Url tmp = A.class.getResource (fileName);
// Or Url tmp = this.getClass().getResource (fileName);
File tmpFile = File (tmp);
if (tmpFile.exists())
System.out.print("I found the file.")
}
}
It will help if you read about classloaders.
say I have a text file input.txt which is located on the desktop
and input.txt has the following content
i came
i saw
i left
and below is the java code for reading that text file
public class ReadInputFromTextFile {
public static void main(String[] args) throws Exception
{
File file = new File(
"/Users/viveksingh/desktop/input.txt");
BufferedReader br
= new BufferedReader(new FileReader(file));
String st;
while ((st = br.readLine()) != null)
System.out.println(st);
}
}
output on the console:
i came
i saw
i left

Categories

Resources