串口上传输文本文件

契机:一位朋友的求助。

目的:通过串口传输XML文件。

开发平台:Delphi7

核心组件:SPComm

发送端:

 const  //申明长度和简单的协议头、尾标识常量
    LEN_FILENAME = 255;
    MAX_LENGTH = 1024;
    MARK_HEAD = '#MYFILE#%s';
    MARK_END = '#END#';

{
  发送文件
  aFile - 文件名
  aDelay - 发送延时,给接收端以足够的处理时间,在实际应用时通过经验调节
  comm: 用来发送数据的SPComm串口对象,在调用该方法前请确保comm已经打开(StartComm)。
}

procedure sendFile(aFile: string; aDelay: integer; comm: TComm);
var fs: TFileStream; //以流的方式读文件
    ss, fn: string//文件名处理变量
    buf: array[1 .. MAX_LENGTH] of char; //用于读取文件数据的缓存数组
    iLen, i: integer;
begin
  //判断参数的有效性
  if not FileExists(aFile) or (comm = nil) then Exit;
  //打开文件,准备读取
  fs := TFileStream.Create(aFile, fmOpenRead);
  with comm do try
    try
      //将固定长度的文件名写入发送头(简单的协议)
      fn := ExtractFilename(aFile);
      for i := 1 to LEN_FILENAME - Length(fn) do
        fn := fn + ' ';
      ss := Format(MARK_HEAD, [fn]);
      WriteCommData(pchar(ss), Length(ss));
      //延时
      sleep(aDelay);
      //循环读取文件数据并发送
      repeat
        try
          iLen := fs.Read(buf, MAX_LENGTH);
          if iLen > 0 then begin
            WriteCommData(@buf, iLen);
            sleep(aDelay);
          end;
        except
          break;
        end;
      until iLen <= 0;
      //发送数据结束标志(简单的协议)
      WriteCommData(MARK_END, Length(MARK_END));
    except
    end;
  finally
    //保证文件的关闭
    fs.Free;
  end;
end;

接收端:

const  //申明长度和简单的协议头、尾标识常量
    MAX_LENGTH = 1024;
    LEN_FILENAME = 255;
    MARK_HEAD = '#MYFILE#';
    MARK_END = '#END#';

var fs: TFileStream; 

{
  将文本串以流的方式写入文件
}
procedure writeStr(s: string; fs: TFileStream);
var
    buf: array[1..MAX_LENGTH] of char; //数据缓存
    i, j, iLen: integer;
begin
  if fs = nil then Exit;
  i := 1;
  while i <= length(s) do begin
    if Length(s) - i + 1 > MAX_LENGTH then
      iLen := MAX_LENGTH
    else
      iLen := Length(s) - i + 1;
    for j := i to i + iLen - 1 do
      buf[j - i + 1] := s[j];
    fs.Write(buf, iLen);
    inc(i, iLen);
  end;
end;
{
  接收数据串到文件
}

procedure receiveData(ss: string);
var fn, s1: string;
begin
  //判断文件头
  if copy(ss, 1, Length(MARK_HEAD)) = MARK_HEAD then begin
    //创建接收文件
    if fs <> nil then fs.Free;
    fn := trim(copy(ss, Length(MARK_HEAD) + 1, LEN_FILENAME));
    fs := TFileStream.Create(fn, fmCreate);
    //截取信息头和文件名以外的主体数据
    s1 := copy(ss, Length(MARK_HEAD) + LEN_FILENAME + 1,
      Length(ss) - Length(MARK_HEAD) - LEN_FILENAME);
    //写入文件
    writeStr(s1, fs);
  end else
    //判断结束标志
    if pos(MARK_END, ss) <> 0 then begin
      //截取结束标志以外的主体数据并写入文件
      s1 := Copy(ss, 1, pos(MARK_END, ss) - 1);
      writeStr(s1, fs);
      //关闭文件
      if fs <> nil then fs.Free;
      fs := nil;
    end else if fs <> nil then try
      //将主体数据写入文件
      writeStr(ss, fs);
    except
    end;
end;

{
  Comm组件的数据接收事件
}

procedure TForm1.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
  BufferLength: Word);
var i: integer;
    s: array of char; //数据缓存
    ss: string; //因为是文本信息,通过字符串方式处理
begin
  //初始化缓存
  setLength(s, BufferLength);
  //接收数据到缓存
  s := Buffer;
  //生成数据串
  ss := '';
  for i := 0 to BufferLength - 1 do
    ss := ss + s[i];
  //接收到文件
  receiveData(ss);
end;

后记:上面的代码只是给了个大体的思路,要真正的应用,还需要进一步的完善。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值