一次读一行

时间:2013-06-19 16:07:12

标签: c#

我目前正在开展一个项目。但我不太擅长C#。我需要做的是,打开一个G代码文件并从中读取数据并通过USB将其发送到CNC机器。我可以读取数据并发送它。但现在我想读一行并通过USB发送,然后读下一行。下面我附上了用于阅读G代码文件和其他相关数据的代码。

打开g代码文件并将所有数据读入文本框:

 private void btnopen_Click(object sender, EventArgs e)
    {
        //OpenFileDialog1.ShowDialog();
        OpenFileDialog file = new OpenFileDialog();
        file.FileName = "";
        file.Title = "Open A Text document.";
        file.Filter = "(*.gc)|*.gc|(*.etf)|*.etf|(*.txt)|*.txt|(*.GC)|*.GC|(*.tap)|*.tap";
        DialogResult result = file.ShowDialog();
        if (result == DialogResult.OK)
        {
            System.IO.StreamReader OpenFile = new System.IO.StreamReader(file.FileName);


            textBox1.Text = OpenFile.ReadToEnd();

            OpenFile.Close();


        }

从打开的文件中读取X Y Z坐标:

  private void button1_Click(object sender, EventArgs e)
    {


        Regex Gcode = new Regex("[ngxyzf][+-]?[0-9]*\\.?[0-9]*", RegexOptions.IgnoreCase);
        MatchCollection m = Gcode.Matches(this.textBox1.Text);


        double X, Y, Z, F;


        int g_code = 0;
        int x_code = 0, y_code = 0, z_code = 0;
        float x = 0, y = 0, z = 0;


        foreach (Match n in m)
        {

            if (n.Value.StartsWith("G"))
            {
                g_code = Convert.ToInt32(ExtractNumbers(n.Value));
            }

            if (n.Value.StartsWith("X"))
            {
                x = float.Parse(ExtractNumbers(n.Value));
                x = x * 1000;
                x_code = Convert.ToInt32(x);

            }

            if (n.Value.StartsWith("Y"))
            {
                y = float.Parse(ExtractNumbers(n.Value));
                y = y * 1000;
                y_code = Convert.ToInt32(y);

            }

            if (n.Value.StartsWith("Z"))
            {
                z = float.Parse(ExtractNumbers(n.Value));
                z = z * 1000;
                z_code = Convert.ToInt32(z);
            }
        }


        ExchangeInputAndOutputReports(g_code,x_code, y_code,z_code);

}

4 个答案:

答案 0 :(得分:3)

一些重构将有助于改进您的代码 首先从按钮单击中提取代码并构建一个接收字符串并操作该行上存在的命令的私有方法。 然后修改打开文件的方法,以便及时读取一行,并为每行调用提取的方法...

using(StreamReader OpenFile = new System.IO.StreamReader(file.FileName))
{
    string textLine = string.Empty;
    // Loop until the end of file and call the operation for the line
    while((textLine = OpenFile.ReadLine()) != null)
        ExecuteLine(textLine);
}

private void ExecuteLine(string line)
{
    Regex Gcode = new Regex("[ngxyzf][+-]?[0-9]*\\.?[0-9]*", RegexOptions.IgnoreCase);
    MatchCollection m = Gcode.Matches(line);
    ....
}

当然,不要忘记从按钮单击调用新的私有方法以保留以前的功能。

private void button1_Click(object sender, EventArgs e)
{
     ExecuteLine(textBox1.Text);
}

答案 1 :(得分:1)

而不是

textBox1.Text = OpenFile.ReadToEnd();

你想要

string line = OpenFile.ReadLine();
while (line != null)
{
    // do something with line
    line = OpenFile.ReadLine();
}

答案 2 :(得分:0)

您只是立即阅读整个文件。您可以这样做,然后从内存中对象读取每一行,或者您可以直接从文件中一次读取一行。第二种方法更冗长,更容易理解,但如果您有错误或中间发生某些事情,它很容易让文件保持打开状态。

这是一个演示程序,展示了如何一次读取一行... http://www.dotnetperls.com/file-readlines

答案 3 :(得分:0)

您无法逐行读取gcode文件,因为:A)您可以在一行上拥有多个命令。 B)一个命令可以跨越多行。

您可以在https://github.com/chrismiller7/GCodeNet

使用我的gcode解析库

做类似的事情:

new Thread(() -> {
    for (int i = 1; true; i++) {
        try {
            Thread.sleep(1000);
        } catch (final InterruptedException e) {
            return;
        }

        if (shell.isDisposed())  // Stop thread when shell is closed
          break;

        final String newText = Integer.toString(i);
        Display.getDefault().asyncExec(() -> text.setText(newText));
    }
}).start();