2

I do read serial interface file in Linux via Java. Sometimes I just need to discard all data and read only what is new.

Explanation: There is loads of data and new is coming so I do have to discard existing buffer and start to wait for new data. External board just keeps sending. And I end up reading old data, just in few iterations I have current value. I need just skip to end and wait for new data set only instead reading all old crap.

String file = "/dev/ttyO1";
FileInputStream inputStream  = new FileInputStream(file);

private static byte[] readUntil(InputStream in, int timeout) throws IOException {
//        long lastTime = System.currentTimeMillis();
    while (true) {
        if (in.available() > 0) {
            if (in.read() == 83)
                break;
        }
        try { Thread.sleep(20); } catch (Exception e) {}
    }
    byte[] text = new byte[10];
    for (int i = 0; i < 10; i++) {
        text[i] = (byte) in.read();
        if (text[i]=="E".getBytes()[0]) break;
        try { Thread.sleep(20); } catch (Exception e) {}
    }
    in.read(); // just read last one
    return text;
}

I just cannot figure out how to discard the existing data and read only new coming.

allprog
  • 16,540
  • 9
  • 56
  • 97
  • What exactly do you need help with? I don't understand. – Enrico Susatyo Apr 25 '14 at 09:01
  • what is the purpose of `Thread.sleep(20)`?? – Baby Apr 25 '14 at 09:02
  • Thread.sleep(20) - I was intended to save processor power... I might be wrong... –  Apr 25 '14 at 09:24
  • I don't understand the question. Just read all the data, as fast as possible. When data isn't available, the read will block. The available/sleep loop is therefore pointless. I don't understand what your problem is. – user207421 Apr 26 '14 at 02:07

4 Answers4

2

I assume that what you really want is to flush all data in the incoming buffers of the serial port.

On Linux, in a C program, you would be able to do:

tcflush(fd, TCIFLUSH)

To flush the incoming buffer. But you won't be able to do this directly from Java - it's not a platform-independent functionality.

You could write a small C program that performs this operation and then pipes the data from /dev/ttyO1 to stdout. You can start that program from your Java code using ProcessBuilder and read its data instead of reading the serial port directly.


Thinking about it a bit more, you don't need the C program to do any piping, you just need to invoke it once and after that you can open /dev/tty01 from Java.

Here's a small C program that will do this:

#include <sys/types.h> 
#include <sys/stat.h> 
#include <termios.h>
#include <fcntl.h> 
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char** argv) {
    int i;
    for (i = 1; i < argc; i++) {
        int fd = open(argv[i], O_NOCTTY, O_RDONLY);
        if (fd >= 0) {
            int result = tcflush(fd, TCIFLUSH);
            close(fd);
            if (result == -1) {
                fprintf(stderr, "%s: Couldn't open file %s; %s\n",
                        argv[0], argv[i], strerror(errno));
                exit (EXIT_FAILURE);
            }
        } else {
            fprintf(stderr, "%s: Couldn't open file %s; %s\n",
                    argv[0], argv[i], strerror(errno));
            exit (EXIT_FAILURE);
        }
    }
}

Compile with gcc -o tcflush tcflush.c and run with tcflush /dev/tty01.

Community
  • 1
  • 1
Erwin Bolwidt
  • 30,799
  • 15
  • 56
  • 79
  • I think it's possible not just with external program, but with JNI, it's still will be platform dependent, but without extra process. – Alexander Kudrevatykh Apr 26 '14 at 06:22
  • @AlexanderKudrevatykh true. If performance is of high importance, the OP should look to JNI. But better check first using an external program if this does what he requires (there may be timing issues between flushing the buffer and reading the data for example) – Erwin Bolwidt Apr 26 '14 at 06:24
1

I don't know exactly what a 'serial interface file in Linux' is. But I assume it is a simple file which has some text appended all the time and you want to wait for the new stuff appended and not read the whole file from scratch. You could use the RandomAccessFile class' seek(long) method to skip data. Or you could just sleep for some time when you reached the end of file.

public static void main(String[] args) throws Exception {
    FileInputStream fis = new FileInputStream("src/file.txt");
    int i = 0;
    while (i < 50) { // read only 50 bytes
        byte b = (byte)fis.read();

        if (b == -1) { // end of file, wait
            Thread.sleep(500L);
            continue;
        }
        System.out.print((char) b);
        i++;
    }
    fis.close();
}

This is just a simple example. I read only up to 50 bytes, but you want to read much more than that. Maybe you could use a timeout.

TomasZ.
  • 449
  • 1
  • 5
  • 10
0

External board just keeps sending.

This looks more like a target for an event-driven approach than the usual sequential-read.

Have you considered using RXTX or the jSSC? You can find an example in the Arduino IDE source code: SerialMonitor and Serial.

Cebence
  • 2,406
  • 2
  • 19
  • 20
-1

Your aim is very unclear from the code. I presume you want some functionality like tail command in linux..if so, Below code is helpful..please run it and check it out..

import java.io.*;

public class FileCheck {

    static long sleepTime = 1000 * 1;
    static String file_path = "/dev/ttyO1";

    public static void main(String[] args) throws IOException {
            BufferedReader input = new BufferedReader(new FileReader(file_path));
            String currentLine = null;
            while (true) {
                if ((currentLine = input.readLine()) != null) {
                    System.out.println(currentLine);
                    continue;
                }
                try {
                    Thread.sleep(sleepTime);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
            input.close();
    }
}
niiraj874u
  • 2,180
  • 1
  • 12
  • 19
  • It reads file and when you add contains, It displays new constants on console. Now, what do you want to achieve ? – niiraj874u Apr 25 '14 at 10:06
  • The readLine() method returns null at end of stream. At this point, the peer has closed the connection, so there will never be any more data. It is therefore pointless to sleep and try the readLine() again. -1 – user207421 Apr 26 '14 at 02:08
  • Dear, Pls run the program to have importance of sleep..it will chk file for data after an internal.. – niiraj874u Apr 26 '14 at 08:44
  • Can you tell me what problem could be occurred with above code. Just for my information. – niiraj874u Apr 28 '14 at 10:25
  • The importance of the sleep is zero, whether 'dear' or otherwise. – user207421 May 10 '17 at 10:45