lua文件读取注意事项

来源:互联网 发布:低风险理财 知乎 编辑:程序博客网 时间:2024/05/16 11:31
--[[
文件功能:读取CSV文件到table中,从返回的table中获取CSV的字段。
date:2013.7.18
author:JesseCen
CSV文件的规则:
         1.字符编码为UTF-8,否则不能正确处理中文字符。
         2.首行是中文描述字段名称,第二行是代码中使用的字段名称。
         3.文本第二行开始,所有的字段都要以英文逗号分隔,行最后可以不用逗号字符分隔(字段之间可以允许有多余的空格)。
         4.如果文本中需要输入","号,那么用"\,"即可(多于一个逗号还会有bug)。
访问规则:
       id关键字都要用字符串作为访问下标,例如:
       local infoTag=GameData.PlayerAnimatInfo["100110"].StartHitFrame
排序功能使用规则:
       返回按照参数2进行升序降序排列的key列表;传参1是read函数返回的表,参数2是依据该字段排序的字符串名。
       例如:local tSkillID = LuaCSVFile:getKeyTableDESC(GameData.skillBaseEffect,"skillLevel")
遇到问题:1.需要截取要读取的文件大小,否则末行因为越界而末尾乱码。
          2.lua 不能频繁的进行字符串substr操作,否则lua虚拟机频繁的申请内存和回收内存会使得文件读取很慢,应该装到table里面或用游标的方式替代。

--]]
LuaCSVFile = class("LuaCSVFile")
LuaCSVFile.__index = LuaCSVFile
local function checkPlatform()
    local enter = nil
    local sharedApplication = CCApplication:sharedApplication()
    local target = sharedApplication:getTargetPlatform()
    if target == kTargetWindows then
        enter = "\n"
    else
        enter = "\r"
    end
    return enter
end


local function trim(str) --去掉空格 
    if str == nil then  
        return nil, "the string parameter is nil"  
    end  
    str = string.gsub(str, " ", "")  
    -- str = string.gsub(str,"\r","")
     return str  
end


local function trimRN(str) --linux 上去除\r换行符,读取问题多是有符号和空格的原因
    if str == nil then
        return  nil,"the string parameter is nil"
    end
   -- str = string.gsub(str, " ", "") 
    str = string.gsub(str,"\r","")
    str = string.gsub(str,"\n","")
    return str
end


--判断关键字是数字,不是数字的将其去除
local function isNumber(str)  
    if str == nil then  
        return nil
    end  
    local ch = string.sub(str, 1, 1)  
    if ch < '0' or ch > '9' then  
        return false  
    else 
        return true
    end  
end


function LuaCSVFile:read(filePath,isFont) --isFont读取界面文字,启用时传入非nil参数,最好传入true
    local enter = checkPlatform() --enter换行符
    local file = CSVFile:getInstance()
    local csvfile = file:Open(filePath)
    local cursorStart = 1 --当前的游标开始截取的位置
    if csvfile == nil then 
        CCLuaLog("csvfile" .. "error=no open file")
       return
    end
     local totalLen = file:getLength()
     csvfile = string.sub(csvfile, 1, totalLen )
    --第一行中文说明
    cursorStart = string.find(csvfile,enter) + 1
    local filetbl = {}   
    local line = ""
    local ntable = {}


    if not isFont then
        csvfile = trim(csvfile)
    end
    local endNum = string.find(csvfile,enter,cursorStart)
    line = string.sub(csvfile,cursorStart, endNum)
    line = trimRN( line )
    if line == nil then file:Close() return end
    local keyFlag = 0
    local nIndex = 0
    local nIndexPre = 1
    local tableKeyName = ""
    while true do 
        nIndex = string.find(line,",",nIndexPre)
        if nIndex == nil then
            tableKeyName = string.sub(line,nIndexPre,string.len(line))
            if tableKeyName ~= nil then
                table.insert(ntable,tableKeyName)
            end
            break
        end
        tableKeyName = string.sub(line, nIndexPre, nIndex-1)
        nIndexPre = nIndex + 1              
        if keyFlag > 0 then --去除第一个字段
            table.insert(ntable,tableKeyName)                
        end
        keyFlag = 1
    end
     --跳过行
     cursorStart = endNum + 1
    --跳过類型行
    cursorStart = string.find(csvfile,enter,cursorStart) + 1
    ---记录字段值到subTable
    local kIndex
    local kIndef
    local onceFlag = 0
    local keyValue = ""
    while true do
        startIndex = string.find(csvfile,enter,cursorStart)
        if startIndex == nil then
                break
        end  
        line = trimRN(string.sub(csvfile, cursorStart, startIndex))
        --得到key                
        kIndex = string.find(line,",")   
        if kIndex == nil then
                break
        end     
        keyValue = string.sub(line,1,kIndex-1)
        --取得各个字段值
        local subTable = {}   
        local isEscape = nil 
        local fieldValue1 = ""
        local fieldValue = ""
        local kIndefPre = 1
        line = string.sub(line,kIndex+1,string.len(line))            
        for i,v in pairs(ntable) do        
            kIndef = string.find(line,",",kIndefPre)
            if kIndef == nil then
                local fieldValue = string.sub( line, kIndefPre, string.len(line) )
                if fieldValue ~= nil then 
                    subTable[v] = fieldValue 
                end
                break
            end 
                           
            fieldValue = string.sub(line,kIndefPre,kIndef-1)
            kIndefPre = kIndef + 1
            subTable[v] = fieldValue      
        end    
       --记录到表中  
        filetbl[keyValue] = subTable
        --跳过当前读取行
        cursorStart = startIndex + 1  
    end
    file:Close() --关掉文件流,删除new出来的堆内存
    return filetbl
end




function LuaCSVFile:save(filePath,tbl)--将读取的csv得到的tbl信息存放到其它文件中
    if filePath == nil then return end
    if tbl == nil then return end
    --Open file to write
    local dfile = io.open(filePath,"w")
    if dfile == nil then return end
    dfile:write("fileName\n")
    for i,v in pairs(tbl) do
        --dfile:write(i)
        --dfile:write(v)
        dfile:write("\n")        
    end    
end    




local function reCreateNameTable(tTable) --构造一个命名的table,用于排序
     local createTable = {}
     local tempTable = {}
     local index = 1
      for i ,v in pairs(tTable) do
        if isNumber(i) then --去除末行情况
          tempTable["id"] = i
          tempTable["record"] = v
          v.id = i
          createTable[index] = tempTable --不能用tostring(index)
          tempTable = {}  --置空
          index = index +1
         end
      end
      return createTable
end


--获取升序排列的表id值
function LuaCSVFile:getKeyTableASC(tTable,sfield) --tTable是排序的表,sfield是排序的字段字符串名
    local keyTable = {}
    local reTable = reCreateNameTable(tTable)
    --排序开始
    table.sort(reTable,function(a,b)
        return (tonumber(a.record[sfield]) < tonumber(b.record[sfield]))
    end)
     --排序结束
     --
     for i, v in pairs(reTable) do
       keyTable[i] = v.id
     end


     return keyTable
 end


--获取降序排列的表id值
 function LuaCSVFile:getKeyTableDESC(tTable,sfield) 
    local keyTable = {}
    local reTable = reCreateNameTable(tTable)
    --排序开始
    table.sort(reTable,function(a,b)
      --  local x = a.record[sfield]
        return (tonumber(a.record[sfield]) > tonumber(b.record[sfield]))
    end)
     --排序结束
     --
     for i, v in pairs(reTable) do
       keyTable[i] = v.id
     end


     return keyTable
 end


--返回原始的id表
function LuaCSVFile:getKeyTable(tTable)
  local keyTable = {}
  local reTable = reCreateNameTable(tTable)


  for i,v in pairs(reTable) do
    keyTable[i] = v.id
  end


  return keyTable
end
0 0
原创粉丝点击