读取,操作和编写文本文件C#

时间:2015-11-16 16:12:49

标签: c# .net file io

我需要将任何平面分隔文件转换为管道分隔格式。我将此控制台应用程序编写为POC,但它尝试编写的第二个文件将包含第一个文件中的所有文本。有什么建议吗?

        string sourceDir = @"c:\temp\";
        string targetDir = @"c:\dest\";

        List<string> listLines = new List<string>();

        string[] files = Directory.GetFiles(sourceDir);

        foreach(string file in files)
        {
            using (StreamReader sr = new StreamReader(sourceDir + Path.GetFileName(file)))
            {
                do
                {
                    listLines.Add(sr.ReadLine());
                } while (!sr.EndOfStream);

                for (int i = 0; i < listLines.Count; i++)
                {
                    listLines[i] = listLines[i].Replace(',', '|');
                    listLines[i] = listLines[i].Replace('\t', '|');                        
                }                                         
            }

            using (StreamWriter sw = new StreamWriter(targetDir + Path.GetFileName(file)))
            {
                foreach (string line in listLines)
                {
                    sw.WriteLine(line);
                }           
            }
        }

3 个答案:

答案 0 :(得分:1)

  

您正在向listLines添加行,并且在foreach迭代后从不清除列表。

@Jonathan Carroll

除此之外,您可以改进代码:

string sourceDir = @"c:\temp\";
string targetDir = @"c:\dest\";

List<string> listLines = new List<string>();

string[] files = Directory.GetFiles(sourceDir);

foreach (string file in files)
{
    using (StreamReader sr = new StreamReader(sourceDir + Path.GetFileName(file)))
    using (StreamWriter sw = new StreamWriter(targetDir + Path.GetFileName(file)))
    {
        do
        {
            var line = sr.ReadLine();

            line = line.Replace(',', '|').Replace('\t', '|');

            sw.WriteLine(line);

        } while (!sr.EndOfStream);
    }
}

答案 1 :(得分:1)

您需要将listLines的实例化移动到foreach中,或者在循环结束时重新初始化列表。

    string sourceDir = @"c:\temp\";
    string targetDir = @"c:\dest\";

    string[] files = Directory.GetFiles(sourceDir);

    foreach(string file in files)
    {
        List<string> listLines = new List<string>();
        using (StreamReader sr = new StreamReader(sourceDir + Path.GetFileName(file)))
        {
            do
            {
                listLines.Add(sr.ReadLine());
            } while (!sr.EndOfStream);

            for (int i = 0; i < listLines.Count; i++)
            {
                listLines[i] = listLines[i].Replace(',', '|');
                listLines[i] = listLines[i].Replace('\t', '|');                        
            }                                         
        }

        using (StreamWriter sw = new StreamWriter(targetDir + Path.GetFileName(file)))
        {
            foreach (string line in listLines)
            {
                sw.WriteLine(line);
            }           
        }
    }

答案 2 :(得分:0)

我认为其他答案相当清楚,但我想我会使用LINQ和Regex投入一个简短的替代解决方案:

foreach (var file in Directory.GetFiles(sourceDir).Select(x => Path.GetFileName(x)))
    File.WriteAllText(targetDir + file, new Regex("[,\t]").Replace(File.ReadAllText(sourceDir + file), "|"));

LINQ select查询用于将完整路径转换为文件名 - 然后迭代此文件名集合。 正则表达式用于匹配从源文件中读取的所有“,”和“\ t”字符,并将其替换为“|”字符。然后将生成的字符串写入目标文件。