I have a problem with reading a ULR response. On Android it only reads around the half of the response.
If I use the same code in a normal Java project everything works fine.
try {
String _output = null;
URL url = new URL("http://example.com");
BufferedReader buffer = new BufferedReader(new InputStreamReader(url.openStream()));
StringBuilder everything = new StringBuilder();
String line;
while ((line = buffer.readLine()) != null) {
everything.append(line);
}
_output = everything.toString();
buffer.close();
System.out.print(_output);
} catch (IOException e) {
e.printStackTrace();
}
How do you know that it's only half of the response? If you rely on what is printed with System.out.println() then you should be aware that Logcat has a limitation that prevents it from printing more than 4,000 characters. Anything after that is truncated. To check how much of the response you have, you could print everything.length()first, ot see if you are in that situation.
You can look at this existing question on SO for reference, but there are many others.
Related
I'm writing a little Java project for fun where I want to get statistics for whatsapp chats. In this case i want to get the emojis that are used most frequently as one of those statistics.
These chats look like this and are a regular txt file:
29-04-2021 18:49 - Friend_A: I’m also up for the party🥳🥳🥳
29-04-2021 18:50 - Friend_B: I am also down
🥳 29-04-2021 18:52 - Friend_C: Im also down to party
29-04-2021 18:52 - Friend_A:
Hahahahahaha 29-04-2021 18:52 - Friend_A: Okay I’ll do it 😂😂
29-04-2021 18:52 - Friend_D: I'll see how it goes ♡♡♡ 29-04-2021
18:52 - Friend_E: Now I feel bad 😅
I use this code to parse the text file
try(BufferedReader reader = Files.newBufferedReader(filePath)) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
However, when i use this code all the emoji's get replaced by either a single question mark ('?') or two question marks ('??'). I've done this before in python and had no issues.
Ive tried to set the encoding of the printstream to UTF-8 like this
PrintStream out = new PrintStream(System.out, true, StandardCharsets.UTF_8);
using an InputStreamReader like below has the same results.
try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(String.valueOf(filePath)), StandardCharsets.UTF_8))){
String line;
while ((line = reader.readLine()) != null){
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
I feel like i'm missing something really simple here but i can't figure it out.
I need to download a JSON in a string, i'm almost sure the code isn't wrong, but there's something strange...
public boolean downloadJSON(){
json="";
try{
URL url = new URL(theURL);
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String line;
while ((line = in.readLine()) != null) {
json+=line;
}
in.close();
return true;
} catch (Exception e) {
return false;
}
}
Basically it open the buffer correctly, it read the json correctly and store it in the variable, it close the stream, then it go to the return true and... It randomly jump to the return false without sense, and while it's on the return false the Exception e is... null O.o
That make absolutely no sense, help me please D:!!!
In the end i solved it in this way:
public boolean downloadJSON(){
json="";
boolean out=false;
try{
URL url = new URL(theURL);
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String line;
while ((line = in.readLine()) != null) {
json+=line;
}
in.close();
out = true;
} catch (Exception e) {
}
return out;
}
Don't ask me how this is supposed to be correct if the first doesen't work, in my mind i still think the first should work :S
ADD: for Stephen C:
public boolean downloadJSON(){
json="";
try{
URL url = new URL("http://fapfapfap.altervista.org/conapo/conapo.php?n="+numeroPagina);
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String line;
while ((line = in.readLine()) != null){json+=line;}
in.close();
return true;
}catch (Exception e) {
Log.d("ERRORE", e.getStackTrace().toString());
return false;
}
}
Try this:
URL url = new URL(theURL);
StringBuilder jsonResults = new StringBuilder();
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
InputStreamReader in = new InputStreamReader(conn.getInputStream());
// Load the results into a StringBuilder
int read;
char[] buff = new char[1024];
while ((read = in.read(buff)) != -1) {
jsonResults.append(buff, 0, read);
}
System.out.println(jsonResults.toString());
.... it still make no sense that my code jumped to the false without exception
You are misinterpreting the evidence:
public boolean downloadJSON(){
json = "";
try {
URL url = new URL(theURL);
BufferedReader in = new BufferedReader(
new InputStreamReader(url.openStream()));
String line;
while ((line = in.readLine()) != null) {
json += line;
}
in.close();
return true;
} catch (Exception e) {
return false; // HERE
}
}
When you get to the statement I've labelled // HERE. It has happened >>because<< some exception has been thrown. There is absolutely no doubt about it. We don't know what exception it was, because your code simply throws away the exception object.
(Try adding e.printStacktace(); before the return false;)
I suspect it is either going to be a MalformedURLException, on a FileNotFoundException ... but it could be other things.
So what are your mistakes in this code?
1) Catching Exception is bad idea. The problem is that it catches too much. In addition to catching the exceptions that you (might have) expected at this point, it will catch all of the unexpected ones as well. For example, any NPEs or AIOOPEs or whatever arising from (hypothetical) bugs in your code.
In this case, you should probably catch the exceptions that are likely at this point; i.e. IOException.
2) Catching an exception and throwing away the stacktrace makes it hard to diagnose a problem. It is only advisable to "squash" an exception like that if you know (and can prove) that the exception is going to be what you expect.
3) Doing both 1) and 2) in the same piece of code is a REALLY bad idea.
4) Building a string like that is inefficient (or very inefficient ... if you are loading a really large document). Using a StringBuilder is much better.
Note however the 4) is peripheral to the problem you were having.
I have a problem. I am using a file to load some strings to use them in my App.
I have this function:
public void lecturaFichero(){
String linea = null;
try {
InputStream in = cntx.getAssets().open("cc.txt");
if (in != null) {
InputStreamReader input = new InputStreamReader(in,Charset.forName("iso-8859-1"));
BufferedReader buffreader = new BufferedReader(input);
while ((linea = buffreader.readLine()) != null) {
rellenaCodigo(linea);
}
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
The problem is that when I run the app it crashes right away (reading the file is the first thing I do).
If I do this instead of the above:
InputStreamReader input = new InputStreamReader(in)); //Without specifying the charset
It does work, it does not crash but the app shows where that special characters should be.
I need to solve this, I'd appreciate a solution in which I can read special characters in my app.
Thanks in advance.
PS: Android can print special characters because when I type a String by hand and print it on the screen it shows the character, the problem is when it comes to reading from the .txt.
I know this question might sound really basic for most of you. I need to download a large file from server. The first line of this file contains a time tag. I want to download entire file only if my time tag mismatches to that of file. For this I'm using the given code. However, I'm not sure if this actually prevents file from uselessly downloading entire file.
Please help me out !
public String downloadString(String url,String myTime)
{
try {
URL url1 = new URL(url);
URLConnection tc = url1.openConnection();
tc.setConnectTimeout(timeout);
tc.setReadTimeout(timeout);
BufferedReader br = new BufferedReader(new InputStreamReader(tc.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
if(line.contains(myTime))
{
Log.d("TIME CHECK", "Article already updated");
break;
}
sb.append(line+"\n");
}
br.close();
return sb.toString();
}
catch(Exception e)
{
Log.d("Error","In JSON downloading");
}
return null;
}
No, there is no easy way to control exactly to the last byte what will be downloaded. Even at the Java level you are involving a BufferedReader, which will obviously download more than you ask for, buffering it. There are other buffers as well, including at the OS level, which you cannot control. The proper technique to download only new files with HTTP is to use the IfModifiedSince header.
Your code won't download the whole file but as the BufferedReader has a default buffer size of 8192 you will read at least that many characters.
You can go byte-by-byte or chunk-by-chunk if it is the size
BufferedInputStream in = new BufferedInputStream(url).openStream())
byte data[] = new byte[1024];
int count;
while((count = in.read(data,0,1024)) != -1)
{
out.write(data, 0, count);
}
Check this question please
How to download and save a file from Internet using Java?
This is my code to download and read the text in my file in Dropbox. Version is a URL.
BufferedReader in = new BufferedReader(new InputStreamReader(version.openStream()));
String inputLine;
int line = 0;
try{
while ((inputLine = in.readLine()) != null){
strings[line] = new String(inputLine);
line++;
}
} catch (Exception e){
e.printStackTrace();
}
Although, I get this really annoying error.
java.lang.ArrayIndexOutOfBoundsException: 1
at sky.the.venture.client.Download.getCredits(Download.java:38)
at sky.the.venture.client.LauncherFrame.credits(LauncherFrame.java:315)
at sky.the.venture.client.LauncherFrame.(LauncherFrame.java:49)
at sky.the.venture.Destiny.(Destiny.java:13)
at Start.main(Start.java:11)
So, the part which is an error is Download.java:38. Which is
strings[line] = new String(inputLine);
So if anyone can help, I will be really happy =D
Well presumably you only created an array like this:
String[] strings = new String[1];
Arrays don't resize themselves in Java - indeed, they can't be resized. If you want a dynamically sized collection, use a List<E> implementation e.g. ArrayList<E>:
List<String> lines = new ArrayList<String>();
while ((inputLine = in.readLine()) != null) {
lines.add(inputLine);
}
It appears that you are attempting to write to an element of the strings array that hasn't been allocated. For example, if you have allocated something like strings[10], and lines is incremented to 11, you will receive the ArrayIndexOutOfBoundsException exception.