You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NativeScript(TS)中readTextSync读取CSV时数据篡改问题求助

问题描述

我在NativeScript(TypeScript)环境下读取CSV文件,文件内容示例如下:

25300-2-0842;A PATTE PEINT;2;PC;2 10 C;;;;;
25300-2-0845;A PATTE PEINT;2;PC;2 10 C;;;;;
25300-2-0980;B FIXATION BATTERIE PEINT;2;PC;2 10 C;;;;;
25300-2-1390;B TOLE PEINT C3;8;PC;3 10 C;;;;;
25300-2-1528;A CAPOT PEINT C3;4;PC;4 10 C;;;;;
25300-2-0285;B TOLE PEINT;4;PC;2 11 C;;;;;

我需要获取每行第5个字段的位置信息,代码如下:

global.currentLine.emplacement = helper.getToken(fileInput[i], 5).trim().toUpperCase();

但解析时出现错误:

  • CSV文件中该字段为2 10 C
  • 读取后fileInput[i]内容变成25300-2-0842;A PATTE PEINT;2;PC;210 C;;;;;
  • 导致getToken返回210 C,位置信息丢失了空格

所有行都存在这个问题,正确结果应该是2 10 C而非210 C。请问这是什么原因?readTextSync会做隐式转换吗?相关代码如下:

export function getToken(Text:string="", Index:number=1, Separator:string=";"):string {
  let result = "";
  if ((Text != null) && (Text != "")) {
    let temp = Text.split(Separator);
    Index--;
    if (Index < temp.length)
      result = temp[Index];
  }
  return result;
}

async function loadData():Promise<boolean> {      
  global.lignes  = -1;
  const filepath = fileCheck("stock.csv");
  if (filepath == "") {
    helper.loading.hide();
    await helper.dialogsModule.alert({
      title        : "Erreur critique !",
      message      : "Le fichier des données stocks (stock.csv) n'est pas présent.\nL'application EASY va se terminer.",
      okButtonText : " OK ",
      cancelable   : false
    })
    exit()
  }
  const filefevcsv : File = File.fromPath(filepath);
  global.fileinput = filefevcsv.readTextSync(loadError, encoding.UTF_8);
  let dummy      = "";
  let fileInput  = global.fileinput.split("\n");
  let lengthData = fileInput.length;
  if (lengthData < 3) {
    helper.loading.hide();
    await helper.dialogsModule.alert({
      title        : "Erreur critique !",
      message      : "Le fichier des données stocks (stock.csv) ne semble pas complet.\nL'application EASY va se terminer.",
      okButtonText : " OK ",
      cancelable   : false
    })
    exit()
  }  
  global.lignes      = 0;
  global.data.length = 0;
  let maxloop        = lengthData + 1;
  for (let i = 1; i < maxloop; i++) {
    dummy = helper.getToken(fileInput[i],1).trim();
    if (dummy == "")
      continue;
    global.lignes++;
    global.currentLine.reference   = dummy;
    global.currentLine.description = helper.getToken(fileInput[i], 2).trim();
    global.currentLine.quantite    = parseCheck(helper.getToken(fileInput[i], 3).replace(",", "."));
    global.currentLine.unite       = helper.getToken(fileInput[i], 4).trim().toUpperCase();
    if (global.currentLine.unite == "")
      global.currentLine.unite = "PC";
    global.currentLine.emplacement = helper.getToken(fileInput[i], 5).trim().toUpperCase();
    // Structure différente si gestion double emplacement ou non
    let colnum;
    if (global.dblempl) {
      global.currentLine.emplacement2 = helper.getToken(fileInput[i], 6).trim().toUpperCase();
      colnum = 7;
    }  
    else
      colnum = 6;
    global.currentLine.observation = helper.getToken(fileInput[i], colnum).trim();
    global.currentLine.observation = global.currentLine.observation.replace(/<br>/g, "\n");
    global.currentLine.operation   = helper.getToken(fileInput[i], colnum+1).trim();
    global.currentLine.operateur   = helper.getToken(fileInput[i], colnum+2).trim();
    global.currentLine.horodatage  = helper.getToken(fileInput[i], colnum+3).trim();
    if (global.currentLine.horodatage == "") {
      global.currentLine.horodatage = "--/--/----";
    }  
    dummy                          = helper.getToken(fileInput[i], colnum+4).trim().toUpperCase();
    global.currentLine.cq          = (dummy == "1") || (dummy == "VRAI") || (dummy == "TRUE") || (dummy == "X")
    await global.data.push(helper.copyArray(global.currentLine));
  }
  return true;
}
问题分析与解决方案

核心原因

readTextSync本身不会做隐式转换导致空格丢失,问题大概率出在以下两个方向:

  1. 非标准空白字符:CSV中的2 10 C里的空格并非普通半角空格(ASCII 32),而是非断空格(\u00A0)、全角空格或其他空白字符,这些字符在显示时和普通空格一致,但在读取或后续处理中被意外合并/忽略。
  2. 文件编码不匹配:虽然代码指定了UTF_8编码,但如果CSV文件实际使用的是Windows-1252等其他编码,读取时会导致字符解析异常,间接造成空格丢失。

排查与解决步骤

  1. 验证文件实际字符:用十六进制编辑器打开CSV文件,检查2 10 C位置的字符:
    • 普通半角空格的十六进制值是20,如果是C2 A0则对应非断空格,这就是问题根源。
  2. 统一替换空白字符:在读取文件后,将所有非标准空白字符替换为普通空格:
    global.fileinput = filefevcsv.readTextSync(loadError, encoding.UTF_8).replace(/\s+/g, ' ');
    
    或针对性替换非断空格:
    global.fileinput = filefevcsv.readTextSync(loadError, encoding.UTF_8).replace(/\u00A0/g, ' ');
    
  3. 优化换行分割逻辑:改用兼容\n和\r\n的分割方式,避免行尾残留字符影响解析:
    let fileInput = global.fileinput.split(/\r?\n/);
    
  4. 使用专业CSV库:自定义的getToken函数无法处理复杂CSV场景,推荐用成熟库(如papaparse,兼容NativeScript),它能自动处理各种边缘字符和格式问题。

内容的提问来源于stack exchange,提问作者BenoitB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 22:31:59