Visual HMIファイルIO:LUA読み書きSDカード/USBドライブ/フラッシュとカタログ列挙

freeFree Technical Resource

This content is free to read, suitable for basic learning and search traffic.

ファイル読み書きAPIのフルスイート:txt/csv/binの読み取り、ファイルの書き込み、ディレクトリのトラバース、コピー/削除。基本的なアイデアは1つです。ストリーミング、メモリに2 KB以上のバッファを同時にexistenceさせない。HMIメモリは非常に小さく、ウォッチドッグの直接リセットに違反し、デバイスは警告なしに再起動します。

1.ストレージデバイスID(Mシリーズvs DHシリーズ)

設備はMシリーズDHシリーズ
SDカード。1:/1.txt/sdcard/1.txt
Uディスク。2:/1.txt/udisk/1.txt
内部 Flash3:/1.txt/data/1.txt

パスの区切り文字は/でなければなりません。

2.ドキュメントAPI概要

関数の機能パラメータ説明書は
dofile(name)luaファイルのパスロード実行.luaモジュール、大規模プロジェクトのモジュール解除
list_dir(path)ディレクトリ·パスディレクトリを非同期スキャンし、結果を項目ごとにコールバックon_list_dir
on_list_dir(path,filename,type,fsize)type 0=フォルダ/1=ファイル;fsizeバイト検索結果のコールバック、検索されたエントリごとに1回
file_open(path,mode)mode 0= FA_READ読み取り専用/1= FA_WRITE上書き書き込み/2= FA_WRITE_ADD追加書き込みファイルを開き、ブール値を返す
file_close()-ファイルを閉じ、書き込み後に調整する必要があり、データのドロップ防止
file_size()-現在開いているファイルの合計バイト数
file_seek(offset)バイトオフセット、0=ファイルの開始読み取りと書き込みの位置
file_read(count)1 ≤ count ≤ 2048バイト配列(テーブル、インデックス1から)を読み取り、失敗してnilを返す
file_write(data)バイトテーブル、1 ≤ #data ≤ 20 4 8バイト配列を書き込み、ブール値を返す
file_delete(path)フルパスを参照。ファイルの削除、復元不可
file_copy(src,dst)ソース/ターゲットフルパスファイルのコピー、進行状況コールバックon_copy_file_process
on_copy_file_process(status,filesize,transfersize)status 0失敗/1進行中/2成功コピーの進行状況コールバック、transfersizeコピーされたバイト
mkdir(dir)完全なディレクトリパス同期フォルダの作成

3.メモリ安全

複数の読み取りデータをグローバル変数や長寿命バッファに蓄積することは禁止します。典型的なエラー:最初の読み取りは2 KBグローバルテーブルを格納し、その後の読み取りは毎回追加されます。大きなファイルを処理するとメモリが成長し続け、ウォッチドッグのリセットが直接トリガーされます。

正しい姿勢:フロー処理--各file_read(2048)の直後にParse/検証/書き込み/表示され、処理が完了すると解放され、いつでもメモリ内には≤ 2 KBの一時バッファが1つしかない。ファイルを書くのと同じです:一度に2048バイト以下のブロックを準備するたびに、一度にfile_writeを作成し、最初に数MBの大きなテーブルをスクランブルしないでください(データ準備段階でメモリオーバーフローが発生します)。

4.ファイルの読み取りストリーミングチャンク+コールバック

正式に閉鎖。file.read_stream(filepath, on_chunk)開く→サイズを取る→ループseek+readコールバックはfalseを返し、大きなファイルループはfeed_dogを犬にフィードします。

4.1 txtを読む行ごとに表示

addr === 0 x 1501の場合
  local idx = get_uint16 vtype addr
  Ix == 0の場合、終了を返す
  local path = idx == 1 and "1/1.txt" or "1/2.txt"
  record_clear 0
  g_line_bu = """                       - ラインバッファ。
  file.read_stream path function chunk offset is_last
    local str = ""
    for _b in ipairs chunk do =.. string.char b end
    g_line_bu = g_line_bu.. str
    local lines = my_split g_line_buffer "n"--行ごとに分割
    g_line_buffer = lines[#lines]          --不完全な行を保持するブロックにまたがる可能性がある
    for i = 1 #line-1 do
      if #lines[i] 0 then record_write_string 0 lines[i] end
    End of Endシングル
    真のリターン
  end nParticle
  if string.len g_line_buffer 0then    - 最後の行。
    record__string 0 g_line_bu
  End of Endシングル
End of Endシングル

クロスブロック行バッファに注意してください:改行は2つのブロックの間に入る可能性があるので、g_line_bufferを維持して不完全な行を次のブロックに残します。

4.2 binを16バイト1行で読み取る

elseif addr == 0 x 150 2 then
  local idx = get_uint16 vtype addr
  Ix == 0の場合、終了を返す
  local path = idx == 1 and "1/1.bin" or "1/2.bin"
  record_clear 1
  g_byte_bu = {}
  file.read_stream path function chunk offset is_last
    for _b in ipairs chunk do
      table.insert g_byte_buffer b
      if #g_byte_buffer = 16 then        --フル16バイトごとに1行コミット
        ローカル線= {}
        for i = 1 16 do line[i] = g_byte_bu [i] end
        record_write_data 1、line
        for i = 1 16 do table.remove g_byte_buffer 1 end
      End of Endシングル
    End of Endシングル
    真のリターン
  end nParticle
  if #g_byte_buffer 0 then              --末尾が16バイト未満で補数0
    while #g_byte_bu16 do table.insert g_byte_bu0 end
    record__data 1 g_byte_bu
  End of Endシングル

5.文書を書く。

カプセル化するfile.write_chunk(filepath, data, mode)モード1=上書き書き込み、2=追加書き込み、データは文字列またはバイトテーブル(≤ 20 4 8)をサポートします。

function file._chunk filepath data mode
  if mode ~= file.mode.create and mode ~= file.mode.append false endを返す
  local t = type data
  local len = t == "string" or t == "table" and #data or -1
  もしlen chunk_sizeがfalseを返す   - メモリオーバーフロー防止
  local ok = file_open filepath mode
  OKでない場合はfalse endを返す
  mode == file.mode.append then            -- 追加モードは手動で配置する必要があります!
    local size = file_size
    if not file_seek size then file_close; return false end
  End of Endシングル
  local buf = {}
  if t == "String" then
    for i = 1 len do buf[i] = string.byte data i end
  elseさん
    for i = 1 len do buf[i] = data[i] end
  End of Endシングル
  local ret = file_buf
  file_cl
  Return toレット
End of Endシングル

シナリオ1:新規執筆
local name = get_string VT_LW、0x1510
local msg = get_string_LW、0x1520
名前がない場合、#name == 0またはmsgでない場合、終了します。
file._chunk "1/"..名前は。".txt"、msg..“n”1

シナリオ2:追加書き込み
file._chunk "1/"..名前は。".txt"、msg..“n”2

️追加の書き込みは明示的にfile_seek file_sizeを行う必要があります。HMIのfile_open(mode=2)はPOSIXのO_APPENDと等しくないため、自動的に最後に配置されません。seekせずにオフセット0から書き込みを開始し、元のファイルの先頭を上書きします。

6.トラバース+コピー削除

6.1 SDルートをトラバースしてデータログコントロールに表示

function get_extension
  local dot = string.find filename ". "1 true
  If Dot Thenより
    return string. 1 dot-1 string. dot +1 l
  End of Endシングル
  return filename "不明"
End of Endシングル

function on_list_dir path、、type、fsize
  ローカルMSG
  type == 0の場合
    msg = filename..“;フォルダ;”
  elseさん
    ローカルSz
    if fsize = 1024 ^3 then sz = string." %. 2fG" fsize/1024 ^3
    elseif fsize = 1024 ^2 then sz = string." %. 2fM" fsize/1024 ^2
    elseif fsize = 1024 then sz = string." %. 2fKB" fsize/1024
    else sz = fsize.. "byte" end
    local name ext = get_extension
    msg = name.. ";".. Ext..。";".. SZ..。";"
  End of Endシングル
  record_write_string 2、msg
End of Endシングル

更新ボタンLW1504=1
function on_update slave vtype
  if vtype ==_LW then
    if addr === 0x1504 and get_uint16 vtype addr == 1 then
      record_clear 2
      list_dir "1"          --SDルートディレクトリを横断する
    End of Endシングル
  End of Endシングル
End of Endシングル

6.2コピー +削除(プログレスバー付き)

function on__file_status filesize transfersize
  ステータス== 0の場合
    set_uint16 VT_LW、0x1507、3           - 失敗した
  elseif status == 1 then
    local p = math.floor transfersize * 100 / filesize
    set_uint16 VT_LW、0x1506、p           - プログレス·バー
    refresh_screen
  elseifステータス== 2倍
    set_uint16 VT_LW、0x1506、100
    set_uint16 VT_LW、0x1507、2           【成功】
    refresh_screen
  End of Endシングル
End of Endシングル

function on_update slave vtype
  vtype == VT_LWとaddr == 0 x 150 5の場合
    local mode = get_uint16 vtype
    mode == 1の場合                      - コピーする。
      if file.exists "1/1.txt" then
        file_copy "1/1.txt"、"1/1_copy.txt"
      elseさん
        set_uint16 VT_LW、0x1507、1
      End of Endシングル
      mkdir "1/test"
    elseif mode == 2 then                  --削除する
      file_"1/test"
      if file.exists "1/1_y.txt" then
        file_"1/1_y.txt"
        if not file.exists "1/1_y.txt" then
          set_uint16 VT_LW、0x1507、4
        elseさん
          set_uint16 VT_LW、0x1507、5
        End of Endシングル
      elseさん
        set_uint16 VT_LW、0x1507、1
      End of Endシングル
    End of Endシングル
    refresh_screen
  End of Endシングル
End of Endシングル
5つの穴がある。メモリの鉄の法則-大域累積大バッファの禁止一度に≤ 2 KBのブロックのみを保持するか、ウォッチドッグがリセットされます。2追加の書き込みはfile_seek file_sizeHMIのappendはO_APPENDではない。パスにはデバイスプレフィックスと/が必要です。--“1/config.txt”が正しく、“1 config.txt”が間違っています。④大きなファイル読み込みループでは_dogが必要時間のかかることを避ける。⑤ファイル书き込み直后file_cl停電はファイルや部分的な書き込みを損傷します。

広州大彩科技Visual HMI開発ドキュメント(hmi-doc.gz-dc.com)LUAチュートリアル“ファイルの読み書き”、著作権は大彩科技に帰属します。

Put this resource to use in a real project?

Go to the Tool Center for message parsing, CRC verification and device debugging, or submit your requirements for selection and integration advice.

Engineer Membership

Turn this article into actionable debugging resources

After activation, you can use advanced message parsing, resource pack downloads, code examples, engineering cases and priority technical support, suitable for real project delivery.

Unlimited Advanced Tools
Resource & Code Packs
Complete Engineering Case Library
Priority Technical Support

Leave a Reply

Your email address will not be published. Required fields are marked *.