2016-12-25 92 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