Java 带有ini4j的单态模式

Java 带有ini4j的单态模式,java,singleton,inputstream,fileinputstream,Java,Singleton,Inputstream,Fileinputstream,原始问题:程序正在读取旧配置文件(.ini)的输入 新问题:在尝试使用stream/ini的单例模式后,我无法再写入文件了。它抛出了一个java.io.FileNotFoundException 我是否可以修改配置类以使其正常工作 提前谢谢 配置类: import org.ini4j.Wini; import java.io.*; //http://www.javenue.info/post/40 public class Configuration { private static

原始问题:程序正在读取旧配置文件(.ini)的输入

新问题:在尝试使用stream/ini的单例模式后,我无法再写入文件了。它抛出了一个java.io.FileNotFoundException

我是否可以修改配置类以使其正常工作

提前谢谢

配置类:

import org.ini4j.Wini;
import java.io.*;

//http://www.javenue.info/post/40

public class Configuration {
    private static Configuration _instance = null;

    private Wini ini = null;
    FileInputStream stream;

    private Configuration() {
        ini= new Wini();
        try {
            stream = new FileInputStream(Constants.PATH);
            ini.load(stream);
        }
        catch (Exception e) {
            System.out.println("FILE NOT FOUND!");
        }
    }

    public synchronized static Configuration getInstance() {
        if (_instance == null)
            _instance = new Configuration();
        return _instance;
    }

    public String getConfig(String xSectionName, String xFieldValue){

        String readValue = null;

        if (ini.get(xSectionName, xFieldValue) != null) {
            readValue = ini.get(xSectionName, xFieldValue);
        } else {
            // TODO: What should happen
        }
        return readValue;
    }

    public void setConfig(String xSectionName, String xFieldValue, String xValue){

        System.out.println("Section: " + xSectionName);
        System.out.println("Field:   " + xFieldValue);
        System.out.println("Value:   " + xValue + "\n\n");

        try {
            ini.put(xSectionName, xFieldValue, xValue);
            ini.store();
        } catch (Exception e1) {
            System.out.println(xValue + " could not be stored.");
            e1.printStackTrace();
        }
    }
}
章节:漂移

字段:mu

价值:5

5无法存储

org.Ini.Ini.store上的java.io.FileNotFoundException(Ini.java:126) 在 application.prototype.Configuration.setConfig(Configuration.java:72) 位于application.prototype.UserInputs.lambda$0(UserInputs.java:92) com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86) 在 com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238) 在 com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191) 在 com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59) 在 com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) 在 EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 在 com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) 在 EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 在 com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) 在 EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 位于com.sun.javafx.event.EventUtil.fireventimpl(EventUtil.java:74) 位于com.sun.javafx.event.EventUtil.firevent(EventUtil.java:54) javafx.event.event.fireEvent(event.java:198)位于 位于的javafx.scene.scene$KeyHandler.process(scene.java:3964) javafx.scene.scene$KeyHandler.access$1800(scene.java:3910)位于 javafx.scene.scene.impl_processKeyEvent(scene.java:2040)位于 javafx.scene.scene$ScenePeerListener.keyEvent(scene.java:2501)位于 com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:216) 在 com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:148) 位于java.security.AccessController.doPrivileged(本机方法) com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleKeyEvent$353(GlassViewEventHandler.java:247) 在 com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389) 在 com.sun.javafx.tk.quantum.GlassViewEventHandler.handleKeyEvent(GlassViewEventHandler.java:246) 位于com.sun.glass.ui.View.handleKeyEvent(View.java:546) com.sun.glass.ui.View.notifyKey(View.java:966)位于 com.sun.glass.ui.win.WinApplication.\u runLoop(本机方法)位于 com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191) 位于java.lang.Thread.run(未知源)

新问题的解决方案:见下面的答案

对原问题的决议:

我正在用Java运行时编译器库动态加载一个类。经过一些研究,我了解到一个类加载器只能有一个特定类的实例。因此,解决方案是在.loadFromJava()方法中创建一个类加载器的新实例,并解决问题

下面是一些代码

import net.openhft.compiler.CompilerUtils;

...

ClassLoader classloader = new ClassLoader() {
        };

Class aClass = CompilerUtils.CACHED_COMPILER.loadFromJava(classloader, className, javaCode);

Callable<Object[]> caller = (Callable<Object[]>) aClass.newInstance();

Object[] obj = (Object[]) caller.call();

...
import net.openhft.compiler.CompilerUtils;
...
ClassLoader ClassLoader=新的ClassLoader(){
};
类aClass=CompilerUtils.CACHED_COMPILER.loadFromJava(类加载器,类名,javaCode);
Callable caller=(Callable)aClass.newInstance();
Object[]obj=(Object[])caller.call();
...

动态类实现Callable并返回对象——因此可以检索在其中创建的任何对象

我刚刚查看了源代码。
问题是,如果要使用相同的
Wini
实例调用
store()
方法,则应避免
Wini
类中的
void load(InputStream input)
加载ini文件。
为什么? 因为
store()
方法希望在当前
Wini
的实例中有一个现有的文件字段,但它找不到它,因为您从流而不是文件加载了ini。

因此,应该使用
Wini
构造函数加载ini文件。构造函数将
文件
作为参数,它还额外设置实例内的字段以加载ini内容

看看这个:

public Wini(File input) throws IOException, InvalidFileFormatException{
        this();
        setFile(input);
        load();
}
因此,请替换:

 private Configuration() {
        ini = new Wini();
        try {
            stream = new FileInputStream(Constants.PATH);
            ini.load(stream);
        }
        catch (Exception e) {
            System.out.println("FILE NOT FOUND!");
        }
    }
据此:

private Configuration()  {
    try {
        ini= new Wini(new File(Constants.PATH));
    }
    catch (Exception e) {
        LOGGER.error("Exception during init of Configuration",e);
    }
}

下面是使用logging to log exception的完整类,该类使用惰性单例实现,而不使用任何显式同步,如
synchronized

public class Configuration {

    private static Logger LOGGER = Logger.getLogger(Configuration.class)//

    private static class HolderLazySingleton {
        private static Configuration instance = new Configuration();
    }

    private Wini ini = null;

    private Configuration() {    
        try {
            ini = new Wini(new File(Constants.PATH));    
        } catch (Exception e) {
            LOGGER.error("Exception during init of Configuration",e);
        }
    }

    public static Configuration getInstance() {
        return HolderLazySingleton.instance;
    }

    public String getConfig(String xSectionName, String xFieldValue) {

        String readValue = null;

        if (ini.get(xSectionName, xFieldValue) != null) {
            readValue = ini.get(xSectionName, xFieldValue);
        } else {
            // TODO: What should happen
        }
        return readValue;
    }

    public void setConfig(String xSectionName, String xFieldValue, String xValue) {

        System.out.println("Section: " + xSectionName);
        System.out.println("Field:   " + xFieldValue);
        System.out.println("Value:   " + xValue + "\n\n");

        try {
            ini.put(xSectionName, xFieldValue, xValue);
            ini.store();
        } catch (Exception e1) {
            LOGGER.error(xValue + " could not be stored.", e1);         
        }
    }
}

System.out.println(“未找到文件!”)在运行时执行?对于singleton,您可以执行更简单的操作,而无需与Bill Pugh的singleton显式同步implementation@davidxxx它正在打印“…无法存储。”好的,你能发布与此异常相关的stacktrace吗?我认为问题在于流-当它尝试写入时,它不再具有访问权限。我希望有办法克服这个问题。非常感谢。它解决了“写”问题,使原来的问题更容易解决。如果你好奇的话,我在描述中加了一个解释。再次感谢——节日快乐。好消息。我已经看到了原始问题的解决方案:有趣。不客气。祝你节日快乐:)