Node.js通过SSH读取SFTP的CSV文件转JSON出现乱码如何解决
你遇到的\x00开头的乱码是文件编码不匹配导致的,你读取到的Buffer默认用UTF-8解码,但你的CSV文件实际是UTF-16编码(多为Windows平台生成的文件),才会出现每个字符前带\x00的情况。
代码修改点
- 解码时指定正确编码
调用toString()时传入对应编码即可,常见的UTF-16小端编码传入utf16le即可解决乱码问题。如果是其他编码可以引入iconv-lite包做更灵活的编码转换。 - 优化csvtojson的异步处理逻辑
你当前标注// parse each json asynchronously的位置的Promise是空实现,没有实际作用。如果不需要逐行异步处理数据,直接调用then即可一次性拿到转换完成的全量JSON数组;如果需要逐行异步处理,把你的业务逻辑写入Promise内部,处理完成后再调用resolve即可。
修正后完整代码
let Client = require('ssh2-sftp-client'); let sftp = new Client(); var csv = require("csvtojson"); sftp.connect({ host: 'HOST', port: 'PORT', username: 'USERNAME', password: 'PASSWORD' }).then(() => { return sftp.get('/home/user/etc/testfile.csv'); }).then((data) => { // 解决乱码:指定正确的文件编码 const csvContent = data.toString('utf16le'); // 不需要逐行处理的写法,直接拿全量JSON csv() .fromString(csvContent) .then((jsonArray) => { // 此处可直接处理全量JSON数据 console.log(jsonArray); }) // 如果需要逐行异步处理,用下面的写法替换上面的部分 /* csv() .fromString(csvContent) .subscribe((jsonObj) => { return new Promise((resolve, reject) => { // 此处写你的异步处理逻辑,比如写入数据库、调用接口等 // 处理完成后调用resolve,出错调用reject console.log(jsonObj); resolve(); }) }) */ }).catch((err) => { console.log(err, 'catch error'); });
如果上述编码指定后还有乱码,可以先打印data的前几个字节判断编码格式,比如开头是FF FE就是UTF-16LE,FE FF是UTF-16BE,对应调整编码参数即可。
内容的提问来源于stack exchange,提问作者Jim Dover
相关产品推荐
相关产品推荐

