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

如何合并目录中所有CSV文件为单个CSV?遇文件占用错误求解决

解决F#合并CSV时的文件占用错误

问题根源

  • 若之前运行过代码生成了mergedCsvFile.csv,Directory.GetFiles会把这个文件也纳入待处理列表,导致程序尝试读取正在写入的文件,直接触发占用冲突。
  • 所有文件流(输入、输出)未用use绑定,无法自动释放资源,即便没有上述问题,也可能因流未关闭引发后续报错。

修正后代码(带表头处理,避免重复表头)

open System.IO

let path = @"C:\Users\james\Desktop\Name\"
let outputFileName = "mergedCsvFile.csv"
let outputPath = Path.Combine(path, outputFileName)

// 过滤掉输出文件,避免读取正在写入的文件
let csvFiles = 
    Directory.GetFiles(path, "*.csv", SearchOption.TopDirectoryOnly)
    |> Array.filter (fun f -> Path.GetFileName(f) <> outputFileName)

// 用use绑定流,确保作用域结束后自动释放资源
use outputStream = File.Create(outputPath)
use outputWriter = new StreamWriter(outputStream)

// 处理第一个文件,保留表头
if csvFiles.Length > 0 then
    use firstFileStream = File.OpenRead(csvFiles.[0])
    use firstFileReader = new StreamReader(firstFileStream)
    outputWriter.WriteLine(firstFileReader.ReadToEnd())

// 处理剩余文件,跳过表头
for file in csvFiles.[1..] do
    use fileStream = File.OpenRead(file)
    use fileReader = new StreamReader(fileStream)
    fileReader.ReadLine() |> ignore // 跳过第一行表头
    outputWriter.WriteLine(fileReader.ReadToEnd())

outputWriter.Flush() // 确保所有内容写入文件

简化版(无需处理表头,直接全量复制)

open System.IO

let path = @"C:\Users\james\Desktop\Name\"
let outputFileName = "mergedCsvFile.csv"
let outputPath = Path.Combine(path, outputFileName)

let csvFiles = 
    Directory.GetFiles(path, "*.csv", SearchOption.TopDirectoryOnly)
    |> Array.filter (fun f -> Path.GetFileName(f) <> outputFileName)

use outputStream = File.Create(outputPath)
for file in csvFiles do
    use inputStream = File.OpenRead(file)
    inputStream.CopyTo(outputStream)

注意事项

  • 若目录已存在mergedCsvFile.csv,File.Create会直接覆盖该文件。
  • 若CSV文件编码不一致,可在StreamReader/StreamWriter构造函数中指定编码(如Encoding.UTF8)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 20:55:16