I've created this class for access/create some files:
public static File getFile(String filePath) throws IOException {
File file = new File(filePath);
if (file.exists() && !file.isDirectory()) {
return file;
} else {
file.createNewFile();
byte[] dataToWrite = "some text".getBytes();
FileOutputStream out = new FileOutputStream(file);
out.write(dataToWrite);
out.close();
return file;
}
}
I'm calling the class this Way:
getFile("myfile.txt");
The application tries to access the file, if there isn't specific file, it'll be created.
The problem is when I run this code under non-admin account, I'll get IOException for permission issues. I know that the file will be created in eclipse folder. Also I shouldn't use static file path for my project, It should work dynamically. What should I do?
Unless this is a class assignment, I would not write low-level File code any more. Look at Apache Commons IO and/or Google Guava.
Also, without any more detailed path, the file is looked for (and created) in whatever location the app is run in. In Eclipse, that's the project's root folder by default, you can change it in the Launch Configuration. Launch Configurations are created automatically when you do Run as... on a project or file; they can be edited via the Run > Run Configurations... or Run > Debug Configurations... menu. Note that Run and Debug configurations are actually the same under the covers, the only difference is how Eclipse launches the JVM (either in debug mode or not).
You can also invoke and/or edit them via toolbar buttons:
See more info at http://help.eclipse.org/luna/index.jsp?topic=%2Forg.eclipse.jdt.doc.user%2Ftasks%2Ftasks-java-local-configuration.htm
Regarding the permission issue there is no going around that. You should capture the Exception and interact with the user telling that the user doesn't have permission and should/could provide another path.
You have to capture the path from the user maybe from the console, application parameters or another file.
One of the options is to capture the arguments when the application is called, for example:
public static void main (String args [])
{
//First argument is the file path
String path = args[0];
File theFile = null;
if(args[0] != null){
try{
File theFile = File getFile(path);
//do stuff with the file
}catch(IOException ioe){
//NManage the Exception here
}
}
}
Related
I am working on a game in Java and I have a class that reads an audio file as InputStream and then plays that file through AudioPlayer.
I keep getting a file not found exception.
I have tried placing the audio files in many different locations, and nothing has worked.
This is my class code:
public void play(String string,int sleep) throws IOException
{
//this part does not recognize file
try {
//System.out.println(System.getProperty());
AS = new AudioStream(new FileInputStream(string));
AD = AS.getData();
loop = new ContinuousAudioDataStream(AD);
}
catch(IOException error){
System.out.print(string +" file not found");
}
AP.start(loop);
}
I pass a string like ("audio/beginning.wav")
You are using a path that is relative to the working directory defined when your program runs.
If you are running the program from Eclipse, by default it's the root directory of your program (top-level folder of the program). So normally placing the file in program_folder/audio/beginning.wav should work.
However, the working directory can be changed in the Run Configuration that you are using in Eclipse to run the program: go to the tab Arguments, and you'll find Working directory.
To debug the problem, check the output of the following:
System.out.println(new File("").getAbsolutePath());
Another option is to use the absolute path of the file.
I've a JavaFX application that I packaged it using antBuild to build a single installer .exe file, my app have some configuration files that was placed in the root of the project this way i load them from the root of the project in order to they can be place beside the .jar file and could be changable:
try {
File base = null;
try {
base = new File(MainApp.class.getProtectionDomain().getCodeSource().getLocation().toURI())
.getParentFile();
} catch (URISyntaxException e) {
System.exit(0);
}
try {
File configFile = new File(base, "config.properties");
}
so after packaging the app even if I put the files manually in the same place with jar file, again the app can not recognize them and put into error.
So what is the proper way to store and where to store some sort of config files and how to add them to the installer to put it to right place during installation?
If your application is bundled as a jar file, then MainApp.class.getProtectionDomain().getCodeSource().getLocation().toURI() will return a jar: scheme URI. The constructor for File taking a URI assumes it gets a file: scheme URI, which is why you are getting an error here. (Basically, if your application is bundled as a jar file, the resource config.properties is not a file at all, its an entry in an archive file.) There's basically no (reliable) way to update the contents of the jar file bundling the application.
The way I usually approach this is to bundle the default configuration file into the jar file, and to define a path on the user file system that is used to store the editable config file. Usually this will be relative to the user's home directory:
Path configLocation = Paths.get(System.getProperty("user.home"), ".applicationName", "config.properties");
or something similar.
Then at startup you can do:
if (! Files.exists(configLocation)) {
// create directory if needed
if (! Files.exists(configLocation.getParent())) {
Files.createDirectory(configLocation.getParent());
}
// extract default config from jar and copy to config location:
try (
BufferedReader in = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("/config.properties")));
BufferedWriter out = Files.newBufferedWriter(configLocation);) {
in.lines().forEach(line -> {
out.append(line);
out.newLine();
});
} catch (IOException exc) {
// handle exception, e.g. log and warn user config could not be created
}
}
Properties config = new Properties();
try (BufferedReader in = Files.newBufferedReader(configLocation)) {
config.load(in);
} catch (IOException exc) {
// handle exception...
}
So this checks to see if the config file already exists. If not, it extracts the default config from the jar file and copies its content to the defined location. Then it loads the config from the defined location. Thus the first time the user runs the application, it uses the default configuration. After that, the user can edit the config file and subsequently it will use the edited version. You can of course create a UI to modify the contents if you like. One bonus of this is that if the user does something to make the config unreadable, they can simply delete it and the default will be used again.
Obviously this can be bullet-proofed against exceptions a little better (e.g. handle case where the directory is unwritable for some reason, make the config file location user-definable, etc) but that's the basic structure I use in these scenarios.
I am working on building a web application around a Standalone JAR application. Essentially the JAR application reads an input file, processes it and generates an output file.
The input file is placed like this, right next to the JAR.
The code for the JAR application is shown below.
public class FileReadWriteApp {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
try {
File inFiles = new File("../inputFiles");
if (!inFiles.exists()) {
if (inFiles.mkdirs()) {
System.out.println("Input directory is created!");
} else {
System.out.println("Failed to create input directory!");
}
}
Path inputPath = FileSystems.getDefault().getPath("testInput.txt", new String[0]);
Files.copy(inputPath, new FileOutputStream("../inputFiles/testInput.txt"));
String content = new String(Files.readAllBytes(inputPath));
String parsedInput = content.toUpperCase();
new File("../outputFiles").mkdirs();
Files.write(Paths.get("../outputFiles/testOutput.txt"), parsedInput.getBytes());
} catch (IOException exc) {
System.out.println(exc);
System.exit(1);
}
}
Upon executing the JAR in the Command prompt it successfully creates inputFiles and outputFiles folders at one level higher than the JAR file and puts the corresponding input/output files correctly.
However, when I add the JAR as a dependency in the Spring based web application that I am building and place the input file and JAR file at the same location, it can't access the input file.
In the Spring web application I have placed both the input file and the JAR file as shown below:
I can even see them come up in the Target folder in the lib directory as shown below:
In my Spring Controller method, I am executing the main() method of the JAR file like this:
String[] args = new String[] { "" };
filereadwriteapp.FileReadWriteApp.main(args);
However, in the console I see these messages:
Input directory is created!
java.nio.file.NoSuchFileException: testInput.txt
I am not able to understand why the application can't find the file testInput.txt?
Can somebody kindly guide me regarding fixing this issue?
Is there some specific location where I should place the testInput.txt file so that the "dependency" JAR file can access it?
Kindly note that I am not loading a resource from WEB-INF directory from within the Web Application. In my case, I am having issue with a "dependency" JAR loading a resource from a relative path to itself.
Any help in this regard would be highly appreciated.
FileSystems api returns different path , so you need to use classpath to get the file as shown below
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("testInput.txt").getFile());
I'm building a Vaadin(basically Java that compiles to html/javascript) project and am trying to import a template(basically a HTML file). For all intents and purposes thought, I'm just importing a file as an input stream. Here is the offending code:
File file = new File("C:/JavaProjects/VaadinSpikeWorkspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/CISTVaadinClient/VAADIN/themes/layoutsinteractionDetailsTabLayout.html");
InputStream is = null;
CustomLayout custom = null;
try {
is = new FileInputStream(file);
} catch (FileNotFoundException e1) {
System.out.println("mark 1");
e.printStackTrace();
}
try {
custom = new CustomLayout(is);
} catch (IOException e) {
System.out.println("mark 2");
e.printStackTrace();
}
What I'm doing:
Deploying the Vaadin project (basically a dynamic web project with a few extra .jars) to tomcat and accessing thVe aadin Project using my browser
What I'm seeing:
A blank screen in my browser
File not found exception (i.e "mark 1")
And as a result: IOException (i.e. "Mark 2")
What I've checked:
The file definitely does deploy to tomcat with the rest of the project
Outside of the webapps folder, the file i'm trying to import is available via the browser once deployed (i.e. Localhost/myProject/MyFile.html)
The Tomcat install is fine (It was a fresh install and works with this/other projects outside of this problem)
What I've tried
Using a relative URL, or just the name of the file (i.e. New File( "../webapps/vaadin/layouts/MyFile.html") )
Using the absolute Path to the Project directory
Using the absolute path to the deploy directory (as above)
Putting the file somewhere else (read: Every single possible location in the project)
Again, I'm trying to simply read the file, MyFile.html as an input stream. What am I doing wrong/ overlooking?
Thanks for your time.
I had no problems reading files when using VaadinService which points to WebContent directory (with META-INF, VAADIN and WEB-INF inside). If it's run in the test environment then VaadinService is not available, so I use such piece of code:
private static final String BASEDIR;
static {
if (VaadinService.getCurrent() != null) {
BASEDIR = VaadinService.getCurrent().getBaseDirectory().getAbsolutePath();
} else {
BASEDIR = "WebContent";
}
}
then to navigate to VAADIN folder just use
BASEDIR+="/VAADIN/restOfYourPath"
Just in order to make it more portable: have you thought about bringing your templates into your classpath? Something like
yourApp/WEB-INF/classes/templates/layoutsinteractionDetailsTabLayout.html
This way, you only need this line of code, assuming you are into a Servlet or Spring Controller or Struts 1/2 action or whatever called YourClass:
InputStream is = YourClass.class.getClassLoader().getResourceAsStream("templates/layoutsinteractionDetailsTabLayout.html");
If you are really trying to use this file as an HTML template, you'll be much better off to leverage Vaadin's support for this. They have a CustomLayout which loads an HTML template from your theme.
Your template would go into a folder like the following:
VAADIN/themes/mytheme/layout/layoutsinteractionDetailsTabLayout.html
Note that mytheme is the name of your theme and layout is a specially recognized Vaadin directory within themes.
Your custom component would then look like:
public class InteractionDetailsTabLayout extends CustomLayout {
private static final String TEMPLATE = "layoutsinteractionDetailsTabLayout";
public InteractionDetailsTabLayout() {
super(TEMPLATE);
}
}
Note that the super constructor argument excludes the directory and file suffix.
If you actually want to load a file in your webapp, don't bother with it in your VAADIN directory but instead put it in your classpath resources and access it with the ClassLoader.
I am reading a file as follows:
File imgLoc = new File("Player.gif");
BufferedImage image = null;
try {
image = ImageIO.read(imgLoc);
}
catch(Exception ex)
{
System.out.println("Image read error");
System.exit(1);
}
return image;
I do not know where to place my file to make the Eclipse IDE, and my project can detect it when I run my code.
Is there a better way of creating a BufferedImage from an image file stored in your project directory?
Take a look in the comments for Class.getResource and Class.getResourceAsStream. These are probably what you really want to use as they will work whether you are running from within the directory of an Eclipse project, or from a JAR file after you package everything up.
You use them along the lines of:
InputStream in = MyClass.class.getResourceAsStream("Player.gif");
In this case, Java would look for the file "Player.gif" next to the MyClass.class file. That is, if the full package/class name is "com.package.MyClass", then Java will look for a file in "[project]/bin/com/package/Player.gif". The comments for getResourceAsStream indicate that if you lead with a slash, i.e. "/Player.gif", then it'll look in the root (i.e. the "bin" directory).
Note that you can drop the file in the "src" directory and Eclipse will automatically copy it to the "bin" directory at build time.
In the run dialog you can choose the directory. The default is the project root.
From my experience it seems to be the containing projects directory by default, but there is a simple way to find out:
System.out.println(new File(".").getAbsolutePath());
Are you trying to write a plugin for Eclipse or is it a regular project?
In the latter case, wouldn't that depend on where the program is installed and executed in the end?
While trying it out and running it from Eclipse, I'd guess that it would find the file in the project workspace. You should be able to find that out by opening the properties dialog for the project, and looking under the Resource entry.
Also, you can add resources to a project by using the Import menu option.
The default root folder for any Eclipse project is also a relative path of that application.
Below are steps I used for my Eclipse 4.8.0 and Java 1.8 project.
I - Place your file you want to interact with along the BIN and SRS folders of your project and not in one of those folders.
II - Implement below code in your main() method.
public static void main(String [] args) throws IOException {
FileReader myFileReader;
BufferedReader myReaderHelper;
try {
String localDir = System.getProperty("user.dir");
myFileReader = new FileReader(localDir + "\\yourFile.fileExtension");
myReaderHelper = new BufferedReader(myFileReader);
if (myReaderHelper.readLine() != null) {
StringTokenizer myTokens =
new StringTokenizer((String)myReaderHelper.readLine(), "," );
System.out.println(myTokens.nextToken().toString()); // - reading first item
}
} catch (FileNotFoundException myFileException) {
myFileException.printStackTrace(); } } // End of main()
III - Implement a loop to iterate through elements of your file if your logic requires this.