2016-12-25 66 views
1

原始问题:该方案是读取旧的配置文件的输入文件(.ini)Singleton模式与ini4j

新问题:尝试与流Singleton模式后/ INI,我不能写入文件了。它抛出java.io.FileNotFoundException。

有无论如何我可以修改我的配置类,使其工作?

在此先感谢。

Configuration类:

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(); 
     } 
    } 
} 

条:漂移

字段:亩

值:5

5不能被存储。在application.prototypes.UserInputs.lambda

java.io.FileNotFoundException在org.ini4j.Ini.store(Ini.java:126) 在 application.prototypes.Configuration.setConfig(Configuration.java:72) $ 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) at com.sun.javafx.event.CompositeEventDispatcher.dispat chBubblingEvent(CompositeEventDispatcher.java:59) 在 com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) 在 com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 在 com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) 在 com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 在 com.sun.javafx .event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)at javafx.event.Event.fireEvent( Event.java:198) javafx.scene.Scene $ KeyHandler.process(Scene.java:3964)at javafx.scene.Scene $ KeyHandler.access $ 1800(Scene.java:3910)at javafx.scene.Scene .impl_processKeyEvent(Scene.java:2040)at javafx.scene.Scene $ ScenePeerListener.keyEvent(Scene.java:2501)at com.sun.javafx.tk.quantum.GlassViewEventHandler $ KeyEventNotification.run(GlassViewEventHandler.java:216 ) at com.sun.javafx.tk.quantum.GlassViewEventHandler $ KeyEventNotification.run(GlassViewEventHandler.java:148) at java.securit在 com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda $ handleKeyEvent y.AccessController.doPrivileged(本机方法)$ 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)at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)at com.sun.glass.ui.win.WinApplication。拉姆达为$ null $ 148(WinApplication.java:191) 在java.lang.Thread.run(来源不明)

解决新问题:请参见下面的回答。

分辨率以原始发行日期:

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

这是一段代码。

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(); 

... 

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

+0

是'System.out.println(“FILE NOT FOUND!”);'在运行时执行? – davidxxx

+0

对于单身人士,你可以做得更简单,没有与Bill Pugh的单例实现 – davidxxx

+0

@davidxxx显式同步它正在打印“...无法存储”。 –

回答

1

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

所以你应该使用Wini构造函数加载ini文件。该构造函数以参数File为参数,并且还将该实例中的字段另外设置为加载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); 
    } 
} 

下面是一个使用日志记录异常和满级没有使用懒惰的单例实现使用任何明确的同步作为​​:

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);   
     } 
    } 
} 
+0

非常感谢。它解决了“写入”问题,使解决原始问题变得更容易。如果您好奇,我在说明中添加了解释。再次感谢 - 并且节日快乐。 –

+0

好消息。我已经看到了原始问题的解决方案:有趣。不用谢。祝你节日快乐:) – davidxxx