2013-10-27 115 views
1

我有一個US-ASCII文本文件,其中包含一個單獨的長行。我需要訪問的文本項是由不同數量的空格分隔,就像這樣:使用Java掃描文本文件

metadata1 attrib1  metadata2 attrib2 attrib2a trackstart attrib1 attrib2 trackstart attrib1 atrib2 attrib3 

該文件可以有一個最大的99「軌道」的條目,並會採取很少的內存。

我需要做的

我要提取這些條目到內存中的結構,我可以遍歷,訪問值,並計算項目。舉例來說,我需要通過計算「trackstart在上面的例子中得到「軌道」(的數量,也可以增加每個軌道屬性爲結構像object.track1.attribute1

我已經試過

我使用的掃描儀在文件中讀取,並通過文本輸入步驟這似乎很好地工作,然後我創建嵌套包含HashMap,如:

HashMap<String, String> overallMap = new HashMap<String, String>(); // contains the tracks map and some other metadata 
HashMap<String, Map> tracks = new HashMap<String, Map>(); // contains a map of all tracks 
HashMap<String, String> track = new HashMap<String, String>(); // contains an individual track 

但問題是,(我認爲)包含HashMap贏得」讓我算上鑰匙(所以我不能在我的文本文件中獲得「軌道」數量樂)。我懷疑我會遇到這個數據結構的其他問題。

問題

  1. 在這種情況下,是掃描儀中讀取和操作文件的最好方法?
  2. 我應該選擇什麼內存數據結構?我如何建立曲目列表,計算曲目並訪問此結構中的各個屬性?
+1

首先,你可以用'Map.size()'給你鑰匙的數量在'Map'。其次,如果你正在使用'Map'的'Map's等,那麼這通常是「Object Phobia」的標誌。事實上,你有'Track'的概念意味着你應該有一個'Track'對象來存儲它的屬性。 –

+0

因此每條曲目都有屬性和元數據對象具有屬性和曲目,是否正確? –

+0

@AnkitRustagi有一些'元數據'鍵具有不同數量的值,它們位於整個數據結構的根部,但它主要由'trackstart'分隔的'track'組成,並且還包含不同數量的值。 'metedata'對象不包含音軌。謝謝! – Fiona

回答

0

既然你有一些元數據對象和一些軌道,其中每個具有可變數量的屬性,我們可以有一個基類名爲「MyObjects」來代表他們每個人的

public class MyObject implements java.io.Serializable 
{ 
    String name; 
    ArrayList attributes; 
    public MyObject(String name) 
    { 
     this.name = name; 
    } 
    public void addAttribute(String attr) 
    { 
     this.attributes.add(attr); 
    } 
} 

,然後有一個類爲MyFile這將代表您閱讀的每個文件。

public class MyFile 
{ 
    MyObject[] metadata; 
    MyObject[] track; 

    public int check(String s) 
    { 
     if(s.substring(0,s.length()-1).equals("metadata")) return 0; 
     if(s.equals("trackstart")) return 1; 
     return 2; 
    } 
} 

然後在主函數中,你可以讀取文件

File f = new File(filepath); 
BufferedReader br = new InputStreamReader(f.getInputStream()); 
String line = "",content = ""; 
while((line = br.readLine())!=null) content += line; 

MyFile myfile = new MyFile(); 
StringTokenizer t = new StringTokenizer(content," "); 
int status; 
String word = ""; 
while(t.hasMoreTokens()) 
{ 
    word = t.nextToken(); 
    status = myfile.check(word); 

    // add the attributes to the to metadata or tracks 

} 
0

Java是一種OO語言,因此您應該創建自己的對象,而不僅僅依賴於數據結構。這將使所有事情變得更加容易,可以書寫,閱讀和維護。

所以你應該有一個Track類,其中包含ListSet的屬性。選擇取決於您是否關心屬性的順序,以及您是否必須刪除重複項。

Track類應該讓你添加和獲取屬性,因爲這是你需要做的。而且由於您似乎只對曲目感興趣,而不是對第一首曲目前的曲目中的其他信息感興趣,所以您只需要一個曲目列表來保存所有曲目。

因此算法應該是很簡單的:

  • 劈令牌行
  • 創建通過令牌
    • List<Track>
    • 迭代如果當前標記是trackstart,然後創建新的Track,並將此新的Track實例分配給變量currentTrack。這條賽道添加到曲目列表
    • 如果當前標記是別的什麼,然後
      • 要麼currentTrack是空的,你應該忽略令牌
      • currentTrack是不是空的,你應該添加令牌通過調用currentTrack.addAttribute(token)

在算法結束的當前曲目的屬性,你有List<Track>已滿軌道實例,順序與線路中的軌道相同。並且每個Track實例都有一個包含軌道屬性的List<String>