own csv reader to string array out of memory - android

because i am only reading a very simple csv, where only strings are comma separated and should be converted to a String[].
I thought this was so easy a external jar would be a bit to much and i could handle this very easy. But what happens is that the first item get added until the memory is full and crash!
public List readWinkels(Activity a){
List winkelList = new ArrayList();
try{
InputStream winkelcsv = a.getResources().getAssets().open("winkels.csv");
BufferedReader br = new BufferedReader(new InputStreamReader(winkelcsv, "UTF-8"));
String s = br.readLine();
while (s != null){
winkelList.add(s);
System.out.println(s.toString());
}
br.close();
for(int i =0;i<winkelList.size();i++) {
System.out.println(winkelList.get(i));
}
}catch(IOException ioe){
ioe.printStackTrace();
}
return winkelList;
here is my code.... i dont get why it doesnt work, can anyone help? A readline reads the line and then the reading points jumps to the next line (i think) so why is the first line added a zillion times?

Here's the standard idiom for using a while loop to iterate over lines of a file, applied to your code:
String s;
while ((s = br.readLine()) != null){
winkelList.add(s);
System.out.println(s.toString());
}
You need to call readLine() at every iteration through the loop. The original code is nothing but an infinite loop, since s is only read once. Assuming s is not null, the loop condition is never false, so the list grows without bound until all available memory is used.

Related

Reading a large text file with over 130000 line of text

How can i read a large text file into my Application?
This is my code but it does not work. My code must read a file called list.txt. The code worked only with a file with only 10.000 lines.
can someone helps me?
Thanks!
My code:(Worked with small files, but not with large files)
private void largefile(){
String strLine2="";
wwwdf2 = new StringBuffer();
InputStream fis2 = this.getResources().openRawResource(R.raw.list);
BufferedReader br2 = new BufferedReader(new InputStreamReader(fis2));
if(fis2 != null) {
try {
LineNumberReader lnr = new LineNumberReader(br2);
String linenumber = String.valueOf(lnr);
while ((strLine2 = br2.readLine()) != null) {
wwwdf2.append(strLine2 + "\n");
}
// Toast.makeText(getApplicationContext(), linenumber, Toast.LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), wwwdf2, Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Since you are processing a large file, you should process the data in chunks . Here your file reading is fine but then you keep adding all rows in string buffer and finally passing to Toast.makeText(). It creates a big foot-print in memory. Instead you can read 100-100 lines and call Toast.makeText() to process in chunks. One more thing, use string builder instead of string buffer go avoid unwanted overhead of synchronization. You initializing wwwdf2 variable inside the method but looks it is a instance variable which I think is not required. Declare it inside method to make it's scope shorter.

Android - How to save an array of int/bool, check if it exists, and load it back after restarting app

Previously I've asked some questions regarding what method I should use to save some data from my app to retrieve at a later time after it's been closed/stopped. I got the answers I was looking for, I think. But since then, my efforts to implement such a feature has fallen way short. I've researched various questions I've had, for which I thought I found answers. But it seems that the answers, while maybe correct, are not a match necessarily for each other. What I mean, is they might work separately, but coming from various sources, they don't work together as a whole, and for me they don't work at all. I'm led to believe I want to use SharedPreferences. That may or may not be the case, but that has been the direction of my efforts lately.
So I'll ask this multi-part question.
How would you go about saving an array of integers(or boolean values)?
Before loading that saved array, how would I check if it exists?
How would I load the array to use its values again?
Those are the basis of my issues right now. Even at this point, as frustrated as I may be, I don't mind doing more research if someone can point me in the right direction, but everywhere I've looked seems to be missing information and I'm unable to really understand/see how to code what I want to do.
If you REALLY want to see some code, I can show you all my broken pieces at the moment (what I haven't deleted), but I don't see it doing you any good. That said, I'll answer any questions you may need to help me out.
Thanks in advance.
EDIT: The array will change very little from app version to version. It should be about 500-2000 integers or boolean values (either/or will work the same for me). The array is basically a set of flags that tells the app to do one thing or another depending on the value. The size will only change if I add or remove items between versions. For this reason, after checking if the file/array exists, I'll compare the saved array with one in the app and act accordingly.
I've had similar issues with data that has to be preserved through a reboot. I found two ways to do it.
1) Data is seldom accessed.
Store data in .../files in some format that can be easily saved/retrieved. I used JSONArrays to hold the data. mContext.getFilesDir() will get you the path, and you can simply see if your file.exists() to determine if the data exists.
You will need to create an object that will:
1) convert your data to the stored format
for(int i = 0; i < mArray.size(); i++ )
{
JSONObject jo = new JSONObject();
jo.put("THINGY", mArray[i]);
ja.put(jo);
}
2) retrieve your data from the store
String js = readFromFile(fileName);
if( !js.isEmpty() )
ja = new JSONArray( js );
for( int i = 0; i < ja.length(); i++
{
// CONVERT THIS ARRAY TO YOUR INT...
}
3) read/write files like this:
private void writeToFile(String fileName, String data)
{
try
{
FileOutputStream fOut = openFileOutput( fileName, MODE_PRIVATE );
OutputStreamWriter osw = new OutputStreamWriter(fOut);
// Log.d(TAG, "Writing output log...");
osw.write(data);
osw.flush();
osw.close();
}
catch( Exception e )
{
Log.e(TAG, "Cannot create " + fileName );
}
}
private String readFromFile(String fileName)
{
String ret = "";
try
{
InputStream inputStream = openFileInput(fileName);
if ( inputStream != null )
{
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String receiveString = "";
StringBuilder stringBuilder = new StringBuilder();
while ( (receiveString = bufferedReader.readLine()) != null )
{
stringBuilder.append(receiveString);
}
inputStream.close();
ret = stringBuilder.toString();
}
}
catch (FileNotFoundException e)
{
Log.e(TAG, "File not found: " + e.toString());
}
catch (IOException e)
{
Log.e(TAG, "Can not read file: " + e.toString());
}
return ret;
}
JSON works well in this case because there are easy methods to convert to/from strings.
2) Frequent Access
I used SQLiteDatabase. I use a Singlton and DBHelper.getInstance() to get access to it. This seems like overkill, but it is a good solution if the amount of data you are saving is increasing beyond a simple array of Integers.
A really basic (but sound) place to start is: http://www.vogella.com/tutorials/AndroidSQLite/article.html. Note his page was written for 4.3.
HTH.

What is the best way to view large text files from websites?

I tried webview.loadurl("www.blahblah.com/blah.txt") and it crashed after a couple of seconds. What else can I do?
I only want to view these .txt files from the web as fast and as stable as possible.
Also I came across asynctask while researching. What is it and can it help me with this?
Also how can I make them to a string if I want to display these text files as a listview item?
Asynctask is wrapper for a new thread that allow you to perform network tasks such as downloading. If you try to download on the UI thread, you will get a crash.
For the text file, download it to disc first, and then read it into memory and display it
StringBuilder txtString = new StringBuilder();
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String textLine;
while ((textLine = br.readLine()) != null) {
txtString.append(line);
txtString.append('\n');
}
}
catch (IOException e) {
//error stuff
}

I keep getting ArrayIndexOutOfBoundsException

Keep getting ArrayIndexOutOfBoundsException when trying to display a specific item form array list data displays fine in logcat but then after displaying throws exception at top please help is the code kind of new to android
public void loadData(){
InputStream file = ourContext.getResources().openRawResource(R.raw.cashpot);
BufferedReader reader = new BufferedReader(new InputStreamReader(file));
String line ="";
ArrayList<String> values = new ArrayList<String>();
try {
while((line = reader.readLine()) != null) {
values.add(line);
// String[] strings = line.split(",");
/*for(String s : strings) {
values.add(s);
}*/
}
reader.close();
//for(String s : values) Log.d("CSV Test", s);
for(int i = 0; i < values.size();i++){
String[] data = values.get(i).split(",");
Log.d("Test String",data[2] );
}
} catch (IOException e) {
e.printStackTrace();
}
}
Your some lines do not have comma(,)(or 1 comma) and you are trying to split them by comma and storing it in to data array. and you are accessing data[2] location. which might not been created that's why you are getting this exception.
There might not be a 3rd element in your array ,that is created after the split on ",".
You can print value of data before accessing data[2](that might not exist).
Or you can Debug your program and proceed step by step and monitoring the value of each variable.

Android - Comparing String Input On A Textfile Content

May I ask you to guide me how I can accomplish this problem?
I need to compare an inputWord to a string inside a .txt file and if found, return the whole line but if not, show "word not found".
Example:
inputWord: abacus
Text file content:
abaca - n. large herbaceous Asian plant of the banana family.
aback - adv. archaic towards or situated to the rear.
abacus - n. a frame with rows of wires or grooves along which beads are slid, used for calculating.
...
so on
Returns: abacus with its definition
What i am trying to do is compare my inputWord to the words before the " - " (hyphen as delimiter), if they dont match, move to the next line. If they match, copy the whole line.
I hope it doesnt seem like im asking you to "do my homework" but I tried tutorials around different forums and sites. I also read java docs but i really cannot put them together to accomplish this.
Thank you in advance!
UPDATE:
Here's my current code:
if(enhancedStem.startsWith("a"))
{
InputStream inputStream = getResources().openRawResource(R.raw.definitiona);
try {
BufferedReader in = new BufferedReader(new InputStreamReader(inputStream));
String s = in.readLine();
String delimiter = " - ";
String del[];
while(s != null)
{
s = in.readLine();
del = s.split(delimiter);
if (enhancedStem.equals(del[0]))
{
in.close();
databaseOutput.setText(s);
break;
}
}
in.close();
}
catch (FileNotFoundException e) {
databaseOutput.setText("" + e);
}
catch (IOException e1) {
databaseOutput.setText("" + e1);
}
}
Thanks a lot! Here's what I came up, and it returns the definition of inputs properly but the problem is, when i enter a word not found in the textfile, the app crashes. The catch phrase doesn't seem to work. Have any idea how I can trap it? Logcat says NullPointerExcepetion at line 4342 which is
s = in.readLine();
Assuming that the format of each line in the text file is uniform. This could be done in the following manner :
1) Read the file line by line.
2) Split each line based on the delimiter and collect the split String tokens in a temp String array.
3) The first entry in the temp token array will be the word before the "-" sign.
4) Compare the first entry in the temp array with the search string and return the entire line if there is a match.
Following code could be put up in a function to accomplish this :
String delimiter = "-";
String[] temp;
String searchString = "abacus";
BufferedReader in = new BufferedReader(new FileReader(file));
while (in.readLine() != null) {
String s = in.readLine();
temp = s.split(delimiter);
if(searchString.equals(temp[0])) {
in.close();
return s;
}
}
in.close();
return ("Word not found");
Hope this helps.
you may try like:
myreader = new BufferedReader(new FileReader(file));
String text = "MyInput Word";
while(!((text.equals(reader.readLine())).equals("0")));

Categories

Resources