Load simple JSON file into 2 dimensional Array in Android - android

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.

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.

Custom function which searches for tags in file always return null

I've created a custom function which should search a file for a specified tag, and return the value of it, like this:
Function call:
getSingleLineValue("tagname");
Found line in file:
<tagname>=tagvalue
Returned String:
tagvalue
Here is the code for the function:
public String getSingleLineValue(String tag) {
// The value
String value;
// If the list of passed tags contains the wanted tag
if(passedTags.contains(tag)) {
// Close the readers
close();
// RESET EVERYTHING
try {
// Re-create the FileReader
fileReader = new FileReader(file);
// Re-create the BufferedReader
bufferedReader = new BufferedReader(fileReader);
// Reset the passed tags array
passedTags.clear();
// Recall the function
value = getSingleLineValue(tag);
// Return the value
return value;
} catch(IOException e) {
// Handle the exception
e.printStackTrace();
}
} else {
try {
// The current line
String line;
// While the file has lines left
while ((line = bufferedReader.readLine()) != null) {
// If the current line contains a pair of tag marks ( < and > )
if (line.contains("<") && line.contains(">")) {
// If the line contains the tag
if(line.contains(tag)) {
// Store the parts of the tag in an array (tag and value)
String[] tagParts = line.split("=");
// Get the value
value = tagParts[1];
// Return the value
return value;
} else {
// Get the passed tag
String passedTag = line.substring(1, line.indexOf(">") - 1);
// Add the tag to the passed tags array
passedTags.add(passedTag);
}
}
}
} catch(IOException e) {
// Handle the exception
e.printStackTrace();
}
}
// If the tag wasn't found, return null
return null;
}
The object called file is a simple File object with the path to the file I want to read. It's declared in the same class.
The objects called fileReader and bufferedReader is just what it sounds like. A FileReader and a BufferedReader, declared like this (also in the same class):
private FileReader fileReader;
private BufferedReader bufferedReader;
And in the constructor of the class:
fileReader = new FileReader(file);
bufferedReader = new BufferedReader(fileReader);
The problem is that this function always return null, so when I call it, the above demonstration about how I want it to work would instead look something like this:
Function call:
getSingleLineValue("tagname");
Found line in file:
Unknown (maybe this is the problem?)
Returned String:
null
The problem might be something with the line, because when I print it, I don't get any message in the console, but I don't really know what could be wrong with it, if it's the problem.
All help is greatly appreciated!
I've found out what was the problem. It wasn't the function, which actually worked fine, but it was the file's encoding.
I created a simple computer version and added the function to it, and printed all read lines, and found out that the file was read differently in the program than in Sublime Text (a text editor on the computer). A line which looked like this:
ABCDEFG
in the text editor, was read by the program like this:
A B C D E F G
So basically, it added a space between each character. I think the problem is with the file encoding, so the function works great itself.
EDIT: I solved the file encoding problem by using a FileInputStream and set it's encoding to "UTF-16LE", which was the correct encoding for my file, so the code above instead looked like this:
public String getSingleLineValue(String tag) {
// The value
String value;
// If the list of passed tags contains the wanted tag
if(passedTags.contains(tag)) {
// Close the readers
close();
// RESET EVERYTHING
try {
// Re-create the FileInputStream
fileInput = new FileInputStream(file); // <----- Changed
// Re-create the InputStreamReader
inputReader = new InputStreamReader(fileInput, "UTF-16LE"); // <----- Changed
// Re-create the BufferedReader
bufferedReader = new BufferedReader(inputReader); // <----- Changed
// Reset the passed tags array
passedTags.clear();
// Recall the function
value = getSingleLineValue(tag);
// Return the value
return value;
} catch(IOException e) {
// Handle the exception
e.printStackTrace();
}
} else {
try {
// The current line
String line;
// While the file has lines left
while ((line = bufferedReader.readLine()) != null) {
// If the current line contains a pair of tag marks ( < and > )
if (line.contains("<") && line.contains(">")) {
// If the line contains the tag
if(line.contains(tag)) {
// Store the parts of the tag in an array (tag and value)
String[] tagParts = line.split("=");
// Get the value
value = tagParts[1];
// Return the value
return value;
} else {
// Get the passed tag
String passedTag = line.substring(1, line.indexOf(">") - 1);
// Add the tag to the passed tags array
passedTags.add(passedTag);
}
}
}
} catch(IOException e) {
// Handle the exception
e.printStackTrace();
}
}
// If the tag wasn't found, return null
return null;
}

Read all lines from BufferedReader before continuing

I am having a bit of an issue with my app. I receive a data through a socket, via a BufferedReader. I loop round with while ((sLine = reader.readLine ()) != null) and append the sLine to a StringBuilder object. I also spend a new line \n to the builder.
The plan is that once the builder is all finished, String sTotal = builder.toString()is called and a total is passed to the next routine.
However, the next routine is instead being called once for each line rather than with the string as a whole. The routine call is outside the loop above so I really don't know why!
Hope someone can help...
Edit: Code extract below.
public void run() {
try {
oServerSocket = new ServerSocket(iPort);
while ((!Thread.currentThread().isInterrupted()) && (!bStopThread)) {
try {
oSocket = oServerSocket.accept();
this.brInput = new BufferedReader(new InputStreamReader(this.oSocket.getInputStream()));
StringBuilder sbReadTotal = new StringBuilder();
String sReadXML = "";
while ((sReadXML = brInput.readLine()) != null) {
sbReadTotal.append("\n");
sbReadTotal.append(sReadXML);
}
sReadXML = sbReadTotal.toString();
Log.d("XMLDATA", sReadXML);
processXML(sReadXML);
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
/* Nothing Yet */
e.printStackTrace();
}
}
If you're exiting your internal while loop, it means you reached the end of your input stream (that's when readLine() returns null according to the docs).
You should be looking into the client, and not the server. What's establishing the client socket? Are you sure it's not establishing a separate connection for each line it sends?

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

Reading a file returns long string without "spaces , newlines"

Good all;
I am trying to read some files (from assets) based upon list selections. The code below opens the file and retrieves the content nicely even Arabic letters. the only problem is that the text comes as a very long string without any spaces or newlines. for example the file content is:
first line
second line
third line
the output will be : firstlinesecondlinethirdline
the code is :
public void onItemSelected(AdapterView parent, View v,
int position, long id) {
String filename = getFileName(position);
InputStreamReader ls = null;
try {
AssetManager am = getResources().getAssets();
ls = new InputStreamReader(am.open(filename), "UTF-8");
StringBuffer sb = new StringBuffer();
while( true ) {
int c = ls.read();
if( c < 0 )
break;
if( c >= 32 )
sb.append( (char)c );
selection.setText(new String(sb));
}
} catch(IOException e) {
Log.e(LOG_APP_TAG, e.getMessage());
} finally {
if (ls != null) {
try {
ls.close();
} catch (IOException e) {
Log.e(LOG_APP_TAG, e.getMessage());
}
}
}
}
Your code has several problems :
it is not recommended to use the key word break
using a loop with the condition (true) and breaking it in case of something is very close to "goto programming" and should be avoided.
you could have something like
boolean finished = true;
while( !finished )
{
if( c < 0 )
finished = true;
}//while
This kind of loop is more pleasant to read to my mind, and doesn't "shock" as there is not "endless loop" when you read it.
Moreover, you should really consider using a BufferedReader to read text files. This class will provide you with lines of chars, that would give a simpler code :
BufferedReader bfr = new BufferedReader( new InputStreamReader(am.open(filename), "UTF-8"); );
StringBuffer sb = new StringBuffer();
String read = "";
while( (read=bfr.readLine()) != null )
sb.apennd( read );
BuffereReader will use a buffer to read more than one byte at a time from your file, which is much more efficient.
Btw, you try/catch/finally structure is pretty well done.
Regards,
Stéphane
New line has character value of 10 (<32), so its not appended, so consider appending all characters with >0 value, hence change to
if( c <= 0 )
break;
else
sb.append( (char)c );

Categories

Resources