简体   繁体   English

从资产中读取文件

[英]read file from assets

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");    
     }
}

I am using this code trying to read a file from assets.我正在使用此代码尝试从资产中读取文件。 I tried two ways to do this.我尝试了两种方法来做到这一点。 First, when use File I received FileNotFoundException , when using AssetManager getAssets() method isn't recognized.首先,当使用File我收到FileNotFoundException ,当使用AssetManager getAssets()方法时无法识别。 Is there any solution here?这里有什么解决办法吗?

Here is what I do in an activity for buffered reading extend/modify to match your needs这是我在缓冲阅读扩展/修改以满足您的需求的活动中所做的

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
         }
    }
}

EDIT : My answer is perhaps useless if your question is on how to do it outside of an activity.编辑:如果您的问题是关于如何在活动之外进行,我的回答可能没用。 If your question is simply how to read a file from asset then the answer is above.如果您的问题只是如何从资产中读取文件,那么答案就在上面。

UPDATE :更新

To open a file specifying the type simply add the type in the InputStreamReader call as follow.要打开指定类型的文件,只需在 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
         }
    }
}

EDIT编辑

As @Stan says in the comment, the code I am giving is not summing up lines.正如@Stan 在评论中所说,我给出的代码不是总结行。 mLine is replaced every pass. mLine每次通过mLine被替换。 That's why I wrote //process line .这就是我写//process line的原因。 I assume the file contains some sort of data (ie a contact list) and each line should be processed separately.我假设该文件包含某种数据(即联系人列表),并且每一行都应该单独处理。

In case you simply want to load the file without any kind of processing you will have to sum up mLine at each pass using StringBuilder() and appending each pass.如果您只想加载文件而不进行任何类型的处理,您将必须使用StringBuilder()在每次传递时总结mLine并附加每个传递。

ANOTHER EDIT另一个编辑

According to the comment of @Vincent I added the finally block.根据@Vincent 的评论,我添加了finally块。

Also note that in Java 7 and upper you can use try-with-resources to use the AutoCloseable and Closeable features of recent Java.另请注意,在 Java 7 及更高版本中,您可以使用try-with-resources来使用最新 Java 的AutoCloseableCloseable功能。

CONTEXT语境

In a comment @LunarWatcher points out that getAssets() is a class in context .在评论中@LunarWatcher 指出getAssets()context一个class So, if you call it outside of an activity you need to refer to it and pass the context instance to the activity.因此,如果您在activity之外调用它,则需要引用它并将上下文实例传递给活动。

ContextInstance.getAssets();

This is explained in the answer of @Maneesh.这在@Maneesh 的回答中有解释。 So if this is useful to you upvote his answer because that's him who pointed that out.因此,如果这对您有用,请支持他的回答,因为他指出了这一点。

getAssets()

is only works in Activity in other any class you have to use Context for it.仅适用您必须使用Context其他任何类中的 Activity

Make a constructor for Utils class pass reference of activity (ugly way) or context of application as a parameter to it.为 Utils类创建一个构造函数,将活动的引用(丑陋的方式)或应用程序的上下文作为参数传递给它。 Using that use getAsset() in your Utils class.在 Utils 类中使用 getAsset() 。

Better late than never.迟到总比不到好。

I had difficulties reading files line by line in some circumstances.在某些情况下,我很难逐行读取文件。 The method below is the best I found, so far, and I recommend it.下面的方法是迄今为止我发现的最好的方法,我推荐它。

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

Where YourDataFile.txt is assumed to reside in assets/假设YourDataFile.txt位于assets/

 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;

 }
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();
}

one line solution for kotlin: kotlin 的单行解决方案:

fun readFileText(fileName: String): String {
    return assets.open(fileName).bufferedReader().use { it.readText() }
}

Also you can use it as extension function everyWhere您也可以将其用作任何地方的扩展功能

fun Context.readTextFromAsset(fileName : String) : String{
     return assets.open(fileName).bufferedReader().use { 
     it.readText()}
}

Simply call in any context Class只需在任何上下文中调用类

context.readTextFromAsset("my file name")
AssetManager assetManager = getAssets();
InputStream inputStream = null;
try {
    inputStream = assetManager.open("helloworld.txt");
}
catch (IOException e){
    Log.e("message: ",e.getMessage());
}

getAssets() method will work when you are calling inside the Activity class.当您在 Activity 类内部调用时, getAssets()方法将起作用。

If you calling this method in non-Activity class then you need to call this method from Context which is passed from Activity class.如果您在非 Activity 类中调用此方法,则需要从从 Activity 类传递的 Context 中调用此方法。 So below is the line by you can access the method.所以下面是您可以访问该方法的行。

ContextInstance.getAssets();

ContextInstance may be passed as this of Activity class. ContextInstance可以作为 Activity 类的 this 传递。

Reading and writing files have always been verbose and error-prone.读取和写入文件总是冗长且容易出错。 Avoid these answers and just use Okio instead:避免这些答案,只需使用Okio

public void readLines(File file) throws IOException {
  try (BufferedSource source = Okio.buffer(Okio.source(file))) {
    for (String line; (line = source.readUtf8Line()) != null; ) {
      if (line.contains("square")) {
        System.out.println(line);
      }
    }
  }
}

Here is a method to read a file in assets:这是一种读取资产中文件的方法:

/**
 * 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;
}

You can load the content from the file.您可以从文件加载内容。 Consider the file is present in asset folder.考虑文件存在于资产文件夹中。

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;
}

Now you can get the content by calling the function as follow现在你可以通过调用函数来获取内容如下

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

Considering the data.json is stored at Application\\app\\src\\main\\assets\\data.json考虑到 data.json 存储在 Application\\app\\src\\main\\assets\\data.json

In MainActivity.java在 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)));
        }
    }

Also, you can create separate class that does all the work此外,您可以创建单独的类来完成所有工作

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();
    }
}

In my opinion it's better to create an interface, but it's not neccessary在我看来最好创建一个界面,但这不是必需的

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

如果您使用除 Activity 以外的任何其他类,您可能想要这样做,

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

Using Kotlin, you can do the following to read a file from assets in Android:使用 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())
}

Here is a way to get an InputStream for a file in the assets folder without a Context , Activity , Fragment or Application .这是一种在没有ContextActivityFragmentApplication情况Context获取assets文件夹中文件的InputStream的方法。 How you get the data from that InputStream is up to you.如何从InputStream获取数据取决于您。 There are plenty of suggestions for that in other answers here.在这里的其他答案中有很多建议。

Kotlin科特林

val inputStream = ClassLoader::class.java.classLoader?.getResourceAsStream("assets/your_file.ext")

Java爪哇

InputStream inputStream = ClassLoader.class.getClassLoader().getResourceAsStream("assets/your_file.ext");

All bets are off if a custom ClassLoader is in play.如果使用自定义ClassLoader则所有赌注都将关闭。

It maybe too late but for the sake of others who look for the peachy answers :也许为时已晚,但为了其他寻找桃色答案的人:

public static String loadAssetFile(Context context, String fileName) {
    try {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(context.getAssets().open(fileName)));
        StringBuilder out= new StringBuilder();
        String eachline = bufferedReader.readLine();
        while (eachline != null) {
            out.append(eachline);
            eachline = bufferedReader.readLine();
        }
        return out.toString();
    } catch (IOException e) {
        Log.e("Load Asset File",e.toString());
    }
    return null;
}

cityfile.txt城市档案.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 + "";

    }

The Scanner class may simplify this. Scanner 类可以简化这一点。

        StringBuilder sb=new StringBuilder();
        Scanner scanner=null;
        try {
            scanner=new Scanner(getAssets().open("text.txt"));
            while(scanner.hasNextLine()){
                sb.append(scanner.nextLine());
                sb.append('\n');
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(scanner!=null){try{scanner.close();}catch (Exception e){}}
        }
        mTextView.setText(sb.toString());

@HpTerm answer Kotlin version: @HpTerm回答 Kotlin 版本:

private fun getDataFromAssets(activity: Activity): String {私人乐趣 getDataFromAssets(activity: Activity): String {

    var bufferedReader: BufferedReader? = null
    var data = ""

    try {
        bufferedReader = BufferedReader(
            InputStreamReader(
                activity?.assets?.open("Your_FILE.html"),
                "UTF-8"
            )
        )                  //use assets? directly if in activity

        var mLine:String? = bufferedReader.readLine()
        while (mLine != null) {
            data+= mLine
            mLine=bufferedReader.readLine()
        }

    } catch (e: Exception) {
        e.printStackTrace()
    } finally {
        try {
            bufferedReader?.close()
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
    return data
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM