Getting incomplete messages when trying to read from Arduino with eclipse? - java

I'm having some issues with arduino. In class, we are learning arduino/java communication. Thus, we are asked to interpret bytes sent from the arduino and write it out in the console of eclipse as whatever type the "key" of the message tells us to write it in.
As of now, I'm just testing input streams, but I can't seem to get a complete message ever. This is what I'm doing:
public void run() throws SerialPortException {
while (true) {
if (port.available()) { //code written in another class, referenced below
byte byteArray[] = port.readByte(); //also code written in another class, referenced below
char magicNum = (char) byteArray[0];
String outputString = null;
for (int i = 0; i < byteArray.length; ++i) {
char nextChar = (char) byteArray[i];
outputString += Character.toString(nextChar);
}
System.out.println(outputString);
}
}
}
below is the code from the other class that is used in the above code
public boolean available() throws SerialPortException {
if (port.getInputBufferBytesCount() == 0) {
return false;
}
return true;
}
public byte[] readByte() throws SerialPortException {
boolean debug= true;
byte bytesRead[] = port.readBytes();
if (debug) {
System.out.println("[0x" + String.format("%02x", bytesRead[0]) + "]");
}
return bytesRead;
}

It is not possible to know when data is going to be available, nor whether input data is going to be available all at once rather than in several chunks.
This is a quick and dirty fix:
public void run() throws SerialPortException {
String outputString = "";
while (true) {
if (port.available()) {
byte byteArray[] = port.readByte();
for (int i = 0; i < byteArray.length; ++i) {
char nextChar = (char) byteArray[i];
if (nextChar == '\n') {
System.out.println(outputString);
outputString = "";
}
outputString += Character.toString(nextChar);
}
}
}
}
The declaration of outputString is moved out, and it is assigned "" so to get rid of that ugly null on standard output.
Each time \n is encountered in the serial input data, the content of outputString is printed on standard output first and cleared afterwards.

Related

How to find total number of tabs and single space characters from a file in java?

I have been trying to find the total number of tabs and single space characters with using the code below. So if i use this
if (c[i] == '\t') {
++tabcount;
}
it gives tabCount = 0, also if i want to get number of single space characters using this
if (c[i] == ' ') {
++singlescpacecount;
}
it gives total number of white spaces in the whole file.
Code for tabCount is
public static void TabCount(String filename) throws IOException{
int tabcount = 0;
InputStream is = new BufferedInputStream(new FileInputStream(filename));
try {
byte[] c = new byte[1024];
int readChars = 0;
while ((readChars = is.read(c)) != -1) {
for (int i = 0; i < readChars; ++i) {
if (c[i] == '\t') {
++tabcount;
}
}
}
System.out.println("The total number of tabcounts are :" + tabcount);
} finally {
is.close();
}
}
Thanks in advance.
At least part of the issue must be that the OP's input file does not contain tabs as expected. As noted by #Andreas, the basic code structure does count tabs. However, I had suggested ensuring the file is not iterated multiple times for counting various characters. Here is one implementation on how to do that. It is not optimal, but suggestive.
/**
* A class to accumulate results
*/
static class Results
{
private int tabs = 0;
private int spaces = 0;
public void incTabCount()
{
++tabs;
}
public void incSpaceCount()
{
++spaces;
}
public int getTabCount()
{
return tabs;
}
public int getSpaceCount()
{
return spaces;
}
#Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("tabs: ");
sb.append(tabs);
sb.append("\nspaces: ");
sb.append(spaces);
return sb.toString();
}
}
/**
* Iterate the file once, checking for all desired characters,
* and store in the Results object
*/
public static Results countInFile(String filename) throws IOException
{
// create results
Results res = new Results();
InputStream is = new BufferedInputStream(new FileInputStream(filename));
try {
byte[] c = new byte[1024];
int readChars = 0;
while ((readChars = is.read(c)) != -1) {
for (int i = 0; i < readChars; ++i) {
// see if we have a tab
if (c[i] == '\t') {
res.incTabCount();
}
// see if we have a space
if (c[i] == ' ') {
res.incSpaceCount();
}
}
}
} finally {
is.close();
}
return res;
}
public static void main(String[] args)
{
Results res;
try {
res = countInFile("f:/tmp/test.txt");
System.out.println(res);
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Input file (the tab is after the word "has" in the first line):
This line has\ta tab.
And there are 7 spaces?
Based upon an input file, the results are as expected:
tabs: 1
spaces: 7
Edit: as an aside, there is a modification that would be ultimately more testable. If one were to separate the File handling from the counting in an input stream, then one could more easily feed a known input to the system. For example, modifying the above slightly:
/**
* Counts in a stream the number of tabs and spaces, and returns
* the Results
*/
private static Results countInStream(InputStream is) throws IOException
{
// create results
Results res = new Results();
try {
byte[] c = new byte[1024];
int readChars = 0;
while ((readChars = is.read(c)) != -1) {
for (int i = 0; i < readChars; ++i) {
// see if we have a tab
if (c[i] == '\t') {
res.incTabCount();
}
// see if we have a space
if (c[i] == ' ') {
res.incSpaceCount();
}
}
}
}
finally {
}
return res;
}
This method may have a String passed to it:
String s = "This\thas\ttabs.\nAs well as spaces";
InputStream is = new ByteArrayInputStream(s.getBytes("UTF8"));
res = countInStream(is);
System.out.println(res);
Since it is now much easier to test the main logic, one can clearly see the base counting operates as expected. The countInFile method suggest above may be modified to open the InputStream from the file, and then call the countInStream(). Such an approach would reduce the debate about whether the logic of the method is at issue, or the contents sent to the method.

Null Cipher -- Java

I'm trying to code the null cipher for a school assignment, and I have no idea what i'm doing wrong.
The cipher is supposed to obtain the char from the number given in the pattern class. If it's a "-1", end the program and return output. If the pattern returns "0", skip the word and move on to the next pattern value. Any other integer and the program should get the char from the word in that place.
So in the example below, the pattern is {1, 0, 0, 1, 5, -1}
And the text is: "Hello, is it me you're looking for".
The output should be : "Hmr"
But i'm getting an out of bounds error, and when I tweak it, it's not printing the correct chars.
The code is below, please help me.
EDIT: I change it so that the runtimeError would disappear, but now i'm getting the incorrect output: "e'[space]"
ArrayList<Character> text;
ArrayList<Character> output;
int outputLen;
ArrayList<Integer> pattern;
public Preform()
{
text = new ArrayList<Character>();
output = new ArrayList<Character>();
pattern = new ArrayList<Integer>();
{
pattern.add(1);
pattern.add(0);
pattern.add(0);
pattern.add(1);
pattern.add(5);
pattern.add(-1);
}
}
public void updateLength()
{
outputLen = output.size();
}
public void stringToChar(String input)
{
for (int i = 0;i < input.length();i++)
{
String value = input.substring(i,i+1);
text.add(value.charAt(0));
}
}
public void printString ()
{
for (int i = 0; i < output.size();i++)
{
System.out.println(output.get(i) + ", ");
}
}
public ArrayList<Character> run()
{
int nullValue = 0;
int textVal = 0;
for (int i = 0; i < pattern.size(); i++)
{
nullValue = pattern.get(i);
if (nullValue == -1)
{
return output;
}
else if (nullValue == 0)
{
textVal = nextWord(textVal);
}
else
{
textVal += nullValue;
char temp = text.get(textVal);
output.add(temp);
textVal = nextWord(textVal);
}
}
return output;
}
public int nextWord (int starting)
{
// go to the next word
int addVal = 0;
do{
starting++;
} while(text.get(starting).equals(' '));
addVal += starting;
return addVal;
}
public static void main (String[] args)
{
Preform event = new Preform();
event.stringToChar("Hello, is it me you're "
+ "looking for");
event.run();
event.printString();
}
Thank you!
For your exception: in run you have to check for pattern.size() not test.size. always look at the line where you get the exception.
a similar issue is in run where you compare text size, but actually mean pattern
Apart from that your code is way to complicated, i.e. instead of nextWord you can simply use "my string".split(" "); and you get an array of string containing each word. There are a few other issues, but that's for you to figure out (its an assignment after all)
Edit: your main logic issue is with the way you use nextWord in run.
First you need to adapt nextowrd to actually do what you want (skip until the next space and then to the start of the next word):
public int nextWord (int starting)
{
// go to the next word
do{
starting++;
} while(!text.get(starting).equals(' '));
// skip the space
starting++;
return starting;
}
and your logic in run where you get the correct char needs to be adapted too:
else
{
char temp = text.get(textVal + nullValue - 1);
output.add(temp);
textVal = nextWord(textVal);
}

ByteBuffer returns null characters (character 0)

I'm trying to implement a simple client-server application, using NIO.
As an exercise, communication should be text-based and line-oriented. But when the server reads the bytes sent by the client, it gets nothing, or rather, the buffer is filled with a bunch of zeroes.
I'm using a selector, and this is the code triggered, when the channel is readable.
private void handleRead() throws IOException {
System.out.println("Handler Read");
while (lineIndex < 0) {
buffer.clear();
switch (channel.read(buffer)) {
case -1:
// Close the connection.
return;
case 0:
System.out.println("Nothing to read.");
return;
default:
System.out.println("Converting to String...");
buffer.flip();
bufferToString();
break;
}
}
// Do something with the line read.
}
In this snippet, lineIndex is an int holding the index at which the first \n occurred, when reading. It is initialized with -1, meaning there's no \n present.
The variable buffer references a ByteBuffer, and channel represents a SocketChannel.
To keep it simple, without Charsets and whatnot, this is how bufferToString is coded:
private void bufferToString() {
char c;
System.out.println("-- Buffer to String --");
for (int i = builder.length(); buffer.remaining() > 1; ++i) {
c = buffer.getChar();
builder.append(c);
System.out.println("Appending: " + c + "(" + (int) c + ")");
if (c == '\n' && lineIndex < 0) {
System.out.println("Found a new-line character!");
lineIndex = i;
}
}
}
The variable builder holds a reference to a StringBuilder.
I expected getChar to do a reasonable convertion, but all I get in my output is a bunch (corresponding to half of the buffer capacity) of
Appending: (0)
Terminated by a
Nothing to read.
Any clues of what may be the cause? I have similar code in the client which is also unable to properly read anything from the server.
If it is of any help, here is a sample of what the writing code looks like:
private void handleWrite() throws IOException {
buffer.clear();
String msg = "Some message\n";
for (int i = 0; i < msg.length(); ++i) {
buffer.putChar(msg.charAt(i));
}
channel.write(buffer);
}
I've also confirmed that the result from channel.write is greater than zero, reassuring that the bytes are indeed written and sent.
Turns out, this was a buffer indexing problem. In the server, a flip() was missing before writing to the socket. In the client code, a few flip() were missing too, after reading and before writing. Now everything works as expected.
Current writing code (server side):
private void handleWrite() throws IOException {
String s = extractLine();
for (int i = 0, len = s.length(); i < len;) {
buffer.clear();
while (buffer.remaining() > 1 && i < len) {
buffer.putChar(s.charAt(i));
++i;
}
buffer.flip();
channel.write(buffer);
}
// some other operations...
}

Java - Search String For Byte Code

I have tried many searches to find a way to search a string for byte code. Here is an example:
String stringThatHasBytes = "hello world hello world[B#9304b1";
If stringThatHasBytes . Does have bytes {
return true or false
}
Is there a method that can search a String for bytes?
You can't do this, in short. Because the printing of a byte changes everytime you print it out. Printing out the bytes doesn't print the actual bytes and it's meaningless if you're looking for exact comparison of bytes.
However, if you only look for any byte printing in the string, just control for [B#s in the string and return true.
String stringThatHasBytes = "hello world hello world[B#9304b1";
if (stringThatHasBytes.indexOf("[B#") >= 0)
return true;
} else return false;
EDIT:
If you need ways of printing bytes in a meaningful way, you should convert the bytes to some meaningful text such as:
public static String convertByteArrayToHexString(byte[] b) {
if (b != null) {
StringBuilder s = new StringBuilder(2 * b.length);
for (int i = 0; i < b.length; ++i) {
final String t = Integer.toHexString(b[i]);
final int l = t.length();
if (l > 2) {
s.append(t.substring(l - 2));
} else {
if (l == 1) {
s.append("0");
}
s.append(t);
}
}
return s.toString();
} else {
return "";
}
}
Would contains be too simple of an answer for you?
boolean hasBytes = str.contains("[B#");
If so let me know I'll show you some good regex! but that should be sufficient.
see if this help
byte[] myByteArray = new byte[5];
myByteArray[0] = 'a';
myByteArray[1] = 'b';
myByteArray[2] = 'c';
myByteArray[3] = 'd';
myByteArray[4] = 'e';
for (byte x : myByteArray)
System.out.println(x);
String myString = "abcde";
System.out.println(myString.equals(new String(myByteArray)));

Reading part of file with BufferedReader

I'm trying to write a function that grabs a certain part of a file, sends that to another function, then continue to do the same thing from where the BufferedReader left off until the end of the file but can't seem to figure out how to make it work.
Here is what I have:
String str = "";
int count = 0;
try {
while(//condition so it loops through the entire file. I've tried fileReader.ready() and fileReader.read != -1 but both just run into infinite loops){
while ((count < 4)){
str += fileReader.read();
count++;
fileReader.mark(1000);
}
fileReader.reset();
DoSomething(str) // send str to another function and do something with it;
}
} catch (IOException e) {
// TODO Auto-generated catch block
}
Can someone help me with this and explain what I'm doing wrong? Much would be appreciated
If you know the number of characters, use the BufferedReader's .skip(long) method, which tells it to skip the first long characters (where long is a 64-bit whole number).
The call to skip will return a long with the number of characters actually skipped.
The mark() method marks position in the file and you can specify how many bytes you want to read before calling reset(), which would reposition stream to the marked point. So, normally you need to call mark() at the beginning of your data and then call reset before next iteration.
while (count < 4){
if(count>0) {
fileReader.reset();
}
fileReader.mark(1000);
str += fileReader.read();
count++;
}
The following works for me. Edited after comment.
import java.io.*;
public class Test {
public static void main(String[] args) {
String str = "";
int count = 0;
try {
Reader fileReader = new BufferedReader(new FileReader("testfile"));
fileReader.mark(5);
while(fileReader.ready()){
count = 0;
str ="";
fileReader.reset();
while (count < 4 && fileReader.ready()){
if (count == 1){
fileReader.mark(5);
}
str += (char)fileReader.read() ;
count++;
}
System.out.println(str); // send str to another function and do something with it;
}
} catch (IOException e) {
// TODO Auto-generated catch block
}
}
}
Note that you need to cast fileReader.read(); to a char or you'll get wrong output, you have to reset the count otherwise count<4 won't be true ever after the first run (and since you don't do fileReader.read(), you'll get in an infitite loop), and you have to test for ready on each read (or you might block)
EDIT: Obviously, this is an example. You should never do the straight str += something in a loop, but use a StringBuffer, and catch and handle the possible exception.
Note on the second edit: if this is an intensive procedure, this is doing it wrong. I'll see if I can do it right (without backtracking)
YET ANOTHER EDIT:
import java.io.*;
public class Test {
public static void main(String[] args) {
StringBuffer buffer = new StringBuffer();
int length = 4;
try {
Reader fileReader = new BufferedReader(new FileReader("teststring"));
for (int i = 0; i < length && fileReader.ready(); i++) {
buffer.append((char) fileReader.read());
}
while (fileReader.ready()) {
System.out.println(buffer); // send str to another function and do
// something with it;
buffer.deleteCharAt(0);
buffer.append((char) fileReader.read());
}
System.out.println(buffer); // send str to another function and do
// something with it;
}
catch (IOException e) {
// TODO Auto-generated catch block
}
}
}
The repeated call to the method that does something still isn't pretty, but this is a lot closer.
I think you just need to reset count = 0 after DoSomething(Str). Right now you're never resetting your count variable and it's preventing you from entering the file read loop.
Why mark and reset at all? Just read 4 bytes, process them, and repeat until EOF.
Based on Martijns answer I made the code a little simpler.
package so4168937;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
public class SecondTry {
static void consume(Reader rd, int length) throws IOException {
StringBuilder sb = new StringBuilder();
int c;
for (int i = 0; i < length - 1; i++) {
if ((c = rd.read()) == -1)
return;
sb.append((char) c);
}
while ((c = rd.read()) != -1) {
sb.append((char) c);
System.out.println("<" + sb + ">");
sb.deleteCharAt(0);
}
}
public static void main(String[] args) throws IOException {
consume(new StringReader("hi my name is joe"), 4);
}
}
You don't need to use mark or reset, and using ready only adds complexity and unwanted behavior.
i see that most of you prefer to use the FileReader, as the question asked for, but i just prefer to use the Scanner instead because i find it easier to use.
so here is my example:
import java.util.Scanner;
import java.io.File;
private void fileReader(){
String str;
try {
input = new Scanner(new File("FILENAME"));
} catch (Exception e) {
System.out.println("Scanner load failed.");
}
while(input.hasNext()){
str+=input.next()+" ";
}
input.close();
int j=0;
for(int i=3;i<str.length();i++){
DoSomething(str.substring(j,i));
j++;
}
}
this reads each line and adds it to the string, and then it sends the string in bites of 4 to the DoSomething method.
i hope it helps.
Edit1:
removed this edit.
Edit2:
did just read that you wanted in the comments.. and that can be done easily with any code actually i will change my code at the top to reflect this change.
hmm .. yeah.. that should work .. :)
My idea is to define a CharConsumer that defines what it means to consume a bunch of characters. Then I wrote a method that takes an arbitrary Reader and reads it until the end. If you want another terminating condition, replace the while (true) with it.
If you need the input to the consume method to be buffered, be sure that you create exactly one BufferedReader and don't use the other reader anymore after that. Otherwise some characters may get lost while reading.
package so4168937;
import java.io.EOFException;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
public class Main {
// unused, since the question was initially unclear
public static void consumeFourInARow(Reader rd, CharConsumer consumer) throws IOException {
char[] chars = new char[4];
while (true) {
for (int i = 0; i < chars.length; i++) {
int c = rd.read();
if (c == -1) {
if (i == 0)
return;
throw new EOFException("Incomplete read after " + i + " characters.");
}
chars[i] = (char) c;
}
consumer.consume(chars);
}
}
public static void consume(Reader rd, CharConsumer consumer) throws IOException {
char[] chars = new char[4];
int c;
for (int i = 0; i < chars.length; i++) {
if ((c = rd.read()) == -1) {
return;
}
chars[i] = (char) c;
}
consumer.consume(chars);
while ((c = rd.read()) != -1) {
System.arraycopy(chars, 1, chars, 0, chars.length - 1);
chars[chars.length - 1] = (char) c;
consumer.consume(chars);
}
}
interface CharConsumer {
void consume(char[] chars);
}
public static void main(String[] args) throws IOException {
final StringBuilder sb = new StringBuilder();
consume(new StringReader("hi my name is joe..."), new CharConsumer() {
#Override
public void consume(char[] chars) {
sb.append('<');
sb.append(chars);
sb.append('>');
}
});
System.out.println(sb.toString());
}
}
Update [2010-11-15]: Replaced the old code with code that implements a simple cyclic buffer, which is apparently what was wanted in the original question.

Categories

Resources