简体   繁体   English

在java中读取到文件末尾

[英]Read to the end of file in java

I do read serial interface file in Linux via Java.我确实通过 Java 在 Linux 中读取串行接口文件。 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.我只是不知道如何丢弃现有数据并只读取新数据。

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 :在 Linux 上,在 C 程序中, 您可以执行以下操作

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.但是您将无法直接从 Java 执行此操作 - 它不是独立于平台的功能。

You could write a small C program that performs this operation and then pipes the data from /dev/ttyO1 to stdout.您可以编写一个小的 C 程序来执行此操作,然后将数据从/dev/ttyO1到 stdout。 You can start that program from your Java code using ProcessBuilder and read its data instead of reading the serial port directly.您可以使用ProcessBuilder从 Java 代码启动该程序并读取其数据,而不是直接读取串行端口。


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.再想一想,你不需要C程序来做任何管道,你只需要调用一次,然后你就可以从Java打开/dev/tty01

Here's a small C program that will do this:这是一个可以执行此操作的小型 C 程序:

#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 .使用gcc -o tcflush tcflush.c编译并使用tcflush /dev/tty01

I don't know exactly what a 'serial interface file in Linux' is.我不确切知道“Linux 中的串行接口文件”是什么。 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.您可以使用RandomAccessFile类的seek(long)方法来跳过数据。 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.我最多只能读取 50 个字节,但您想要读取的内容远不止这些。 Maybe you could use a timeout.也许你可以使用超时。

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 ?您是否考虑过使用RXTXjSSC You can find an example in the Arduino IDE source code: SerialMonitor and Serial .您可以在 Arduino IDE 源代码中找到一个示例: SerialMonitorSerial

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..我想你想要一些像 linux 中的 tail 命令这样的功能..如果是这样,下面的代码很有帮助..请运行它并检查它..

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();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM