BufferedReader adds endlessly on readLine() - java

I'm trying to send test messages from Arduino via bluetooth by spamming "hello world!" every 100 ms.
Now, on android I've got an endless addition of "hello world!" to my StringBuilder and each debug iteration I have "hello world!\nhello world!\nhello world!\n..." etc.
What should I do?
As an idea I will spam a lot of Jsons from arduino to Android device. Do I have to make some special char sequences for dividers to break the while after each message from arduino? Or is there a simpler decision?
public static String toString(InputStream inputStream) throws IOException {
byte[] bs = new byte[inputStream.available()];
if (Utils.isZero(bs.length)) {
return "";
}
BufferedReader r = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder total = new StringBuilder();
String line;
while (r.ready()) {
line = r.readLine();
total.append(line).append('\n');
}
return total.toString();
}

You aren't checking for end of stream.
The correct way to write that read loop is:
while ((line = br.readLine()) != null)
{
total.append(line).append('\n');
}
But if the data is endless it doesn't make sense to even have a loop. Just return br.readLine(). It doesn't even make sense to have this method.
NB You don't need to allocate a byte array just to determine its length.

Related

How can I read lines from a inputted file and then store the most recently read lines in an array?

I am trying to create a program that takes an inputted text file and reads the lines one by one. It then needs to store the most recently read lines (the number of lines depends on the parameter lines) in an array and then I need to print the lines using PrintWriter.
I started the first part but I'm not sure if I have the right idea. If anyone can help me on the second part as well that would be very appreciated!
public void RecentLines(Reader in, Writer out, int lines) throws IOException {
BufferedReader r3ader = new BufferedReader(in);
String str;
while((str = r3ader.readLine()) != null){
String[] arr = str.split(" ");
for( int i =0; i < lines; i++){
arr[i] = r3ader.readLine();
}
}
EDIT
the full question is this:
Create a program which reads lines from IN, one line at the time until the end. Your method must maintain an internal buffer that stores the most recently read lines (this might be best done using an array). Once the method reaches the end of the file, it should print the lines stored in the internal buffer into out, probably best done by creating a PrintWriter to decorate this Writer. (Except for your debugging purposes during the development stage, this method should not print anything to System.out.)
Try this one:
public void RecentLines(Reader in, Writer out, int lines) throws IOException {
BufferedReader r3ader = new BufferedReader(in);
String str;
int i=0;
String[] lineArray = new String[lines];
while((str = r3ader.readLine()) != null){
lines[i%lines] = str;
i++;
if(!r3ader.hasNextLine()){
break;
}
}
sounds like a task for data structures. Queue seems to be the best fit for a given task.
public void RecentLines(Reader in, Writer out, int lines) throws IOException {
BufferedReader r3ader = new BufferedReader(in);
BufferedWriter wout = new BufferedWriter(out);
String str;
Queue<String> content = new LinkedList<String>();
int i = 0;
while ((str = r3ader.readLine()) != null) {
if (i >= lines) {
content.remove();
}
content.add(str);
i++;
}
wout.write(String.valueOf(content));
}

String from server is shorter than it needs to be

for some reason, when I take a string from my server to my app and Log it, the string is shorter than it needs to be.
I thought that it is happening because of the length of the string, but the whole string is 113137 characters long (and the limit is 10^32 -1).
The length of the string that returns to me is something like 4000.
Code:
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(IS));
StringBuilder stringBuilder = new StringBuilder();
String line = "";
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line);
}
Log.d("Base64", stringBuilder.toString());
There is limit on log message length
#define LOGGER_ENTRY_MAX_LEN (4*1024)
#define LOGGER_ENTRY_MAX_PAYLOAD (LOGGER_ENTRY_MAX_LEN - sizeof(struct logger_entry))
Also look at following question to clarify things
Android - Set max length of logcat messages

BufferedReader keeps waiting for response

I have a server and client running on local server.
I read from the server this way:
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
public static String readResponse() throws IOException{
String response = "";
String line;
while((line = br.readLine()) != ""){
System.out.println("s: " + line);
}
return response;
}
And I get the response from server but the program stops and doesn't go anywhere from there:
Please enter option number: 1
c: MSGGET
s: 200 OK
s: Go for it now. The future is promised to no one.
And it just hangs here, when it is suppose to continue.
I also tried:
while((line = br.readLine()) != null){
It just keeps waiting. Is there anything maybe on the server that I have to change to tell the client that I am done transmitting data.
Please help! Thank you!
while((line = br.readLine()) != ""){
System.out.println("s: " + line);
}
return response;
}
Unless your peer is planning to transmit a blank line as an end-of-message sentinel, this loop is pointless, and it also compares Strings incorrectly.
And I get the response from server but the program stops and doesn't go anywhere from there.
It is waiting for an empty line that never arrives. And it is ignoring the end of stream condition.
while((line = br.readLine()) != null){
Now this loop is correct, but it won't exit until end of stream, which won't happen until the peer closes the connection.
It just keeps waiting.
That's what it's supposed to do.
Try this one :
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
public static String readResponse() throws IOException{
String response = "";
String line;
while((line = br.readLine()) != "" || (line = br.readLine()) != null)){
System.out.println("s: " + line);
}
return response;
}
if this is not working then you need to check if you are sending some special character on end of stream from server. Then apply check for that character.
I ended up using this:
while(!(line = br.readLine()).equals("exit")){
And I asked the person responsible for the server to print the following when he is done writing a response:
//this was initiated at the beginning of the program
out = new PrintWriter(socket.getOutputStream(), true);
out.println("exit");
This seems to works well for me so far!
Thank you everyone for your help!

Looping over InputStream truncating data

So this is a very simple problem with a simple solution that I'm just not seeing:
I'm trying to get a list of data through an InputStream, looping until I reach the end of the stream. On each iteration, I print the next line of text being passed through the InputStream. I have it working but for one small problem: I'm truncating the first character of each line.
Here's the code:
while (dataInputStream.read() >= 0) {
System.out.printf("%s\n", dataInputReader.readLine());
}
And the output:
classpath
project
est.txt
Now, I know what's going on here: the read() call in my while loop is taking the first char on each line, so when the line gets passed into the loop, that char is missing. The problem is, I can't figure out how to set up a loop to prevent that.
I think I just need a new set of eyes on this.
readLine for DataInputStream is deprecated. You may try wrapping it with a BufferedReader:
try
{
String line;
BufferedReader bufferedReader = new BufferedReader( new InputStreamReader( dataInputStream ) );
while( (line = bufferedReader.readLine()) != null )
{
System.out.printf("%s\n", line);
}
}
catch( IOException e )
{
System.err.println( "Error: " + e );
}
Also, I`m not sure, that it is a good idea to use available() due to this specification:
* <p>Note that this method provides such a weak guarantee that it is not very useful in
* practice.
Use one BufferedReader and InputStreamReader, here is one example:
InputStream in=...;
BufferedReader br = new BufferedReader(new InputStreamReader(in));
while (br.ready()) {
String line = br.readLine();
}
dataInputStream.read() reads the first character of the InputStream, the same as dataInputReader.readLine() reads the complete next line. Every read character or line is then gone. you can use the dataInputStream.available() to check if the InputStream has data available.
That should print the correct output:
while (dataInputStream.available()) {
System.out.printf("%s", dataInputReader.read());
}
String line;
while ((line = dataInputReader.readLine()) != null) {
System.out.println(line);
}

Reading a file into a CharBuffer, then a StringBuilder or StringBuffer seems to leave out on parts of the file. Why?

The following code seems to only write a small part of the File in the StringBuilder - why?
Reader rdr = new BufferedReader(new InputStreamReader(new FileInputStream(...)));
StringBuilder buf = new StringBuilder();
CharBuffer cbuff = CharBuffer.allocate(1024);
while(rdr.read(cbuff) != -1){
buf.append(cbuff);
cbuff.clear();
}
rdr.close();
Some more information: The file is bigger than the CharBuffer, also i can see from the debugger that the charbuffer is indeed filled as expected. The only part that makes its way to the StringBuilder seems to be from somewhere in the middle of the file. I am using openJDK7.
I wonder why it would show such a behavior and how this can be fixed.
As Peter Lawrey mentioned, you need to call cbuff.flip() between the read and write. It seems that the append will read from the position of the buffer, which is at the end if we don't call cbuff.flip(). The reason why a part from somewhere in the middle is still written is because in the end, the buffer won't be completely filled, thus some "old" bytes will still be between the position in the buffer and the end of the buffer.
Mystery solved :-)
All those classes have been part of the JDK since 1.0. I doubt that any of them needs to be fixed.
Your code is a long way for the usual idiom. Was this intended as a learning exercise, one that's gone awry? Or did you really want to put this into an application?
Here's how I would expect to see those classes used:
public static final String NEWLINE = System.getProperty("line.separator");
public String readContents(File f) throws IOException {
StringBuilder builder = new StringBuilder(1024);
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(f));
String line;
while ((line = br.readLine()) != null) {
builder.append(line).append(NEWLINE);
}
} finally {
closeQuietly(br);
}
return builder.toString();
}

Categories