1

I have previously asked a question about how to import a file from xml on stackoverflow (Read here). The solution provided to me was to use

documentbuilder.parse( xmlhandler.class.getResourceAsStream("shutdownscheduler.xml")); 

This solution is picking the xml file from "C:\Users\Rohan Kandwal\Documents\NetBeansProjects\Shutdown Scheduler\build\classes\shutdown\scheduler\shutdownscheduler.xml"which is fine for read only purpose.

But i need documentbuilder to access file from location "C:\Users\Rohan Kandwal\Documents\NetBeansProjects\Shutdown Scheduler\src\shutdown\scheduler so that i can save updations made to the xml permanently. Is there a way to access file from src folder rather than build folder?

Community
  • 1
  • 1
Rohan Kandwal
  • 9,112
  • 8
  • 74
  • 107
  • see [http://stackoverflow.com/questions/2797367/write-to-a-file-stream-returned-from-getresourceasstream](http://stackoverflow.com/questions/2797367/write-to-a-file-stream-returned-from-getresourceasstream) – predi Jan 17 '13 at 13:00

1 Answers1

1

Usually when your application is supposed to write files it must do so in a place where it has write access. The only place where you can be sure (in most cases) that your app will be allowed to have such access is the user home directory. You might have noticed that other java based applications usually create a directory named ".some-application" in your home folder (in your case "C:\Users\Rohan Kandwal"). The reason (one of them) why they do so is write access.

You should do the same and forget about using Class.getResourceAsStream(...) for writeable files. You can get the path to your home directory via System.getProperty("user.home").

Note taht the reason why Class.getResourceAsStream(...) as used in your example is getting a file from your build directory is because you are running it within your IDE. If you run it outside the IDE this path will change. This is because the path to the class file (xmlhandler.class) will most likely change and Class.getResourceAsStream(...) relies on it to find the resource.

Also note that your src directory will most likely not even exist when the application is deployed. Even if it did, there's no way to know if your users will have it deployed in a location with write access. So what you are trying to do doesn't make much sense.

Edit01

This is an example of how you could do what you want. This will create a home directory for your application where you can write files any way you wish. If the file you want to preserve between application runs does not exist, it will be created and filled with the content of your resource file. Note that this is just an example.

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class ConfigDir {

    private static final String APP_DIR = ".myappdir";
    private static final String FILE_NAME = "shutdownscheduler.xml";

    private File fillFileFromTemplate(InputStream template, File file) throws FileNotFoundException, IOException {
            OutputStream out = null;
            try {
                out = new FileOutputStream(file);
                int read = 0;
                byte[] bytes = new byte[1024];
                while ((read = template.read(bytes)) != -1) {
                    out.write(bytes, 0, read);
                }
                out.flush();
                return file;
            } catch (FileNotFoundException ex) {
                throw ex;
            } finally {
                if (out != null) {
                    out.close();
                }
            }
        }

    public static void main(String[] argv) throws IOException {        
        String userdir = System.getProperty("user.home"); // user home directory
        // OR if you know that your program will run from a directory that has write access
        // String userdir = System.getProperty("user.dir"); // working directory
        if (!userdir.endsWith(System.getProperty("file.separator"))) {
            userdir += System.getProperty("file.separator");
        }
        String myAppDir = userdir + APP_DIR;
        File myAppDirFile = new File(myAppDir);
        myAppDirFile.mkdirs(); // create all dirs if they do not exist
        String myXML = myAppDir + System.getProperty("file.separator") + FILE_NAME;
        File myXMLFile = new File(myXML); // this is just a descriptor        
        ConfigDir cd = new ConfigDir();        
        if (!myXMLFile.exists()) {
            // if the file does not exist, create one based on your template
            // replace "ConfigDir" with a class that has your xml next to it in src dir
            InputStream template = ConfigDir.class.getResourceAsStream(FILE_NAME);  
            cd.fillFileFromTemplate(template, myXMLFile);
        }

        // use myXMLFile java.io.File instance for read/write from now on
        /*
        DocumentBuilderFactory documentbuilderfactory=DocumentBuilderFactory.newInstance();
        DocumentBuilder documentbuilder=documentbuilderfactory.newDocumentBuilder();
        Document document=(Document)documentbuilder.parse(myXMLFile);
        document.getDocumentElement(); 
        ...
        */        
    }    
}
predi
  • 5,528
  • 32
  • 60
  • I know that the path of my file will be changed when application is deployed. This is the reason i am not providing a direct path to the file i.e. `C:\Users\Rohan Kandwal\Documents\NetBeansProjects\Shutdown Scheduler\src\shutdown\scheduler ` . In my previous question also i asked the same thing that the file should always be imported from my package even if it is deployed. I was given a solution by the member which was working and i thought it to be correct. Can you please give me way such that the file is accessed even after deployment? – Rohan Kandwal Jan 17 '13 at 13:59
  • will this create a new blank xml file or copy the file to home directory from my package? Sry i am a noob. – Rohan Kandwal Jan 19 '13 at 05:42
  • @RohanKandwal, as stated in my edit, it creates a new blank file and fills it with content from your template file. – predi Jan 19 '13 at 18:48