在 C# 中达到一定大小时创建 csv 文件

Create csv file when certain size reached in c#

我有一种从列表内容写入 csv 的方法。如果 csv 文件大小达到特定大小,如 5MB,我想创建一个新的 csv 文件,这样如果列表内容很大,它就不会变得太大。下面是我的代码,但它不起作用。我收到错误 "file is being used by another process"。看起来这不是创建新 csv 文件的正确方法。

    public static void WriteCSV<T>(IEnumerable<T> items, string path)
    {
        Type itemType = typeof(T);
        var props = itemType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                            .OrderBy(p => p.Name);
        int filenumber = 0;
        using (var writer = new StreamWriter(path))
        {
            writer.WriteLine(string.Join(", ", props.Select(p => p.Name)));

            foreach (var item in items)
            {
                writer.WriteLine(string.Join(", ", props.Select(p => p.GetValue(item, null))));
                if (writer.BaseStream.Length > 5120)
                {
                    writer.Close();
                    writer.Dispose();
                    filenumber++;
                   var writer2 = new StreamWriter(string.Format(path, filenumber), false);
                }
            }

        }
    }

你的问题有两个方面。

  1. 方法 string.Format(path, filenumber) 没有达到您的预期。它实际上需要一个格式字符串作为第一个参数,如 "value goes here {0}" 和一个变量来代替 {0}。因为你只给它一个路径,它会 return 只是路径,它与你以前的文件同名。因此你得到了错误,因为你试图再次访问同一个文件。

1 的解决方案):

1.1) 你需要把路径分成路径和文件名,

1.2) 然后取不带扩展名的文件名,

1.3) 然后将数字连接到文件名

1.4)重构路径

问题 2)

对集合的迭代不应在作者的 using 块内。它甚至不取决于作者。这使得您不可能在每次不指定新实例的情况下使用另一个编写器。这会使代码变得丑陋和不必要的复杂。

删除 using 块并像您已经做的那样手动处理 writer: 这是一个可以解决问题的示例程序。

void Main()
{
    string path = @"C:\WorkSpace\temp\test\fileName.csv";


    List<string> items = Enumerable.Range(1, 1200).Select(x => $"Something: {x} else {x+2} ").ToList();

    int filenumber = 0;
    var writer = new StreamWriter(path);
    string pathOnly = Path.GetDirectoryName(path);
    string fileName = Path.GetFileNameWithoutExtension(path);
    string extension = Path.GetExtension(path);


    foreach (var item in items)
    {
        writer.WriteLine(string.Join(", ", item.Split(' ')));
        if (writer.BaseStream.Length > 120)
        {
            writer.Close();
            writer.Dispose();
            filenumber++;
            writer = new StreamWriter(Path.Combine(pathOnly, $"{fileName}{filenumber}{extension}"), false);
        }
    }

    // don't forget to close and dispose the last instance of the writer
    writer.Close();
    writer.Dispose();
}