2017-06-19 85 views
0

我有這樣的數據片段(這是整個文件的一行的只是其中的一部分):如何實現這個屬性文件?

000000055555444444******4444  YY 

我實現這個CSV配置文件,以便能夠讀出的數據的每一部分,並解析它:

128-12,140-22,YY 

第一對(128-12)表示在開始讀取什麼在線位置,然後字符的量來讀取,即第一對是帳戶號碼。

第二對如果是卡號。

而thir參數是註冊表名稱。

無論如何,我所做的是String.split(「,」),然後指定數組[0]作爲帳號,等等。

但我想將該CSV配置文件更改爲屬性文件,但我不知道如何實現該解決方案,如果我使用屬性文件我必須添加一堆如果/然後在爲了正確映射了我的價值觀,這裏就是我想這樣做的:

Property cfg = new Property(); 
cfg.put("fieldName", "accountNumber"); 
cfg.put("startPosition", "128"); 
cfg.put("length", "12"); 

但我不得不說,如果(「字段名」 .equals(「使用accountNumber」)),然後指定使用accountNumber;有沒有一種方法可以實現這一點,以避免執行所有這些決定?現在用我的解決方案,我不必使用ifs,我只說accountNumber = array [0];就是這樣,但我不認爲這是一個很好的解決方案,我覺得用房產會更優雅的或有效的

編輯:

這可能需要一些更多的澄清,這個數據我展示是我目前爲客戶做的解析程序的一部分;這些數據爲許多客戶提供了信息,而且我必須將我從他們那裏收到的大量數據解析爲更具可讀性的內容,以便將其轉換爲PDF文件,到目前爲止該程序正在生產中,我試圖重構它一點點。客戶的所有信息都保存到不同的登記類,有它自己的一套獨特的信息字段的每一個類,可以說,這是RegistryYY會是什麼樣子:

class RegistryYY extends Registry{ 
    String name; 
    String lastName; 
    PhysicalAddress address; 

    public RegistryYY(String dataFromFile) { 
    } 
} 

我要實現的物業解決方案,因爲通過這種方式,我可以讓Property來解析文件,或者正確解釋每個Registry類所擁有的數據,我的意思是,Registry應該知道從文件接收到的數據需要哪些數據?如果我這樣做,我可以使每個註冊表成爲一個觀察者,並且他們會通過檢查存儲在當前行中的註冊表名稱來決定從文件讀取的當前行是否屬於他們,然後他們會將已初始化的註冊表返回給只關心接收的呼叫對象並存儲一個註冊表類。

編輯2:

我創造了這個函數返回存儲在每行的位置值:

public static String getField(String fieldParams, String rawData){ 
     // splits the field 
     String[] fields = fieldParams.split("-"); 

     int fieldStart = Integer.parseInt(fields[0]); // get initial position of the field 
     int fieldLen = Integer.parseInt(fields[1]); // get length of field 

     // gets field value 
     String fieldValue = FieldParser.getStringValue(rawData, fieldStart, fieldLen); 

     return fieldValue;  
    } 

與CSV文件的工作,我想改變與工作實施該屬性文件,而不是。

+0

@VinceEmigh,因爲OP可能有很多「fieldName」。我不認爲房地產是這方面的良好儲備。也許YAML:http://yamlbeans.sourceforge。net /(看電話號碼的例子) – 2017-06-19 15:37:34

+0

據我所知,OP有某種固定長度的數據(startPosition = 128,length = 12,startPosition = 140,length = 22) – 2017-06-19 15:42:11

+0

@VinceEmigh RC表示,我有很多很多領域,我在我的問題開始時說過,我所展示的僅僅是一行數據的一部分,該文件可以有多達800K +行的數據,到目前爲止,最大的文件具有20K不同的信息客戶端。 –

回答

0

是否有任何理由需要將記錄佈局暴露給外部世界?它需要配置嗎?

我認爲你提出的使用Property文件的方法比使用CSV文件的當前方法更好,因爲它更具描述性和更有意義。我只需在屬性定義中添加一個「type」屬性,以便強制轉換,即Numeric/String/Date/Boolean。

我不會使用「if」語句來處理您的屬性文件。您可以將所有屬性加載到開頭的數組,然後陣列周圍循環爲你的數據文件和流程的每一行該部分相應的類似下面的僞代碼,

for each loop of data-file{ 
    SomeClass myClass = myClassBuilder(data-file-line) 
} 

myClassBuilder SomeClass (String data-file-line){ 
    Map<column, value> result = new HashMap<> 
    for each attribute of property-file-list{ 
     switch attribute_type { 
       Integer: 
        result.put(fieldname, makeInteger(data-file-line, property_attribute) 
       Date: 
        result.put(fieldname, makeDate(data-file-line, property_attribute) 
       Boolean : 
        result.put(fieldname, makeBoolean(data-file-line, property_attribute) 
       String : 
        result.put(fieldname, makeBoolean(data-file-line, property_attribute) 
       ------- etc 
      } 
    } 
    return new SomeClass(result) 
} 

}

如果您記錄佈局不需要可配置,那麼你可以只在Java應用程序內進行所有轉換,甚至不使用Property文件。

如果您可以使用XML格式獲取數據,那麼您可以使用JAXB框架,並且只需將數據定義在XML文件中即可。

+0

以供參考,這裏是一個老問題,我問到我正在工作的項目,我只發佈RegistroCL類,我想讓每個註冊中心擁有它自己創建的屬性,這樣我只需要擔心閱讀行和通知監聽者,他們會決定該行是否屬於他們,並創建一個註冊表實例:https://codereview.stackexchange.com/questions/142514/system-to-process-data-from-a -specific-client –

+0

順便說一句,到目前爲止甚至認爲該項目正在生產中,客戶端總是對數據佈局做出很多更改,這就是爲什麼現在我需要它是可配置的。 @ robbie70 –

0

首先,感謝幫助我的人,@ robbie70,@RC。和@VinceEmigh。

我用YAML解析一個名爲「test.yml」具有以下信息在它的文件:

statement: 
    - fieldName: accountNumber 
    startPosition: 128 
    length: 12 
    - fieldName: cardNumber 
    startPosition: 140 
    length: 22 
    - fieldName: registryName 
    startPosition: 162 
    length: 2 

這是我編:

// Start of main 

String fileValue = "0222000000002222F                       00000000000111110001000000099999444444******4444  YY"; 
     YamlReader reader = new YamlReader(new FileReader("test.yml")); 
     Object object = reader.read();  
     System.out.println(object); 

     Map map = (Map) object; 

     List list = (List) map.get("statement"); 

     for(int i = 0; i < list.size(); i++) { 
      Map map2 = (Map) list.get(i); 

      System.out.println("Value: " + foo(map2, fileValue)); 
     }  
    } 

// End of main 

    public static String foo(Map map, String source) { 
     int startPos = Integer.parseInt((String) map.get("startPosition")); 
     int length = Integer.parseInt((String) map.get("length")); 

     return getField(startPos, length, source); 
    } 

    public static String getField(int start, int length, String source) { 
     return source.substring(start, start+length); 
    } 

它正確地顯示輸出:

Value: 000000099999 
Value: 444444******4444  
Value: YY 

我知道,也許配置文件有一些列表和其他不必要的值,什麼不是,一個這也許該計劃需要一點改進,但​​我認爲我可以從這裏拿出來並實施我的想法。

編輯:

我做了這等一個,使用Apache共享,這是我在配置屬性文件:

#properties defining the statement file 

#properties for account number 
statement.accountNumber.startPosition = 128 
statement.accountNumber.length = 12 
statement.account.rules = ${statement.accountNumber.startPosition} ${statement.accountNumber.length} 

#properties for card number 
statement.cardNumber.startPosition = 140 
statement.cardNumber.length = 22 
statement.card.rules = ${statement.cardNumber.startPosition} ${statement.cardNumber.length} 

#properties for registry name 
statement.registryName.startPosition = 162 
statement.registryName.length = 2 
statement.registry.rules = ${statement.registryName.startPosition} ${statement.registryName.length} 

而且這是我讀它:

// Inside Main 


String valorLeido = "0713000000007451D                       00000000000111110001000000099999444444******4444  YY";  

    Parameters params = new Parameters(); 
    FileBasedConfigurationBuilder<FileBasedConfiguration> builder = 
     new FileBasedConfigurationBuilder<FileBasedConfiguration>(PropertiesConfiguration.class) 
     .configure(params.properties() 
       .setFileName("config.properties")); 

    try { 
     Configuration config = builder.getConfiguration();   

     Iterator<String> keys = config.getKeys(); 

     String account = getValue(getRules(config, "statement.account.rules"), valorLeido); 
     String cardNumber = getValue(getRules(config, "statement.card.rules"), valorLeido); 
     String registryName = getValue(getRules(config, "statement.registry.rules"), valorLeido); 
    } catch (org.apache.commons.configuration2.ex.ConfigurationException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
// End of Main  

public static String getRules(Configuration config, String rules) { 
    return config.getString(rules); 
} 

public static String getValue(String rules, String source) { 
    String[] tokens = rules.split(" "); 

    int startPos = Integer.parseInt(tokens[0]); 
    int length = Integer.parseInt(tokens[1]); 

    return getField(startPos, length, source); 
} 

我不完全確定,我認爲使用YAML文件它看起來更簡單,但我真的很喜歡我用Apache Commons Config獲得的控件,因爲我可以將Configuration對象傳遞給每個註冊表,註冊表知道它想要得到什麼「規則」,假設Registry類只關心「statement.registry.rules」,就是這樣,使用YAML選項我不完全確定如何做到這一點但是,也許我需要再嘗試兩種選擇,但是我喜歡這種情況。

PS:

那我fileValue用怪異的價值就是我負責的,現在增加近1,000個字符的線的長度,你就會明白爲什麼我想有一個配置文件解析它(不要問爲什麼....客戶端會瘋狂)

相關問題