Чтение / запись XML-файла из пакета приложений Java - PullRequest
1 голос
/ 04 мая 2010

У меня есть файл XML, который анализируется и записывается в моем приложении. Изнутри моей IDE (Eclipse) я просто обращаюсь к этому так:

Чтение:

private String xmlFile = "file.xml";

и затем я создаю документ:

doc = sax.build(xmlFile);

Запись ведется так:

writer = new FileWriter("file.xml");

Пока работает отлично, но после связывания моего приложения файл больше не доступен. Что именно мне нужно сделать, чтобы сделать его доступным из пакета приложений? Я абсолютно не знаком с classpath или чем-то, что мне нужно для этого, поэтому, пожалуйста, будьте осторожны со мной!

Большое спасибо!

Ответы [ 7 ]

2 голосов
/ 05 мая 2010

Питер,

Я столкнулся с подобной проблемой, и, поскольку вы новичок в этом, я начну с этого: когда вы упаковываете файл в jar, он сжимается и, таким образом, обращается к нему, как у вас в оригинальный код не будет работать, так как мы не можем прочитать файлы, сжатые в банке. Вместо этого вам нужно попросить Java вытащить этот ресурс в виде потока (как и многие другие любезно указали), который Java знает, как предоставить вам.

Теперь вывод файла оттуда - это боль. Вот некоторый код, который я написал некоторое время назад, чтобы сделать это, который, конечно, из какого-то другого источника, который я нашел. Заполните исключения по мере необходимости! =)

        InputStream in = null;
        in = this.getClass().getResourceAsStream("/main.cc");

        File outputFile = createMainOutputFile();
        OutputStream out = null;
        try {
            out = new FileOutputStream(outputFile);
        } catch (FileNotFoundException e) {
            System.out.println(outputFile + " was not found!");
            e.printStackTrace();
        }

        // Transfer bytes from in to out 
        byte[] buf = new byte[1024]; 
        int len; 
        try {
            while ((len = in.read(buf)) > 0) { 
                out.write(buf, 0, len); 
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        try {
            in.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        try {
            out.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 

На самом деле мы должны выводить файл по частям, к сожалению, я знаю, я действительно хочу, чтобы то, что вы надеялись сделать, сработало! Это сделало бы жизнь намного проще. Единственное, что может сбить с толку - это вызов createMainOutputFile (), так что вот код для этого тоже ...

private File createMainOutputFile() {
    File directoryPath = new File(mainOutputFolder);
    directoryPath.mkdirs();
    File newFile = new File (mainOutputFolder + "main.cc");
    try {
        newFile.createNewFile();
    } catch (IOException e) {
        System.out.println("failed To create new file.");
        e.printStackTrace();
    }
    return newFile;
}

Удачи!

Редактировать: Теперь, когда я заметил, что вы на самом деле анализируете его с помощью синтаксического анализатора XML, я укажу вам, что если вы используете синтаксический анализатор SAX (по крайней мере, Apache), вы обнаружите, что он действительно принимает inputStream так же, как и файл:

DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = null;
        try {
            docBuilder = docFactory.newDocumentBuilder();
        } catch (ParserConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            //Here we supply the inputStream instead of the file...
            doc = docBuilder.parse(inputStream);
        } catch (SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        Node xmlRoot = doc.getFirstChild();
2 голосов
/ 04 мая 2010

Для чтения файла вы можете создать BufferedReader следующим образом:

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(
    getClass().getResourceAsStream("file.xml")));

Вы можете записать файл, как и раньше, но следите за тем, куда он был записан - тогда вы можете перечитать файл оттуда, если это необходимо.

1 голос
/ 05 мая 2010

Лучший вариант решения этой распространенной проблемы: Абсолютный путь к местоположению вне jar / war.

Само приложение может быть развернуто где угодно, но на хосте должна быть общая файловая область, такая как "/ common/ files / someApplication "

Еще лучше иметь конфигурацию для указания (во время сборки или во время выполнения), какой путь использовать.Например, для сборки dev будет использоваться "/ dev / myprojects / someApplication"

Не самое удачное решение: развернуть как разнесенный файл войны.Чтение и запись не являются проблемой, но теперь вы вызываете зависимость развертывания.

1 голос
/ 04 мая 2010

Я не могу комментировать, поэтому мой ответ относится к ответу LES2.Хитрость в том, что ваш файл file.xml должен находиться в пути к классам, если вы хотите использовать загрузчик классов.

Обычно он включается в classpath, если он находится в вашем JAR-файле.чтобы проверить, есть ли он, откройте банку с 7zip или любой другой программой zip.Если файл не находится внутри jar, вы должны отправить его вместе с jar и вручную добавить его в classpath при запуске приложения.

Допустим, файл.xml и jar находятся в одном каталоге.тогда

java -cp .:myjar.jar com.example.Main

должно помочь.

1 голос
/ 04 мая 2010

Представьте, что у вас есть пакет с именем myXmlDir, поместите файл file.xml в этот пакет (фактически каталог)

Обратите внимание, что этот пакет упакован с вашим классом внутри jar и может быть доступен для classLoader.

См. Этот код, который возвращает входной поток:

return SomeClass.class.getClassLoader().getResource("myXmlDir/file.xml").openStream();

вы также можете вместо openStream () активировать функцию getFile ()

1 голос
/ 04 мая 2010

Использовать файл как свойство. Вы можете делать с этим все, что захотите. Для доступа используйте

Class.getResourceAsStream()

или эквивалентный метод. Проверьте эту ссылку на несколько советов: http://www.javaworld.com/javaworld/javaqa/2003-08/01-qa-0808-property.html?page=2

Edit:
Мне жаль говорить, что мое предложение не так хорошо, как я думал. Я чувствовал, что однажды сделал что-то, как ты хочешь, но я посмотрел на приложение, и все, что я сделал, это прочитал файлы. Я также немного погуглил и нашел эту запись форума, которая немного устарела, но, учитывая отсутствие прогресса со стороны Sun, я считаю, что его суть все еще действительна: http://lists.apple.com/archives/Java-dev/2003/Feb/msg00876.html

Обычно, если вы хотите что-то написать, либо потребуйте, чтобы пользователь извлек jar перед запуском, либо (мое предложение) создайте каталог в том же каталоге, в котором находится jar, и запишите свой файл в этот каталог. Если вам действительно нужно, вы можете даже создать еще один jar-файл с этим файлом и всеми файлами исходного jar-файла, что, конечно, оставит вам два архива.

Извините, что поднял ваши надежды.

0 голосов
/ 04 мая 2010

Ваш ввод должен быть абсолютным или относительным путем к файлу ....

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...