Java / Android: Read and parse .txt file from a url - java

Using java in android studio I am trying to read a .txt file and parse it to obtain some data.
the file: https://www.ndbc.noaa.gov/data/latest_obs/latest_obs.txt
I am using he following code to parse the data:
String[] splited = str.trim().replaceAll(" +", " ").split(" ");
String sDate1= splited[3] + "/" + splited[4] + "/" + splited[5]
+ "/" + splited[6] + "/" + splited[7];
try{
java.util.Date date1 = new
java.text.SimpleDateFormat("yyyy/MM/dd/hh/mm").parse(sDate1);
System.out.println(date1);
}
catch(Exception e){
System.out.println(e.getMessage());
}
String windSpeed = splited[9];
String waveHeight = splited[11];
String airTemperature = splited[17];
String waterTemperature = splited[18];
System.out.println(windSpeed);
System.out.println(waveHeight);
System.out.println(airTemperature);
System.out.println(waterTemperature);
if(windSpeed.toLowerCase().equals("mm")){
// write your code here
}
if(waveHeight.toLowerCase().equals("mm")){
// write your code here
}
if(airTemperature.toLowerCase().equals("mm")){
// write your code here
}
if(waterTemperature.toLowerCase().equals("mm")){
// write your code here
}
The '//write your code here' will just return 'data N/A' since mm refers to missing data.
My problem is I am unsure how to open the file from the url to be read. I would like to open the file every hour, and parse the data below so i can assign it to their buoys in my application.

Your data file is coming from the Internet, so you'll need to download the file first before parsing it. While it is possible to download and parse the file at the same time, let's keep it simple at first.
To download the file, there are many ways to do this, but you might start with OkHttp or UrlConnection (see this SO answer for more info). If you want an alternative, check out Retrofit. Retrofit is a wrapper around OkHTTP to make it a little easier to use for experienced developers, but if you're just getting started, I'd recommend sticking with OkHttp for now until you understand what's going on.
Once the file is downloaded or in memory, you'll probably want to use BufferedReader (as suggested by rileyjsumner) to read and parse one line at a time using the code you posted.
Because you're asking specifically about Android, you'll need to keep a few things in mind:
When reading and writing temporary files, you'll want to use the temporary storage. Check out this documentation for more details: https://developer.android.com/training/data-storage/files
you'll need to do the downloading and file I/O on a separate thread. Android is inherently multithreaded and relies on the main thread to only update the UI. Everything else should be done on a different thread. There are several ways to do this. (see this post or the documentation). Once you get more comfortable with this, you might move on to RxJava.

You may want to use BufferedReader - javadoc
BufferedReader reader = new BufferedReader(new FileReader("url.txt"));
You can then scan through the context of the file.
while(line = reader.readLine() != null) {
// some code
}
This answer has more information on BufferedReader's as well

Related

How to use input from a java code and transfer it into an external application (as well as retrieving output)?

I'm actually not that great and am relatively new at Java. I wish to receive input from the user, and want to input this data into an external application.
This application processes the data and provides an output. I wish to retrieve this output using the Java code.
I have attempted in doing this but, I haven't got the slightest idea on how to start this script.
Nothin' on the internet seems to answer this question. If you have any idea or any new functions that can be useful, please help me in doing so.
Since I'm starting from ground zero, any help is appreciated.
Thanks so much.
To communicate with an external application you need to first define the communication way. For example:
Will this application read the output from a file?
If that statement it's true, then you need to learn serialization:
Will this application read the input from the standard output (like a command-line application)
If that statement it's true then you need to send with System.out.print().
Will this application get the data over HTTP.
Then you need to learn about REST and or RPC architectures.
Assuming that it will be a command-line application, then you could use something like this:
public class App
{
public static void main(String... args)
{
// You need to implement your business logic here. Not just print whatever the user passes as arguments of the command-line.
for(String arg : args)
{
System.out.print(arg);
}
}
}
There's a lot going on here but I'll suggest an example for each part of this question and assume this is just going to be written in Java, and suggesting an iterative design/development approach.
receive input from the user::getting arguments from the command line can work, but I think most users want to use familiar user interfaces like excel to input large amounts of data. Have them export files to .csv or look into reading excel files directly with apache poi. The latter is not for beginners, but not terrible to figure out or find examples. The former should be easy to figure out if you look into reading files and splitting them line by line on the delimiter. Here's an example of that:
try (BufferedReader reader = new BufferedReader(new FileReader(new File("user_input.csv"))) {
String currentLine = reader.readLine();
while (currentLine != null) {
String splitLine[] = currentLine.split(","); //choose delimiter here
//process cells as needed
//write output somewhere so other program can read it later
currentLine = reader.readLine();
}
}
catch (IOException ex) {
System.out.println(ex.getMessage()); //maybe write to an error log
System.exit(1);
}
"input" data to other app::you can use pipes if you're at the command line. but I'd recommend you write to a file and have the other app read it. here's an expansion of the previous code snippet showing how to write to a file as that might be more practical and easier to log/archive/debug.
try (BufferedReader reader = new BufferedReader(new FileReader(new File("user_input.csv")));
BufferedWriter writer = new BufferedWriter(new FileWriter(new File("process_me.csv")))) {
String currentLine = reader.readLine();
while (currentLine != null) {
String splitLine[] = currentLine.split(","); //choose delimiter here
//process cells as needed
writer.write(processed_stuff);
currentLine = reader.readLine();
}
}
catch (IOException ex) {
System.err.println(ex.getMessage());
System.exit(1);
}
Then retrieving output::can just be reading another file with another Java program. This way you're communicating between programs using the file system. You must agree upon file formats and directories though. And you'll be limited to having both programs on the same server.
To make this at scale, you could use web services assuming the other program you're making requests to is a web service or has one wrapped around it. You can send your file and receive some response using URLConnection. This is where things will get much more complex, but now everything in your new program is just one Java program and the other code can live on another server.
Building the app first with those "intermediate" files between the user input code, the external code, and the final code will help you focus on perfecting the business logic, then you can worry about just communication over the network.

Libgdx file handle.. reading a single line

I am trying to save and load files on a project that is coded on libgdx. Which means that i cant use a buffered reader because android wont read it.. and i cant move the project to android because it has to be in the core... after days and days or understanding all.. now i am trying File handing which should work right?? but i cant get it to read line by line.. it puts all the text in on string.. Help plzz.. also is my understanding correct and saving and loading is waaaay more complicated than it should be?? here is the code..
FileHandle handle = Gdx.files.local("words.txt");
String text = handle.readString();
words.add(text);
There are several ways to read this line by line. When your reading a file in using the LibGDX FileHandle API which include strings, byte arrays and into various readers; there are several ways to read the data in. I am assuming you have some form of dictionary in this file, with the words in a list separated by newlines? If this is the case you can take your existing string and split on the new line terminator.
FileHandle handle = Gdx.files.local("words.txt");
String text = handle.readString();
String wordsArray[] = text.split("\\r?\\n");
for(String word : wordsArray) {
words.add(word);
}
There's only really two newlines (UNIX and Windows) that you need to worry about.
FileHandle API
This is to all of you out there new to saving and loading and tired of looking for answers.. let me save u the trouble and days of research...
If you start a project in libgdx and want to save load on android.. Do not follow the buffered reader or inputstreamer or any of these tutorials THEY WILL NOT WORK because for some reason android cannot read inside the assest folder.. it will work on ur desktop version only..
if you are using android studios alone then go ahead with the try catch buffered or file or inputstreamer..
Also the Context.. asset manager.. and that route WILL NOT WORK because the project has to be in your android folder not core to use these libraries..
ELSE FOLLOW THE ABOVE METHOD..
classpath.. internal.. external .. or local ... depending on where you store ur file!!!.. your welcome
String str ="";
StringBuffer buf = new StringBuffer();
FileHandle file = Gdx.files.internal("text.txt");
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(file.read()));
if (is != null) {
while ((str = reader.readLine()) != null) {
buf.append(str + "\n" );
}
}
} finally {
try { is.close(); } catch (Throwable ignore) {}
}

Storing a file as part of android manifest for deployment and then opening it?

Okay I know this should be dead simple but I guess I'm not phrasing my question correctly in my Google & stackoverflow searches.
I have a substantial amount of static data (6 megs) I need to load into my database upon install. Right now I'm fetching a json data file from my web server on first run and populating my database but that can be slow and something could go wrong. I'd prefer to just include the data file in the manifest and then load it on install or first run.
So, where do I put the file, make it so that it ends up on the target device, and then open it?
I've tried putting it in /res/files/ and then doing:
InputStream inputStream = new FileInputStream("/res/files/foo.json");
but of course I'd have been shocked if that had worked.
While I'm at it I should probably use CSV format instead as that would cut down the size but that's another story, I don't seem to have a way to parse it but I do know how to parse JSON data. Sorry I'm a bit new at this. Thanks!
You could store it either in assets or in res\raw.
How to open it from the assets folder:
InputStream is = getAssets().open("foo.json");
How to open it from the res\raw folder:
getResources().openRawResource(R.raw.foo);
I would advise you to use SQLite and/or XML. What #Gabriel suggested will most likely work fine, but loading and processing 6MBs may take some time -a time window of 1 to 5 secs to my experience. Since you downloaded from your webserver I believe your data has some form of structure and in your app you won't need all of the data at once.
Here are some guides/tutorials about SQLite in android, keep in mind that XML is also viable and some will probably advocate XML over SQLite in this case.
http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html
http://www.vogella.com/tutorials/AndroidSQLite/article.html
You can put your JSON file in the raw folder (res/raw) and load it with this code :
InputStream inputStream = getResources().openRawResource(R.raw.foo);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
inputStream.close();
JSONArray jArray = new JSONArray(sb.toString());
Then you can use your knowledge to parse the JSONArray.

Changing a String in a php file on a web server with java?

Basically i have these two pages... each with a string that i get with a minecraft bukkit plugin. I need to know if its possible that i can change the String in the index.php file which sits on a web server using java methods. Basically I'm too lazy to edit the files every time i release a update to my plugin. To get more info on what I'm talking about.... http://updates.milkycraft.net/ - for the version. The source code of my plugin can be found at http://github.com/milkywayz/entitymanager/. I would probably just want to create a separate java application with swing and have that update the values. The index.php file for both strings are extremely simple, i just declared a string variable then echo'd it.
Of course you could change the PHP file, but it's not the best solution - it would be really error-prone. There is an other alternative: write the data to the separate file in a well-known format (XML, JSON, YAML, INI etc.) and let the PHP script read it.
Map<String, String> data = new HashMap<String, String>();
data.put("a", "value a");
data.put("b", "value b");
data.put("c", "value c");
// Convert a Map to JSON using GSON:
String data = new Gson().toJson(data);
// Write data to the file:
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new FileWriter("/path/to/file"));
writer.write(data);
writer.flush();
} catch ( ... ) {
...
} finally {
if (writer != null) {
writer.close();
}
}
// Read the data
$data = json_decode(file_get_contents('/path/to/file'));
print_r($data);
Of course you can.
There are different approaches you can take
Have a index.template where you put in a placeholder like
In java you open that file, replace the with your value and save it as index.php
Or you can enclose the string in the index.php with something like mystring
You then open the index.php and replace the content between START/END replace
André

Using a button to export sqlite db to an excel-readable file (perhaps csv)?

I adapted this tutorial (http://www.screaming-penguin.com/node/7749) to an Android app I've built to allow for a button press to export the current database to the user's sdcard. It works flawlessly.
But I'm afraid that users of my app would be unfamiliar with the db file, and I'm looking for a way to convert that to a more user-friendly format. I came across this thread (http://groups.google.com/group/android-beginners/browse_thread/thread/4e53ebca14daecfc), which recommends "querying data from the database and writing the data into a csv file."
I was hoping someone could point me in the right direction to begin figuring out how to do this. I'm finding it hard to track down more information about the specific method.
Or does it make more sense to just explain in a short "about" how to read and access .db files?
Thanks
EDIT: I also have a question about the sqlite export process, which I think I'll just ask here rather than create a new question. Is there a way to modify the code below so that each export would receive either a string representation of the date or just a single numeral appended to it? Right now if you export a second time, it automatically overwrites the old file. Thanks.
protected Boolean doInBackground(final String... args) {
File dbFile = new File(Environment.getDataDirectory() +
"/data/com.example.example/databases/data");
File exportDir = new File(Environment.getExternalStorageDirectory(), "exampledata");
if (exportDir.exists()) {
exportDir.mkdirs();
}
File file = new File(exportDir, dbFile.getName());
try {
file.createNewFile();
this.copyFile(dbFile, file);
return true;
} catch(IOException e) {
Log.e(MyApplication.APP_NAME, e.getMessage(), e);
return false;
}
}
I was hoping someone could point me in the right direction to begin figuring out how to do this.
To read in the data, use rawQuery().
To write the data, use Java I/O. There are also open source CSV libraries for Java that may work on Android.
Is there a way to modify the code below so that each export would receive either a string representation of the date or just a single numeral appended to it?
Use string concatenation to add whatever you want to the filename.
Also, please get rid of:
File dbFile = new File(Environment.getDataDirectory() +
"/data/com.example.example/databases/data");
and replace it with:
File dbFile=getDatabasePath("data");

Categories