2012-03-03 85 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()) 
    }