0

ia 问题与 java 以及如何导入文件 1024000 数字。我创建了一个从端口读取数据并将每个数字作为 ascii 字符存储到文件中的应用程序。但它需要太长时间。java应该更快。我应该改变什么?我应该使用其他库吗?不是 FileOutputStream 吗?正如我现在在 20 分钟内测试的那样,我的文件中有 100.000.... 谢谢

public void serialEvent(SerialPortEvent evt) {  

   if (evt.getEventType() == SerialPortEvent.DATA_AVAILABLE)  
   {  
       try  
       {  
           int singleData = input.read();  

           if(index<=1024000)  
           {                 
               if(index==1024000 && singleData==42)
               {
                   logText = "End of data. "+index+" data received ";  
               }
               else
               {  
                   if (singleData != NEW_LINE_ASCII)  
                   {  
                       //  logText = Integer.valueOf(singleData).toString()+"\n";  
                       index++;  
                   }  

                   writeFile(singleData, fileName, false);  
               }         
           }  
       }
       catch (Exception e)
       {  
           logText = "Failed to read data. (" + e.toString() + ")";  
       }  
    }  
}  

public void writeFile(int data, String fileName, boolean endOfFile) throws IOException {  

    FileOutputStream xfos = new FileOutputStream(fileName,true);  
    DataOutputStream xdos = new DataOutputStream(xfos);  

    xdos.writeBytes(Integer.toString(data)+"\n");   // writes Ascii  

    xdos.close();  
}  
4

4 回答 4

3

停止为每个条目打开和关闭文件,并开始缓冲。创建一个 int[] 来保存传入的整数,并且仅在您拥有相当数量的整数之后才写入。此外,根据环境,您可以保持流打开并仅在退出时关闭它们(或读取 1024000 个条目)。

现在每次你得到一个整数,你打开文件,跑到最后,写一行,然后关闭它。打开和关闭是昂贵的,你当然可以这样写,这样就不必每次都发生。

于 2013-09-26T17:11:05.887 回答
0

保持输出文件打开,直到完成写入。每次写入后关闭文件会导致操作系统将您刚刚写入磁盘的单个字节写入磁盘。无论使用哪种语言,这都很慢,这只是文件关闭操作附带的保证的效果。此外,每次打开文件时都要找到文件的结尾,文件变得越长,也可能需要相当长的时间。

利用流的批量读写方法。不要读写单个字符,而是使用合理大小的 byte[](通常 8K = 8192 就足够了)。或者,通过将流包装到 BufferedInputStream/BufferedOutputStream 中来缓冲流(开销稍高,但代码更简单)。

本质上,您应该做的是在开始时打开输入和输出流一次,并保持它们都打开,直到所有数据都通过。使用块传输或缓冲流的主要限制因素将是硬件(在您的情况下为串行端口)。

于 2013-09-26T17:59:21.460 回答
0

谢谢大家,但我相信我一开始只打开一个输入输出流。我在 GUI Connect 中有一个按钮,它可以执行此操作:连接到端口初始化流

    private void btnConnectActionPerformed(java.awt.event.ActionEvent evt) {
        communicator.connect();
        if (communicator.getConnected() == true)
        {
            if (communicator.initIOStream() == true)
            {
                communicator.initListener();

            }
        }
    }


 //connect to the selected port in the combo box
public void connect()
{

 fileName="xxxx"+"_"+new SimpleDateFormat("yyyy-MM-dd hh-mm-ss").format(new Date())+".txt";
    String selectedPort = (String)window.cboxPorts.getSelectedItem();
    selectedPortIdentifier = (CommPortIdentifier)portMap.get(selectedPort);
    index=0;
    vec.clear();
    CommPort commPort = null;

    try
    {
        //the method below returns an object of type CommPort
        commPort = selectedPortIdentifier.open("TigerControlPanel", TIMEOUT);
        //the CommPort object can be casted to a SerialPort object
        serialPort = (SerialPort)commPort;
        output = serialPort.getOutputStream();

        //for controlling GUI elements
        setConnected(true);
        window.txtLog.setText(null);
        //logging
        logText = selectedPort + " opened successfully.";
        window.txtLog.setForeground(Color.black);
        window.txtLog.append(logText + "\n");

    }
    catch (PortInUseException e)
    {
        logText = selectedPort + " is in use. (" + e.toString() + ")";

        window.txtLog.setForeground(Color.RED);
        window.txtLog.append(logText + "\n");
    }
    catch (Exception e)
    {
           if(selectedPort==null)
           {  
            logText = " No port selected";

           }else 
            logText = "Failed to open " + selectedPort + "(" + e.toString() + ")";
        window.txtLog.append(logText + "\n");
        window.txtLog.setForeground(Color.RED);
    }
}

//open the input and output streams
public boolean initIOStream()
{
    //return value for whather opening the streams is successful or not
    boolean successful = false;

    try {
        //
        input = serialPort.getInputStream();
        output = serialPort.getOutputStream();

        successful = true;
        return successful;
    }
    catch (IOException e) {
        logText = "I/O Streams failed to open. (" + e.toString() + ")";
        window.txtLog.setForeground(Color.red);
        window.txtLog.append(logText + "\n");
        return successful;
    }
}

//starts the event listener that knows whenever data is available to be read
public void initListener()
{
    try
    {
        serialPort.addEventListener(this);
        serialPort.notifyOnDataAvailable(true);

    }
    catch (TooManyListenersException e)
    {
        logText = "Too many listeners. (" + e.toString() + ")";
        window.txtLog.setForeground(Color.red);
        window.txtLog.append(logText + "\n");
    }
    try {
        output.write(messageString.getBytes());
      // output.write(System.getProperty("java.library.path").getBytes()) ;

    } catch (IOException e) { }
}
于 2013-09-27T07:07:29.597 回答
0

谢谢大家的建议。我更改了代码并使用缓冲区字节 [] 来获取数据,然后将它们全部存储在一个文件中。时间缩短得不可思议。它在 1.31 秒内读取 1024001 个数据。问题是我可以让它更快吗?它只是数字,它应该只需要几秒钟。这是代码

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

     int    available =0;
     int bytesRead;
    try {

        available = input.available();
    } catch (IOException e) {
            e.printStackTrace();
    }
             byte[] buffer = new byte[1024001];

            try {
        while ( (bytesRead = input.read(buffer)) > 0 ) {
             byte[] newData = new byte[data.length + bytesRead];
         // copy data previously read
         System.arraycopy(data, 0, newData, 0, data.length);
        // append data newly read
         System.arraycopy(buffer, 0, newData, data.length, bytesRead);
         // discard the old array in favour of the new one
         data = newData;
         if(data.length==1024001)
              {
                     logText = "End of data. "+data.length+" data received "+fileName;
                 window.txtLog.setForeground(Color.BLUE);
                 window.txtLog.append(logText + "\n");
                 writeFile(data, fileName, false);
                    }  
            bytesRead++;                 

我还为端口设置了这些参数

               serialPort.setSerialPortParams(115600,
                SerialPort.DATABITS_8,
                SerialPort.STOPBITS_1,
                SerialPort.PARITY_NONE);           

有没有办法将串口速度设置为全速?

于 2013-09-30T07:47:51.307 回答