2012-03-03 110 views
120
public class Utils { 
    public static List<Message> getMessages() { 
     //File file = new File("file:///android_asset/helloworld.txt"); 
     AssetManager assetManager = getAssets(); 
     InputStream ims = assetManager.open("helloworld.txt");  
    } 
} 

我正在使用此代碼嘗試從資產讀取文件。我嘗試了兩種方法來做到這一點。首先,當使用File我收到FileNotFoundException,使用AssetManager getAssets()的方法不被識別。 有沒有解決方法?從資產中讀取文件

回答

174

以下是我在緩衝閱讀活動做擴展/修改,以滿足您的需求

BufferedReader reader = null; 
try { 
    reader = new BufferedReader(
     new InputStreamReader(getAssets().open("filename.txt"))); 

    // do reading, usually loop until end of file reading 
    String mLine; 
    while ((mLine = reader.readLine()) != null) { 
     //process line 
     ... 
    } 
} catch (IOException e) { 
    //log the exception 
} finally { 
    if (reader != null) { 
     try { 
      reader.close(); 
     } catch (IOException e) { 
      //log the exception 
     } 
    } 
} 

編輯:我的答案也許是無用的,如果你的問題是如何做到這一點的活動之外。如果你的問題只是如何從資產中讀取文件,那麼答案就在上面。

UPDATE

要打開一個文件中指定類型只需在InputStreamReader的通話如下補充類型。

BufferedReader reader = null; 
try { 
    reader = new BufferedReader(
     new InputStreamReader(getAssets().open("filename.txt"), "UTF-8")); 

    // do reading, usually loop until end of file reading 
    String mLine; 
    while ((mLine = reader.readLine()) != null) { 
     //process line 
     ... 
    } 
} catch (IOException e) { 
    //log the exception 
} finally { 
    if (reader != null) { 
     try { 
      reader.close(); 
     } catch (IOException e) { 
      //log the exception 
     } 
    } 
} 

編輯

由於@Stan在註釋中說,我給的代碼沒有總結線。每過一遍就更換一次mLine。這就是爲什麼我寫了//process line。我假定該文件包含某種數據(即聯繫人列表),並且每行應該分開處理。

如果您只是想要在沒有任何處理的情況下加載文件,則必須在每次使用StringBuilder()時總結mLine並追加每遍。

ANOTHER編輯

根據@Vincent的評論我增加了finally塊。

另請注意,在Java 7和更高版本中,您可以使用try-with-resources來使用最近的Java的AutoCloseableCloseable功能。

背景

在@LunarWatcher指出getAssets()context一個class評論。因此,如果您將其稱爲activity之外,則需要引用它並將該上下文實例傳遞給該活動。

ContextInstance.getAssets(); 

這在@Maneesh的答案中有解釋。所以如果你對他的回答有幫助,因爲那是他指出的。

+0

此代碼失敗,因爲它會取代mline的內容,每過一遍 – Stan 2014-01-16 18:38:19

+2

@Stan,然後在評論中寫下它,讓作者決定是否要更新它。編輯是爲了提高清晰度,而不是改變意義。代碼修訂應始終首先發布爲註釋。 – KyleMit 2014-01-16 18:39:59

+0

好吧,我明白了,thanx!它很好,你在EDIT中提到了功能。我會盡快刪除這個我的評論,因爲沒有建設性等。我也投了你的評論以上 – Stan 2014-01-17 10:36:57

60
getAssets() 

只有在其他任何類活動工作你必須使用Context它。

爲Util創建構造函數將活動(難看的方式)或應用程序上下文的類引用作爲參數傳遞給它。在你的Utils類中使用getAsset()。

+0

它適用於任何屬於Co的子類ntext,其中Activity是其中之一。 – 2013-08-22 20:59:25

+0

剛纔注意到我寫了'Context'。 – user370305 2013-08-23 07:43:17

+0

@ user370305你知道嗎,我可以如何將InputStream轉換爲FileInputStream? – 2015-05-18 13:17:01

6

getAssets()方法將在您在Activity類中調用時起作用。

如果您在非Activity類中調用此方法,則需要從Activity類中傳遞的Context調用此方法。所以下面是你可以訪問的方法。

ContextInstance.getAssets(); 

ContextInstance可能因該Activity類的傳遞。

9
AssetManager assetManager = getAssets(); 
InputStream inputStream = null; 
try { 
    inputStream = assetManager.open("helloworld.txt"); 
} 
catch (IOException e){ 
    Log.e("message: ",e.getMessage()); 
} 
32
public String ReadFromfile(String fileName, Context context) { 
    StringBuilder returnString = new StringBuilder(); 
    InputStream fIn = null; 
    InputStreamReader isr = null; 
    BufferedReader input = null; 
    try { 
     fIn = context.getResources().getAssets() 
       .open(fileName, Context.MODE_WORLD_READABLE); 
     isr = new InputStreamReader(fIn); 
     input = new BufferedReader(isr); 
     String line = ""; 
     while ((line = input.readLine()) != null) { 
      returnString.append(line); 
     } 
    } catch (Exception e) { 
     e.getMessage(); 
    } finally { 
     try { 
      if (isr != null) 
       isr.close(); 
      if (fIn != null) 
       fIn.close(); 
      if (input != null) 
       input.close(); 
     } catch (Exception e2) { 
      e2.getMessage(); 
     } 
    } 
    return returnString.toString(); 
} 
+0

您可能會認爲如果關閉了BufferedReader,那麼也必須自動關閉InputStreanReader和InputStream。因爲你沒有爲那些人創建句柄,例如'input = new BufferedReader(new InputStreamReader(fIn));'。 – trans 2014-05-28 13:07:47

+1

我會建議創建單獨的try/catch塊來結束所有的資源;而不是將它們全部合併爲一個 - 因爲如果先前嘗試關閉另一個資源引發異常,它可能會使其他資源未關閉。 – Reece 2016-11-18 04:03:59

30

優於從不遲到。

在某些情況下,我很難逐行讀取文件。 到目前爲止,下面的方法是我找到的最好的,我推薦它。

用法:String yourData = LoadData("YourDataFile.txt");

YourDataFile.txt假定居住在資產/

public String LoadData(String inFile) { 
     String tContents = ""; 

    try { 
     InputStream stream = getAssets().open(inFile); 

     int size = stream.available(); 
     byte[] buffer = new byte[size]; 
     stream.read(buffer); 
     stream.close(); 
     tContents = new String(buffer); 
    } catch (IOException e) { 
     // Handle exceptions here 
    } 

    return tContents; 

} 

編輯。明顯的問題:這個函數會返回字符串:

'android.content.res.AssetManager $ @ AssetInputStream [代碼]'

,而不是文件內容。我無法重現這個問題。直到我更新我的答案,當我得到什麼問題時,請考慮上面的代碼'可能不可靠'。

+0

我的返回字符串是[email protected] .. – 2014-10-18 07:31:14

+0

在這裏相同,res.AssetManager $ AssetInputStream @ ....爲什麼它返回這個任何特定的原因? – Bigs 2014-10-25 20:25:34

+1

對我來說工作正常 – Fabian 2016-01-05 13:18:05

4

這裏是讀的資產文件的方法:

/** 
* Reads the text of an asset. Should not be run on the UI thread. 
* 
* @param mgr 
*   The {@link AssetManager} obtained via {@link Context#getAssets()} 
* @param path 
*   The path to the asset. 
* @return The plain text of the asset 
*/ 
public static String readAsset(AssetManager mgr, String path) { 
    String contents = ""; 
    InputStream is = null; 
    BufferedReader reader = null; 
    try { 
     is = mgr.open(path); 
     reader = new BufferedReader(new InputStreamReader(is)); 
     contents = reader.readLine(); 
     String line = null; 
     while ((line = reader.readLine()) != null) { 
      contents += '\n' + line; 
     } 
    } catch (final Exception e) { 
     e.printStackTrace(); 
    } finally { 
     if (is != null) { 
      try { 
       is.close(); 
      } catch (IOException ignored) { 
      } 
     } 
     if (reader != null) { 
      try { 
       reader.close(); 
      } catch (IOException ignored) { 
      } 
     } 
    } 
    return contents; 
} 
2

如果使用其他活動相比其他任何類,您可能想去做,

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(YourApplication.getInstance().getAssets().open("text.txt"), "UTF-8")); 
2

在MainActivity.java

@Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     TextView tvView = (TextView) findViewById(R.id.tvView); 

     AssetsReader assetsReader = new AssetsReader(this); 
     if(assetsReader.getTxtFile(your_file_title)) != null) 
     { 
      tvView.setText(assetsReader.getTxtFile(your_file_title))); 
     } 
    } 

此外,你可以創建單獨的類,做所有的工作

public class AssetsReader implements Readable{ 

    private static final String TAG = "AssetsReader"; 


    private AssetManager mAssetManager; 
    private Activity mActivity; 

    public AssetsReader(Activity activity) { 
     this.mActivity = activity; 
     mAssetManager = mActivity.getAssets(); 
    } 

    @Override 
    public String getTxtFile(String fileName) 
    { 
     BufferedReader reader = null; 
     InputStream inputStream = null; 
     StringBuilder builder = new StringBuilder(); 

     try{ 
      inputStream = mAssetManager.open(fileName); 
      reader = new BufferedReader(new InputStreamReader(inputStream)); 

      String line; 

      while((line = reader.readLine()) != null) 
      { 
       Log.i(TAG, line); 
       builder.append(line); 
       builder.append("\n"); 
      } 
     } catch (IOException ioe){ 
      ioe.printStackTrace(); 
     } finally { 

      if(inputStream != null) 
      { 
       try { 
        inputStream.close(); 
       } catch (IOException ioe){ 
        ioe.printStackTrace(); 
       } 
      } 

      if(reader != null) 
      { 
       try { 
        reader.close(); 
       } catch (IOException ioe) 
       { 
        ioe.printStackTrace(); 
       } 
      } 
     } 
     Log.i(TAG, "builder.toString(): " + builder.toString()); 
     return builder.toString(); 
    } 
} 

在我看來,最好創建一個接口,但它不是neccessary

public interface Readable { 
    /** 
    * Reads txt file from assets 
    * @param fileName 
    * @return string 
    */ 
    String getTxtFile(String fileName); 
} 
0

cityfile.txt

public void getCityStateFromLocal() { 
     AssetManager am = getAssets(); 
     InputStream inputStream = null; 
     try { 
      inputStream = am.open("city_state.txt"); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     ObjectMapper mapper = new ObjectMapper(); 
     Map<String, String[]> map = new HashMap<String, String[]>(); 
     try { 
      map = mapper.readValue(getStringFromInputStream(inputStream), new TypeReference<Map<String, String[]>>() { 
      }); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     ConstantValues.arrayListStateName.clear(); 
     ConstantValues.arrayListCityByState.clear(); 
     if (map.size() > 0) 
     { 
      for (Map.Entry<String, String[]> e : map.entrySet()) { 
       CityByState cityByState = new CityByState(); 
       String key = e.getKey(); 
       String[] value = e.getValue(); 
       ArrayList<String> s = new ArrayList<String>(Arrays.asList(value)); 
       ConstantValues.arrayListStateName.add(key); 
       s.add(0,"Select City"); 
       cityByState.addValue(s); 
       ConstantValues.arrayListCityByState.add(cityByState); 
      } 
     } 
     ConstantValues.arrayListStateName.add(0,"Select States"); 
    } 
// Convert InputStream to String 
    public String getStringFromInputStream(InputStream is) { 
     BufferedReader br = null; 
     StringBuilder sb = new StringBuilder(); 
     String line; 
     try { 
      br = new BufferedReader(new InputStreamReader(is)); 
      while ((line = br.readLine()) != null) { 
       sb.append(line); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      if (br != null) { 
       try { 
        br.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 

     return sb + ""; 

    } 
0

您可以加載該文件中的內容。考慮文件存在於資產文件夾中。

public static InputStream loadInputStreamFromAssetFile(Context context, String fileName){ 
    AssetManager am = context.getAssets(); 
    try { 
     InputStream is = am.open(fileName); 
     return is; 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    return null; 
} 

public static String loadContentFromFile(Context context, String path){ 
    String content = null; 
    try { 
     InputStream is = loadInputStreamFromAssetFile(context, path); 
     int size = is.available(); 
     byte[] buffer = new byte[size]; 
     is.read(buffer); 
     is.close(); 
     content = new String(buffer, "UTF-8"); 
    } catch (IOException ex) { 
     ex.printStackTrace(); 
     return null; 
    } 
    return content; 
} 

現在,您可以通過調用函數獲取內容如下

String json= FileUtil.loadContentFromFile(context, "data.json"); 

考慮到data.json存儲在應用程序\程序\ SRC \主\資產\ data.json

0

使用Kotlin,您可以執行以下操作以讀取Android中的資產文件:

try { 
     val inputStream:InputStream = assets.open("helloworld.txt") 
     val inputString = inputStream.bufferedReader().use{it.readText()} 
     Log.d(TAG,inputString) 
    } catch (e:Exception){ 
     Log.d(TAG, e.toString()) 
    }