如何合并目录中所有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
相关产品推荐
相关产品推荐

