[英]Node.js: difference in file size when copying csv
我有以下代碼,我從 CSV 讀取並寫入另一個 CSV。 在寫入另一個文件之前,我將轉換一些數據,但作為測試,我運行了代碼,發現源文件和目標文件之間存在細微差別,而沒有事件更改文件的任何內容。
for(const m of metadata) {
tempm = m;
fname = path;
const pipelineAsync = promisify(pipeline);
if(m.path) {
await pipelineAsync(
fs.createReadStream(m.path),
csv.parse({delimiter: '\t', columns: true}),
csv.transform((input) => {
return Object.assign({}, input);
}),
csv.stringify({header: true, delimiter: '\t'}),
fs.createWriteStream(fname, {encoding: 'utf16le'})
)
let nstats = fs.statSync(fname);
tempm['transformedPath'] = fname;
tempm['transformed'] = true;
tempm['t_size_bytes'] = nstats.size;
}
}
例如,我看到,
file a: the source file size is `895631` while after copying destination file size is `898545`
file b: the source file size is `51388` while after copying destination file size is `52161`
file c: the source file size is `13666` while after copying destination file size is `13587`
但是當我不使用轉換時,大小匹配,例如此代碼在源和目標上產生完全相同的文件大小
for(const m of metadata) {
tempm = m;
fname = path;
const pipelineAsync = promisify(pipeline);
if(m.path) {
await pipelineAsync(
fs.createReadStream(m.path),
/*csv.parse({delimiter: '\t', columns: true}),
csv.transform((input) => {
return Object.assign({}, input);
}),
csv.stringify({header: true, delimiter: '\t'}),*/
fs.createWriteStream(fname, {encoding: 'utf16le'})
)
let nstats = fs.statSync(fname);
tempm['transformedPath'] = fname;
tempm['transformed'] = true;
tempm['t_size_bytes'] = nstats.size;
}
}
任何人都可以幫助確定我需要將哪些選項傳遞給 csv 轉換,以便正確進行復制。
我正在做這個測試以確保我不會丟失大文件中的任何數據。
謝謝。
更新 1:我還檢查了兩個文件的編碼是否相同。
更新 2:我注意到源文件有CRLF
和目標文件有LF
。 有沒有辦法我可以使用 node.js 保持相同,或者它是否依賴於OS
。
更新 3:看起來問題是EOL
,我看到源文件有CRLF
而目標文件/轉換后的文件有LF
。 我現在需要找到一種方法來指定我上面的代碼,以便EOL
是一致的
您需要設置 EOL 配置:
const { pipeline } = require('stream')
const { promisify } = require('util')
const fs = require('fs')
const csv = require('csv')
const os = require('os')
;(async function () {
const pipelineAsync = promisify(pipeline)
await pipelineAsync(
fs.createReadStream('out'),
csv.parse({ delimiter: ',', columns: true }),
csv.transform((input) => {
return Object.assign({}, input)
}),
// Here the trick:
csv.stringify({ eol: true, record_delimiter: os.EOL, header: true, delimiter: '\t' }),
fs.createWriteStream('out2', { encoding: 'utf16le' })
)
})()
您也可以使用\r\n
或任何您需要$-new-line\n
閱讀源代碼可以發現此設置。
這種差異的兩個主要來源是:
使用簡單的 unix file
命令行實用程序,您可以檢查源文件的編碼和 EOL 樣式。 確保對 dest 文件使用相同的選項,任何差異都應該消失。
希望這可以幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.