Question

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.

Was it helpful?

Solution 2

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.

OTHER TIPS

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.

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.

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();
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top