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.
Related
Driving myself crazy over the simplest thing. I have a JSON file called config.txt. The file is shown below.
{
"UsePipesInGuestData": true
}
All I want to do is get a 2 dimensional array such that:
Array[0] = UsePipesInGuestData and
Array[1] = true
I have been trying for 4 hours with various attempts, my most recent is shown below:
private void getConfig(){
//Function to read the config information from config.txt
FileInputStream is;
BufferedReader reader;
try {
final File configFile = new File(Environment.getExternalStorageDirectory().getPath() + "/guestlink/config.txt");
if (configFile.exists()) {
is = new FileInputStream(configFile);
reader = new BufferedReader(new InputStreamReader(is));
String line = reader.readLine();
while (line != null) {
line = reader.readLine();
if(line!= null) {
line = line.replace("\"", ""); //Strip out Quotes
line = line.replace(" ", ""); //Strip out Spaces
if ((!line.equals("{")) || (!line.equals("}"))) {
} else {
String[] configValue = line.split(":");
switch (configValue[0]) {
case "UsePipesInGuestData":
if (configValue[1].equals("true")) {
sharedPreferences.edit().putString("UsePipes", "true").apply();
} else {
sharedPreferences.edit().putString("UsePipes", "false").apply();
}
break;
}
}
}
}
reader.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
I cannot seem to ignore the lines with the { and } in them.
Clearly there MUST be an easier way. JAVA just seems to take an extremely large amount of code to do the simplest thing. Any help is greatly appreciated.
I believe your condition is incorrect. You try to read the file in the else of the condition (!line.equals("{")) || (!line.equals("}")). Simplifying, your code will run when the following happens:
!(!{ || !}) => { && } (applying De Morgan's law)
This means you will only run your code when the line is "{" AND it is "}" which is a contradiction. Try using simple conditions, like (!line.equals("{")) && (!line.equals("}")) (this is when you want to execute your code).
Additionally, you may be getting end of line characters (\n) in your string, which will make your condition fail ("{\n" != "{"). I suggest you debug and see the actual values you're getting in those lines.
I'm currently working on an android project which allows user to write text using different colors and store them for later use(i.e., editing or reading).
Is their any way to store a file in android with multi color text ??
NOTE: I googled out for the solution but can't find anything useful.
I'm guessing the user has to perform some action to switch color?
If so - you can use that trigger to store the text position/length when switching and save a list of text position - color.
A commenter suggested HTML, and that may be a good choice. You are welcome to try Html.fromHtml() to populate your EditText with the contents of a simple HTML-formatted file, and you are welcome to try Html.toHtml() to generate HTML from the contents of your EditText. However, historically, those methods were not written to do a good job of implementing a "round trip", meaning that the contents of the EditText may wind up changing from its starting point to what it contains after doing Html.toHtml() (to generate and save the HTML) and Html.fromHtml() (to populate the EditText with the previously-saved HTML). If they do not work, you can either fork that Html class and try to modify it as needed, or write your own code to take a Spanned object and convert it to/from HTML, by examining the spans and generating HTML tags from them.
PROBLEM SOLVED:
Code for storing a multi color text from EditText to a txt file:
protected void onDestroy() {
super.onDestroy();
boolean writing_allowed= ExternalStorageWriting.isWritingPossible();
if(writing_allowed)
{
String store= Html.toHtml(et.getEditableText());
File myExternalFile = new File(getExternalFilesDir(filepath), filename3);
try {
FileOutputStream fos = new FileOutputStream(myExternalFile);
fos.write(store.getBytes());
fos.close();
} catch (Exception e) {
Toast.makeText(Notes.this, "Something went wrong...", Toast.LENGTH_SHORT).show();
}
}
}
Code for reading that txt file and displaying it in EditText :
private void setNotes()
{
String myData="";
try {
File myExternalFile = new File(getExternalFilesDir(filepath), filename3);
FileInputStream fis = new FileInputStream(myExternalFile);
DataInputStream in = new DataInputStream(fis);
BufferedReader br =
new BufferedReader(new InputStreamReader(in));
String strLine;
while ((strLine = br.readLine()) != null) {
myData = myData + strLine;
}
in.close();
} catch (IOException e) {
e.printStackTrace();
}
Spanned htmlText = Html.fromHtml(myData);
et.setText(htmlText);
}
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.
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.
My Program needs to be able to scan a text file, and store the values of the text file into a database.
Suppose I've read in a line of code that looks like this
3,95003,"ALLENDALE",,41.030902,-74.130957,2893
I want to be able to call a part of the string and store it as a database value. How exactly would I do that? I already know how to read in text files, but i need to know how to filter and only grab a part of them.
In a database I would usually add a value by doing something like this.
values.put("A", "B");
How can i read a value from only part of the textfile into B?
Say I want it to display values.put("A", "ALLENDALE").
Answer:
AgencyString = readText();
tv = (TextView) findViewById(R.id.letter);
tv.setText(readText());
StringTokenizer st = new StringTokenizer(AgencyString, ",");
while (st.hasMoreElements()) {
tv.setText(st.nextToken());
}
}
private String readText() {
InputStream inputStream = getResources().openRawResource(R.raw.agency);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int i;
try {
i = inputStream.read();
while (i != -1) {
byteArrayOutputStream.write(i);
i = inputStream.read();
}
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
return byteArrayOutputStream.toString();
}
The next step for me is to store these values seperated into an array, and read them into my database. I was able to filter through my agency.txt file by using a StringTokenizer method and setting a 'comma' as my delimiter.
Look at. Use delimiters ",".
http://developer.android.com/reference/java/util/StringTokenizer.html
http://developer.android.com/reference/java/lang/String.html#split(java.lang.String)
http://docs.oracle.com/javase/7/docs/api/java/util/StringTokenizer.html
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#split(java.lang.String, int)