BufferedReader gives weird behaviour on different Android versions - java

I am trying to open an existing file, and process it, and save it somewhere else in Android.
File in = new File("/sdcard/a.pdf"); // This file exists in the location and has been obtained by using getExternalStorage()
FileInputStream fis = new FileInputStream(in);
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
header = br.readLine(); // this gives first line in android 2.3.3 but gives null in android 2.3.6
Executing the above code in Android 2.3.3 gives me the header while executing it in Android 2.3.6 gives "null" in the header.
What may be the problem?
Please Help.

Make sure you explicitly specify the charset to use in each case. At the moment you are relying on the default, which may vary between platforms.
Try the alternative InputStreamReader constructor instead:
new InputStreamReader(fis, "UTF-8")

Related

Why can't I get a file from resources?

Why can't I get a file from resources?
URL resource = getClass().getClassLoader().getResource("input data/logic test.csv");
System.out.println("Found "+resource);
CSVParser parser = new CSVParserBuilder().withSeparator(';').build();
CSVReader reader = new CSVReaderBuilder(new FileReader(resource.getFile())).withSkipLines(1).withCSVParser(parser).build();
Console output:
Found file:/home/alexandr/Repos/OTUS/first_home_work/target/classes/input%20data/logic%20test.csv
Exception in thread "main" java.io.FileNotFoundException: /home/alexandr/Repos/OTUS/first_home_work/target/classes/input%20data/logic%20test.csv (Нет такого файла или каталога)
There is an inherent logic problem with this line:
CSVReader reader = new CSVReaderBuilder(
new FileReader(resource.getFile()))..
Once the CSV is part of a Jar, it will no longer be accessible as a File object. But something like this should work directly for the URL.
CSVReader reader = new CSVReaderBuilder(
new InputStreamReader(resource.openStream()))..
change space for _ in directory name and file name, and working
This will only work while the resource is not in a Jar file.
It's:
try (InputStream raw = ClassThisIn.class.getResourceAsStream(""input data/logic test.csv")) {
InputStreamReader isr = new InputStreamReader(raw, StandardCharsets.UTF_8);
BufferedReader br = new BufferedReader(isr);
// now use br as if it was your filereader.
}
This addresses many issues:
Still works regardless of how you're running it: Your snippet only works if running as straight class files (vs., say, in a jar), and doesn't work if spaces are involved.
Still works even if your class is subclassed (getClass().getClassLoader().getResource won't, which is why you should not do that).
Still works even if the platform local charset encoding is weird (the snippet in this answer is explicit about it. That's always a good idea).
Doesn't have a resource leak. Your code never safely closes the reader you open. If you open resources, either do so in a try-with-resources construct, or, store the resource in a field and implement AutoClosable.
i change space for _ in directory name and file name, and working.... omg.
The answer is in your console output - the file was simply not found.
I would try the same code you have written, but use a file without spaces in it - and see if the file is still not found.

How to load the same JSON file in both an Android app and local unit test?

I have an Android project that displays data from a JSON file. The file is read from the assets directory, following the approach below:
src/main/assets/my_file.json
InputStream is = getResources().getAssets().open(filename);
BufferedReader br = new BufferedReader(new InputStreamReader(is));
// use StringBuilder to get file contents as String
I also have local unit tests which require the same JSON file. In order to avoid the slowness of Instrumentation tests, I am currently loading a duplicate of the file as below:
src/main/resources/my_copy.json
File testData = new File(getClass().getResource(filename).getPath());
InputStream is = new FileInputStream(testData);
// read File as before
Is there an approach that would allow the JSON file to be stored in one location, whilst running the unit tests on a local JVM?
If you're using Robolectric, see this answer.
Note that the "assets" directory is an Android concept, it's different from Java resources. That said, you could also move your JSON file from assets to resources, and use it from both Android and JVM form there like you would in any Java application.
Files in the resource directory can be accessed within Android applications by using ClassLoader#getResourceAsStream(). This returns an InputStream, which can then be used to read the file. This avoids having to duplicate files between resources and the assets directory.
InputStream is = getClass().getClassLoader().getResourceAsStream("my_file.json");
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = null;
StringBuilder sb = new StringBuilder();
while ((line = br.readLine()) != null) {
sb.append(line);
}
}
String json = sb.toString();

Getting the newest version (not the cached version) of a text file on a server using java Streams to read

I have a url of a text file and I want to read it:
URL url = new URL("example.com/textfile.txt");
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String inpuline = null;
while ((inpuline = in.readLine()) != null) {
System.out.println(inpuline);
}
in.close();
The problem is when I change the Content of textfile.txt, my program does not realize the changes next time it runs.
After you change the txt file, you should verify that your server realized the changes and return the last version of your file. To verify this use a browser. If you didn't get the last version of your file something is wrong with the server. If you need to press Ctrl+F5 it means that the maybe some proxies or your browser cashed the old file.
After all trying the following workarounds may helps:
try {
URL url = new URL("example.com/textfile.txt");
Scanner s = new Scanner(url.openStream());
// read from your scanner
}
catch(IOException ex) {
ex.printStackTrace(); // for now, simply output it.
}
If you got the cached version of your file again, then try to use HttpURLConnection to download the file and write it to a temp file. Then read from that temp file and after that delete that temp file. Maybe downloading the file can force the server to get the newest version of that file. To avoid cached version of your file try this:
// Create a URLConnection object
URLConnection connection = myURL.openConnection();
// Disable caching
connection.setUseCaches(false);
Good Luck.

Get automatically a CSV from external server using Spring MVC

I have a scheduled task (using cron) inside my Spring MVC application. Inside the programmed task I have to get a CSV from an external server in the following link:
http://www.aemet.es/es/eltiempo/observacion/ultimosdatos_6172O_datos-horarios.csv?k=and&l=6172O&datos=det&w=0&f=temperatura&x=h24
And once I get it I have to parse it.
The problem comes when getting the file, as when I click on the previous link I can download it to my computer, but I don't know how to do that using Spring.... can you give me I hint??
UPDATE: I don't have any code yet, but I guess that must be something similar to the following code:
URL stockURL = new URL("http://example.com/stock.csv");
BufferedReader in = new BufferedReader(new InputStreamReader(stockUrl.openStream()));
CSVReader reader = new CSVReader(in);
But the problem is that my URL is not exactly a .csv. Whe I put the URL in a browser it looks like it is a redirect.
Thank you very much indeed.
Thank you all for your comments. Even if the URL doesn't have a CSV extension, i tried the following code (in Java, not Spring) but it works!!
URL stockURL = new URL("http://www.aemet.es/es/eltiempo/observacion/ultimosdatos_6172O_datos-horarios.csv?k=and&l=6172O&datos=det&w=0&f=temperatura&x=h24");
BufferedReader in = new BufferedReader(new InputStreamReader(stockURL.openStream()));
//CSVReader reader = new CSVReader(in);
String line;
while((line = in.readLine()) != null){
System.out.println(line);
}
So,I guess that using Spring is going to be really very similar to get the file, so thank you very much everybody!

Android: FileInputStream reading old file

I am storing my file in /data directory.
inputStream = new FileInputStream(Environment.getDataDirectory()+"/logfile.txt");
BufferedReader r = new BufferedReader(new InputStreamReader(
inputStream));
while ((line = r.readLine()) != null)
{...}
After I change my file and upload it to the device using adb and run the app, the app still continues to read the unchanged file from somewhere. But when I start to debug to see whats happening, its reading the modified file.
I am not sure if its caching it somewhere.
Please help.

Categories

Resources