I have a code inside myActivity.class
InputStream inputStream = getApplicationContext().getResources().openRawResource(R.raw.text);
BufferedReader buff = new BufferedReader(new InputStreamReader(inputStream));
String s;
ArrayList <String> list = new ArrayList <String>();
try
{ while((s = buff.readLine()) != null)
{
list.add(s);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
I want to move that part of code to separate java.class, but here I face a problem, how I can to access a raw file by InputStream without using getApplicationContext()?
For instance:
public class MyArrayList extends ArrayList<String>
{
private InputStream in = ???; // how to declare InpuStream without Context???
private BufferedReader buff = new BufferedReader(new InputStreamReader(in));;
private String s;
private MyArrayList array;
public MyArrayList ()
{
try
{
while ((s = buff.readLine()) != null)
{
array.add(s);
}
} catch (IOException e)
{
e.printStackTrace();
} finally
{
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
I have tried
InputStream in = Resources.getSystem().openRawResource(R.raw.text); but it gave me NullPointerException
So my question is: Does exist some way to initialize InputStream with raw file outside Activity ?
how I can to access a raw file by InputStream without using getApplicationContext()?
First, you do not need getApplicationContext() in your existing code. Deleting it will work just fine, and it saves an unnecessary call.
Beyond that -- and assuming that you really think that an ArrayList should be responsible for I/O -- MyArrayList needs you to pass in one of the following:
the InputStream, or
the Resources (so you can call openRawResource() on it), or
a suitable Context (so you can call getResources() on it) (and which, depending on the lifetime of MyArrayList, could be one of several possible objects)
You can't access App resources without current app context. If you want to move code in diff Java file simply Make a class and inside that class make a function with activity as one of the function's parameter and your required return type.
As activity is parent for context we can use it where ever we need activity or context reference out side the activity class.
public class Demo{
public static "whatEverReturnTypeYouNeedToReturnFromFunction" f1(Activity act, ...){
InputStream inputStream = act.getResources().openRawResource(R.raw.text);
BufferedReader buff = new BufferedReader(new InputStreamReader(inputStream));
String s;
ArrayList <String> list = new ArrayList <String>();
try
{ while((s = buff.readLine()) != null)
{
list.add(s);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
return whatEverReturnTypeYouNeedToReturnFromFunction;
}
}
}
In the above code make variables static as our function is static.
And to call it from Activity class simply call
Type "whateverYouWhatToGetFromFunction" = Demo.f1(this, ...);
Related
I have a custom saving method I'm using in a project. Each time I call the method, I'm looking to have the next entry inserted in a new line in a text file.
For example,
if I input "dog1" on the first method call
then input "dog2" on the next method call.
The output should be
dog1
dog2
Unfortunately dog2 overwrites dog1 so my text file output always contains a single entry.
Does anyone notice something off about my code?
Thanks!
public void save(String filename, String st,
Context ctx) {
ArrayList<String[]> list = new ArrayList<>();
list.add(new String[] {st});
FileOutputStream fos;
try {
fos = ctx.openFileOutput(filename, Context.MODE_PRIVATE);
OutputStreamWriter os= new OutputStreamWriter(fos);
String t = st;
for(String[] arr: list){
for(String s: arr){
os.write(s);
}
os.write(System.getProperty( "line.separator" ));
}
os.flush();
os.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
File reader method
public String read(String filename, Context ctx){
String tr="";
FileInputStream fis = null;
try {
fis=ctx.openFileInput(filename);
InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
BufferedReader br = new BufferedReader(isr);
StringBuilder sb= new StringBuilder();
String text;
while((text=br.readLine())!=null){
sb.append(text);
tr = sb.toString();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(fis!=null){
try{
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return tr;
}
Declare ArrayList globally or outside the save method.
Because every time on call save() method new object create for list and override previous data with new data instead of add new data on list.
Declare below line outside save() method or globally
ArrayList<String[]> list= new ArrayList<>();
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.
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.
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. mLine is replaced every pass. That's why I wrote //process line. I assume the file contains some sort of data (i.e 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.
ANOTHER EDIT
According to the comment of #Vincent I added the finally block.
Also note that in Java 7 and upper you can use try-with-resources to use the AutoCloseable and Closeable features of recent Java.
CONTEXT
In a comment #LunarWatcher points out that getAssets() is a class in context. So, if you call it outside of an activity you need to refer to it and pass the context instance to the activity.
ContextInstance.getAssets();
This is explained in the answer of #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.
Make a constructor for Utils class pass reference of activity (ugly way) or context of application as a parameter to it. Using that use getAsset() in your Utils class.
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");
Where YourDataFile.txt is assumed to reside in 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:
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.
If you calling this method in non-Activity class then you need to call this method from Context which is passed from Activity class. So below is the line by you can access the method.
ContextInstance.getAssets();
ContextInstance may be passed as this of Activity class.
Reading and writing files have always been verbose and error-prone. Avoid these answers and just use Okio instead:
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
In 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);
}
Here is a way to get an InputStream for a file in the assets folder without a Context, Activity, Fragment or Application. How you get the data from that InputStream is up to you. 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.
ExceptionProof
It maybe too late but for the sake of others who look for the peachy answers.
loadAssetFile() method returns the plain text of the asset, or defaultValue argument if anything goes wrong.
public static String loadAssetFile(Context context, String fileName, String defaultValue) {
String result=defaultValue;
InputStreamReader inputStream=null;
BufferedReader bufferedReader=null;
try {
inputStream = new InputStreamReader(context.getAssets().open(fileName));
bufferedReader = new BufferedReader(inputStream);
StringBuilder out= new StringBuilder();
String line = bufferedReader.readLine();
while (line != null) {
out.append(line);
line = bufferedReader.readLine();
}
result=out.toString();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
Objects.requireNonNull(inputStream).close();
} catch (Exception e) {
e.printStackTrace();
}
try {
Objects.requireNonNull(bufferedReader).close();
} catch (Exception e) {
e.printStackTrace();
}
}
return result;
}
If you use other any class other than Activity, you might want to do like,
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:
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())
}
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 + "";
}
The Scanner class may simplify this.
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:
private fun 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 inside the 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
}
I'm using this code to save data to file and read data from the file:
public static void save(FileIO files) {
BufferedWriter out = null;
try {
out = new BufferedWriter(new OutputStreamWriter(
files.writeFile(".save")));
for (int i = 0; i < 20; i++) {
out.write(Integer.toString(scores[i]));
out.write("\n");
}
} catch (IOException e) {
} finally {
try {
if (out != null)
out.close();
} catch (IOException e) {
}
}
}
public static void load(FileIO files) {
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(
files.readFile(".save")));
for (int i = 0; i < 20; i++) {
scores[i] = Integer.parseInt(in.readLine());
}
} catch (IOException e) {
} catch (NumberFormatException e) {
} finally {
try {
if (in != null)
in.close();
} catch (IOException e) {
}
}
}
FileIO.java
package com.avoidblocks.avoidblocks.framework;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.content.SharedPreferences;
public interface FileIO {
public InputStream readFile(String file) throws IOException;
public OutputStream writeFile(String file) throws IOException;
public InputStream readAsset(String file) throws IOException;
public SharedPreferences getSharedPref();
}
I'm calling save(FileIO files) and load(FileIO files) multiple times in an app and it works fine while I'm in an app, but when I exit the app and start the app again, all data is gone.
Does anyone know how to create that data remains saved even when I exit the app, so that I could restore the data when I start the app again?
Also, is this the right way to save data if I want that saved data is only visible to my app and that after uninstall, all saved data is erased?
EDIT-EDIT-EDIT:
ok its your FileIO files variable that looks like it is wrong,
what are you using to get that variable?
should be
context.openFileOutput(".save", Context.MODE_PRIVATE)
for save and
context.openFileInput(".save")
for load
and it should be FileOutputStream for save and FileInputStream for read instead of FileIO.
and when adding it to the stream just pass that in.
so in your code you should create the BufferedWriter like this:
out = new BufferedWriter(new OutputStreamWriter(
context.openFileOutput(".save", Context.MODE_PRIVATE)));
and create BufferedReader like this:
in = new BufferedReader(new InputStreamReader(
context.openFileInput(".save")));
==================EDIT: my testing code=================
Ok, I created an activity and made the following two methods and declared an array of ints:
public static int scores[] = {11,12,13,14,15};
public static void save(Context context) {
BufferedWriter out = null;
try {
out = new BufferedWriter(new OutputStreamWriter(
context.openFileOutput(".saveingTest", Context.MODE_PRIVATE)));
for (int i = 0; i < scores.length; i++) {
out.write(Integer.toString(scores[i]));
out.write("\n");
}
} catch (IOException e) {
} finally {
try {
if (out != null)
out.close();
} catch (IOException e) {
}
}
}
public static void load(Context context) {
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(
context.openFileInput(".saveingTest")));
for (int i = 0; i < scores.length; i++) {
Log.d("testingApp", "test: " + Integer.parseInt(in.readLine()));
// scores[i] = Integer.parseInt(in.readLine());
}
} catch (IOException e) {
} catch (NumberFormatException e) {
} finally {
try {
if (in != null)
in.close();
} catch (IOException e) {
}
}
}
in my onCreate I have the following two lines of code:
save(this);
load(this);
to test I did the following:
commented out load in onCreate, ran the app, than I removed the comment on load and commented out save in onCreate and i changed the numbers in the scores variable(this is unnecessary but i did it anyway) and ran the app, the result was the int values in scores from the first time the app was run, inside the android log viewer window on eclipse. you can also have buttons that trigger save and load instead if you don't want to comment and run.
try it yourself, it should work, and make sure you are doing the same thing in your actual android app, if it still dose not work you are doing something else wrong and its not an issue with saving the file.
i'm trying to save a list of integers in my application by saving each integer in a new line of a file in the internal storage.
For retreiving it I read it line by line and put every linevalue, parsed as integer, in my list of integers.
I know a database is better for this kinda stuff, but this should work.
I am trying for quite a while now, but it never seems to work. I always get a nullpointerexception when trying to read. I logged "line", it gave the value it should have. But
saving one id, adding it as a new string:
private void saveToFavorites(Integer saveFav) {
String favstr = String.valueOf(saveFav);
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new OutputStreamWriter(openFileOutput("favorites", MODE_WORLD_WRITEABLE)));
writer.newLine();
writer.append((favstr));
System.out.println(" added to favs :"+ saveFav);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
And the reading method:
#SuppressWarnings("null")
private List<Integer> readFileFromInternalStorage() {
List<Integer> favs = null;
BufferedReader input = null;
try {
input = new BufferedReader(new InputStreamReader(openFileInput("favorites")));
String line;
while ((line = input.readLine()) != null) {
System.out.println("readFileFromInternalStorage line value: "+ line );
favs.add(Integer.parseInt(line));
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("readFileFromInternalStorage: fail" );
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return favs;
}
Which is in an other activity. I thought it would work but it clearly doesnt. When reading back, the logline: System.out.println("readFileFromInternalStorage line value: "+ line );
displays that the value of line equals the LAST added id,and an empty line, and not the others too. So the line by line saving fails. Also when parsing it to an integer it fails, what is weird because it is only a number.
08-01 12:29:54.190: I/System.out(1540): readFileFromInternalStorage line value:
08-01 12:29:54.190: I/System.out(1540): readFileFromInternalStorage line value: 301
Anyone knows what i need to change?
Since Integer is Serializable I sugget to serialize the entire List:
private void saveList(List<Integer> list) {
try {
File file = Environment.getExternalStorageDirectory();
File filename = new File(file, "yourfilename");
fos = new FileOutputStream(filename);
out = new ObjectOutputStream(fos);
out.writeObject(list);
out.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
private void readList()
{
try {
File file = Environment.getExternalStorageDirectory();
File filename = new File(file, "yourfilename");
fis = new FileInputStream(filename);
in = new ObjectInputStream(fis);
List<Integer> list= (List<Integer>) in.readObject();
in.close();
} catch (IOException ex) {
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
}
try this May it help you :-
1 - String saveFav = contaains all integer this form I1+"/"I2+"/"I3;
2:- then save it into file
private void saveToFavorites(String saveFav) {
//right here your code for write into file saveFave string
}
in reading file read string and split("/").it's working for me .
Here's some working code that will read and write ints to the phones internal memory.
You can create an array or list of ints and basically just iterate over it until all ints are saved/read to/from the memory:
Here's the code to write an int to the memory:
public void writePrimitiveInternalMemory(String filename, int value) {
SharedPreferences preferences = this.getPreferences(Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putInt(filename, value);
editor.commit();
}
Here's code to read from the memory:
public int readPrimitiveInternalMemoryInteger(String filename) {
SharedPreferences preferences = this.getPreferences(Activity.MODE_PRIVATE);
return preferences.getInt(filename, 0);
}
I hope this helps you!
You are not allocating the integer list...
List<Integer> favs = null;
Allocate a new arraylist..
List<Integer> favs = new ArrayList<Integer>();
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.
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.
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. mLine is replaced every pass. That's why I wrote //process line. I assume the file contains some sort of data (i.e 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.
ANOTHER EDIT
According to the comment of #Vincent I added the finally block.
Also note that in Java 7 and upper you can use try-with-resources to use the AutoCloseable and Closeable features of recent Java.
CONTEXT
In a comment #LunarWatcher points out that getAssets() is a class in context. So, if you call it outside of an activity you need to refer to it and pass the context instance to the activity.
ContextInstance.getAssets();
This is explained in the answer of #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.
Make a constructor for Utils class pass reference of activity (ugly way) or context of application as a parameter to it. Using that use getAsset() in your Utils class.
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");
Where YourDataFile.txt is assumed to reside in 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:
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.
If you calling this method in non-Activity class then you need to call this method from Context which is passed from Activity class. So below is the line by you can access the method.
ContextInstance.getAssets();
ContextInstance may be passed as this of Activity class.
Reading and writing files have always been verbose and error-prone. Avoid these answers and just use Okio instead:
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
In 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);
}
Here is a way to get an InputStream for a file in the assets folder without a Context, Activity, Fragment or Application. How you get the data from that InputStream is up to you. 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.
ExceptionProof
It maybe too late but for the sake of others who look for the peachy answers.
loadAssetFile() method returns the plain text of the asset, or defaultValue argument if anything goes wrong.
public static String loadAssetFile(Context context, String fileName, String defaultValue) {
String result=defaultValue;
InputStreamReader inputStream=null;
BufferedReader bufferedReader=null;
try {
inputStream = new InputStreamReader(context.getAssets().open(fileName));
bufferedReader = new BufferedReader(inputStream);
StringBuilder out= new StringBuilder();
String line = bufferedReader.readLine();
while (line != null) {
out.append(line);
line = bufferedReader.readLine();
}
result=out.toString();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
Objects.requireNonNull(inputStream).close();
} catch (Exception e) {
e.printStackTrace();
}
try {
Objects.requireNonNull(bufferedReader).close();
} catch (Exception e) {
e.printStackTrace();
}
}
return result;
}
If you use other any class other than Activity, you might want to do like,
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:
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())
}
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 + "";
}
The Scanner class may simplify this.
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:
private fun 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 inside the 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
}