用于读写java的线程

问题描述 投票:0回答:2

我正在从串口读取数据,平均间隔为1秒,同时将读取的数据写入文本区域和文本文件。问题是我有时无法获得正确的数据,也许是因为我在一个程序中执行所有三个过程。如何通过单独的线程写入文本区域和文本文件?

这是我的代码:

import java.io.BufferedWriter;
import java.io.File;

import java.io.FileWriter;

import java.io.IOException;
import java.io.InputStream;

import java.text.SimpleDateFormat;

import java.util.Date;
import java.util.Iterator;

import java.util.TooManyListenersException;
import java.util.TreeMap;

import javax.comm.CommPortIdentifier;
import javax.comm.SerialPort;
import javax.comm.SerialPortEvent;
import javax.comm.SerialPortEventListener;
import javax.comm.UnsupportedCommOperationException;
import javax.swing.JOptionPane;

import com.pressure.constants.Constants;

import com.pressure.online.OnlineStartWindow;

public class SerailReader implements SerialPortEventListener {

    // DECLARES INPUT STREAM TO READ SRIAL PORT
    private InputStream inputStream;
    // DECLARES PORT
    private CommPortIdentifier port;
    private SerialPort serialPort;

    // DATE TO CREATE FILE NAME
    private static final SimpleDateFormat SDF = new SimpleDateFormat("dd-MM-yy");

    
    private int index = 0;

    private File file;

    private OnlineStartWindow onlineStartwindow;

    private int[] tempIntArray = new int[233];
    private int newData = 0;

    private String outFolder;

    private String filename = "0";

    private FileWriter fileWriter;

    private BufferedWriter buffOut;
    private StringBuffer line;
    private String packetFilename;

    TreeMap<Integer, Float> channelMap = new TreeMap<Integer, Float>();
    
    ThreadPrintsAndWrites p;

    public FileWriter getFileWriter() {
        return fileWriter;
    }

    public void setFileWriter(FileWriter fileWriter) {
        this.fileWriter = fileWriter;
    }

    public BufferedWriter getBuffOut() {
        return buffOut;
    }

    public void setBuffOut(BufferedWriter buffOut) {
        this.buffOut = buffOut;
    }

    // SETTER GETTER TO OnlineStartwindow OBJECT
    public OnlineStartWindow getOnlineStartwindow() {
        return onlineStartwindow;
    }

    public void setOnlineStartwindow(OnlineStartWindow onlineStartwindow) {
        this.onlineStartwindow = onlineStartwindow;
    }

    // SETTER GETTER TO SERIALPORT
    public SerialPort getSerialPort() {
        return serialPort;
    }

    public void setSerialPort(SerialPort serialPort) {
        this.serialPort = serialPort;
    }

    // ********* connects to serial port ***********//
    public void SerialReadmethod(OnlineStartWindow onlineStartwindow,
            String outFolderPath) throws Exception {

        setOnlineStartwindow(onlineStartwindow);
        outFolder = outFolderPath;
        // SELECTS PORT NAME SELECTED

        port = CommPortIdentifier.getPortIdentifier(getOnlineStartwindow()
                .getComPort());
        System.out.println("port name " + port);

        // CHEAK WETHER SELECTED PORT AVAILABLE OR NOT
        if (port.getPortType() == CommPortIdentifier.PORT_SERIAL) {

            if (port.getName().equals(getOnlineStartwindow().getComPort())) {

                JOptionPane.showMessageDialog(null, "Successpully opened port",
                        "Online Dump", JOptionPane.INFORMATION_MESSAGE);

            }

        }

        // OPENS SERAIL PORT
        serialPort = (SerialPort) port.open("SimpleReadApp1111", 1000);

        // OPENS SERIAL PORT INPUT STREAM TO READ DATA
        try {
            inputStream = serialPort.getInputStream();

        } catch (IOException e) {
            System.out.println("IO Exception");
        }

        // ADDS LISTNER TO SERIALPORT
        try {
            serialPort.addEventListener(this);

        } catch (TooManyListenersException e) {
            System.out.println("Tooo many Listener exception");
        }

        // EVENT GENERATED WHEN DATA WILL BE AVAILABELE ON SERIALPORT
        // INPUTSTREAM
        serialPort.notifyOnDataAvailable(true);

        try {

            // SETS SELECTED BAUDRATE

            int BAUDRATE = Integer.parseInt((getOnlineStartwindow()
                    .getBaudRate()).trim());

            // SETS SELECTED DATA BITS

            int DATABITS = Integer.parseInt(getOnlineStartwindow()
                    .getDataBits().trim());
            if (DATABITS == 8) {
                DATABITS = SerialPort.DATABITS_8;
            } else if (DATABITS == 7) {
                DATABITS = SerialPort.DATABITS_7;
            } else if (DATABITS == 6) {
                DATABITS = SerialPort.DATABITS_6;
            } else if (DATABITS == 5) {
                DATABITS = SerialPort.DATABITS_5;
            }

            // SETS SELECTED STOPBITS
            int STOPBITS = 0;

            if (getOnlineStartwindow().getStopBits() == "1") {
                STOPBITS = SerialPort.STOPBITS_1;
            } else if (getOnlineStartwindow().getStopBits() == "1.5") {
                STOPBITS = SerialPort.STOPBITS_1_5;
            } else if (getOnlineStartwindow().getStopBits() == "2") {
                STOPBITS = SerialPort.STOPBITS_2;
            }

            // SETS SELECTED PARITY
            int PARITY = 0;
            if (getOnlineStartwindow().getParity() == "NONE") {
                PARITY = SerialPort.PARITY_NONE;
            } else if (getOnlineStartwindow().getParity() == "EVEN") {
                PARITY = SerialPort.PARITY_EVEN;
            } else if (getOnlineStartwindow().getParity() == "ODD") {
                PARITY = SerialPort.PARITY_ODD;
            }

            // SETS SELECTED FLOW CONTROL
            int FLOWCONTROL = 0;
            if (getOnlineStartwindow().getFlowControl() == "NONE") {
                FLOWCONTROL = SerialPort.FLOWCONTROL_NONE;
            } else if (getOnlineStartwindow().getFlowControl() == "XON/XOFF") {
                FLOWCONTROL = SerialPort.FLOWCONTROL_XONXOFF_IN;
            }

            serialPort
                    .setSerialPortParams(BAUDRATE, DATABITS, STOPBITS, PARITY);

            // no handshaking or other flow control
            serialPort.setFlowControlMode(FLOWCONTROL);
            

        } catch (UnsupportedCommOperationException e) {
            System.out.println("UnSupported comm operation");
        }

    }

    // *********this method will automaticaly calls when u get data on port and
    // arranges packet from start frame to end frame *************//
    public void serialEvent(SerialPortEvent event) {

//      switch (event.getEventType()) {
//
//      case SerialPortEvent.DATA_AVAILABLE:

        if(event.getEventType()==SerialPortEvent.DATA_AVAILABLE){

                //dataAvailabel = inputStream.available();
            
                // READING DATA CHARECTER BY CHARECTER

                while (newData != -1) {
                    try {
                        newData = inputStream.read();
                        if (newData == -1) {
                            break;
                        }
                        if (Constants.SF == (char) newData) {
                            index = 0;
                            // System.out.println("start frame");
                        }
                        tempIntArray[index] = newData;

                        if (Constants.EF == (char) newData) {
                            selectToDispalyAndWrite(tempIntArray);
                            // disp(tempIntArray);
                            
                        }
                        index++;

                    } catch (IOException ex) {
                        System.err.println(ex);
                        // return;
                    }
                }
                // ///////////////// completes
        }
            

        

    }

    // DISPLYS PACKET TO TEXT AREA AND CREATES .PSI FILE
    public void selectToDispalyAndWrite(int[] readBufferArray) {

        if (getOnlineStartwindow().getDump().isSelected()) {
            packetFilename = Integer.toString(readBufferArray[1])
                    + Integer.toString(readBufferArray[2])
                    + Integer.toString(readBufferArray[3]);

            
            try {
                if (getOnlineStartwindow().getFileTypeSelection() == "text") {

                    displayAndWriteToTextFile(readBufferArray);

                } else {
                    displayAndWriteToExcelFile(readBufferArray);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            printToTextArea(readBufferArray);
        }
    }

    public void printToTextArea(int[] readBufferArray) {
        int i = 0;
        int portname = 0;
        Float portval = 0.0f;

        
        int len = 0;
        i = 0;
    writeloop:   while (len != readBufferArray.length) {
            // while ((char) readBufferArray[i] != Constants.EF) {
            if ((char) readBufferArray[i] == Constants.SF) {

                // WRITES DASH LINE TO TEXT AREA
                getOnlineStartwindow()
                        .getTextArea()
                        .append(
                                "\r\n\r\n-----------------------------------------------------------------------\r\n");

                getOnlineStartwindow().getTextArea().append(
                        "Time :" + readBufferArray[i + 4] + " Min "
                                + readBufferArray[i + 5] + " Sec.");
                getOnlineStartwindow()
                        .getTextArea()
                        .append(
                                "\r\n-----------------------------------------------------------------------\r\n");
            


            }
            if ((char) readBufferArray[i] == Constants.EF) {
                for (Iterator<Integer> iterator = channelMap.keySet()
                        .iterator(); iterator.hasNext();) {

                    int key = iterator.next();
                    Float value = channelMap.get(key);

                    getOnlineStartwindow().getTextArea().append(
                            "Port_" + key + "           " + value + "\r\n");

                }
                channelMap.clear();
                break writeloop;
            }
            i++;
        }

    }

    public void displayAndWriteToTextFile(int[] readBufferArray)
            throws IOException {
        int i = 0;
        int portname = 0;
        Float portval = 0.0f;

        if (!(filename.equalsIgnoreCase(packetFilename))) {
            filename = packetFilename;
            if (buffOut != null && fileWriter != null) {
                drawLine('*');
                buffOut.close();
                fileWriter.close();

            }

            // GET CURRENT DATE
            Date date = new Date();
            file = new File(outFolder + "\\" + SDF.format(date) + "-"
                    + packetFilename + ".txt");

            if (!file.exists()) {
                fileWriter = new FileWriter(file, true);
                buffOut = new BufferedWriter(fileWriter);
                
                drawLine('*');
                
                drawLine('*');
            } else {
                fileWriter = new FileWriter(file, true);
                buffOut = new BufferedWriter(fileWriter);
            }

        }

        // LOOP TO DISPLY ALL PORT NAME AND PRESSURE VALUES
        int len = 0;
        i = 0;
        writeloop: while (len != readBufferArray.length) {
            // while ((char) readBufferArray[i] != Constants.EF) {
            if ((char) readBufferArray[i] == Constants.SF) {

                // WRITES DASH LINE TO TEXT AREA
                getOnlineStartwindow()
                        .getTextArea()
                        .append(
                                "\r\n\r\n-----------------------------------------------------------------------\r\n");

                getOnlineStartwindow().getTextArea().append(
                        "Time :" + readBufferArray[i + 4] + " Min "
                                + readBufferArray[i + 5] + " Sec.");
                getOnlineStartwindow()
                        .getTextArea()
                        .append(
                                "\r\n-----------------------------------------------------------------------\r\n");

                drawLine('-');
                buffOut.write("TIME: " + readBufferArray[i + 4] + " Min "
                        + readBufferArray[i + 5] + " Sec." + "\r\n\r\n");

            }
            if ((char) readBufferArray[i] == Constants.ST) {

                portname = readBufferArray[i + 1];
                portval = getFloatValue(i);
                channelMap.put(portname, portval);

            }
            if ((char) readBufferArray[i] == Constants.EF) {
                for (Iterator<Integer> iterator = channelMap.keySet()
                        .iterator(); iterator.hasNext();) {

                    int key = iterator.next();
                    Float value = channelMap.get(key);

                    getOnlineStartwindow().getTextArea().append(
                            "Port_" + key + "           " + value + "\r\n");

                    

                }
                channelMap.clear();
                break writeloop;
            }
            i++;
        }

    }
}
java multithreading serial-port
2个回答
1
投票

这是从设计角度来看的一种方法。

  1. 为数据创建一个类类型。这将是一个容器(继承适当的队列)。在此类内部,当您设置和获取数据时,请确保锁定。
  2. 在main中创建一个新线程来启动串口并读取消息。向线程传递一个对象(您的列表类对象)。串口会将数据放入该列表中。这将被设置在对象中。
  3. 主线程(窗口)将有一个计时器,用于触发并从队列中读取数据。您可能需要玩弄计时器。您不希望它过于频繁地触发并占用主窗口中的所有处理时间。但是,如果速度太慢,您可能无法更新足够的消息,也无法在消息可用时将消息从队列中取出。该计时器应该将所有数据从队列中取出并显示出来。

队列和锁是这里的重要部分。队列将保持消息的顺序。该锁将确保您在读取数据时不会尝试将新数据写入队列。


0
投票

我的印象是Java不支持Windows的串行端口,它只支持Solaris或Linux。 你的类应该实现 Runnable 接口。并创建一个在其 run 方法中从串行端口读取数据的线程。 主线程可以对 TextArea 进行写入部分。 您可能需要在主线程和可运行线程之间进行一些同步,以便仅在从端口读取适当的数据后才写入文本区域/文件。

© www.soinside.com 2019 - 2024. All rights reserved.