【问题标题】:Why does File.WriteAllText() format my numbers by adding commas?为什么 File.WriteAllText() 会通过添加逗号来格式化我的数字?
【发布时间】:2013-11-12 19:41:17
【问题描述】:

我不明白为什么会发生这种情况,但确实如此。我正在写一个这样的csv文件:

foreach (var row in record.rows)
{
    csv += "\n";
    csv += row.FooName + ",";
    csv += row.FooMoney + ",";
}

System.IO.File.WriteAllText(filePath + fileName, csv);

这就是有趣的地方。调试时,row.FooMoney(十进制类型)可能是 10000。在书面 csv 中,它是 10,000,我自然不希望逗号是我的分隔符。

我试过 row.FooMoney.ToString("F"/"G") 无济于事......它似乎在文件写入期间被格式化。是什么赋予了?这是故意的吗?

更新


这是与问题相关的所有代码:

public ActionResult PassJSON(string __obj)
{
    var filePath = Url.Content("~/Temp/");
    var fileName = "Report.csv";

    try
    {
        string csv = string.Empty;
        var records = JsonConvert.DeserializeObject<List<RootReportObject>>(__obj);
        csv += "Date Created,Ref #,Name,Vehicle #,Address,ProductID,Product,Weight1,Weight2,";

        foreach (var record in records)
        {
            var count = record.count;
            var value = record.title;

            csv += "\n" + value + ",,,,,,,,,";

            foreach (var row in record.rows)
            {
                csv += "\n";
                csv += row.DateCreated + ",";
                csv += row.RefNo + ",";
                csv += row.Name + ",";
                csv += row.VehicleNo + ",";
                csv += row.Address1 + ",";
                csv += row.ProductID + ",";
                csv += row.Product + ",";
                csv += row.Weight1.ToString(CultureInfo.InvariantCulture) + ",";
                csv += row.Weight2.ToString(CultureInfo.InvariantCulture) + ",";
            }
        }

        System.IO.File.WriteAllText(filePath + fileName, csv);

        return Json(filePath + fileName, JsonRequestBehavior.AllowGet);
    }
    catch (Exception e)
    {
        return Json(e, JsonRequestBehavior.AllowGet);
    }
}

[Serializable]
public class Row
{
    public int id { get; set; }
    public DateTime DateCreated { get; set; }
    public int RefNo { get; set; }
    public string Name { get; set; }
    public string VehicleNo { get; set; }
    public string Address1 { get; set; }
    public int? ProductID { get; set; }
    public string Product { get; set; }
    public Decimal Weight1 { get; set; }
    public Decimal Weight2 { get; set; }
}

[Serializable]
public class RootReportObject
{
    public bool __group { get; set; }
    public int level { get; set; }
    public int count { get; set; }
    public string value { get; set; }
    public string title { get; set; }
    public int collapsed { get; set; }
    public List<Row> rows { get; set; }
    public object groups { get; set; }
    public string groupingKey { get; set; }
}

样本输出

8/16/2013 2:31:16 PM,72,John Doe,LP1234,9021 Beverly Hills Blvd,427,Corn,0,50,
8/16/2013 2:31:34 PM,73,John Doe,LP1234,9021 Beverly Hills Blvd,427,Corn,5,000,0,
8/16/2013 2:32:12 PM,74,John Doe,LP1234,9021 Beverly Hills Blvd,427,Corn,0,50,
8/16/2013 2:33:15 PM,75,John Doe,LP1234,9021 Beverly Hills Blvd,427,Corn,0,50,
8/16/2013 2:50:58 PM,76,John Doe,LP1234,9021 Beverly Hills Blvd,427,Corn,0,50,
8/20/2013 7:19:32 PM,77,John Doe,LP1234,9021 Beverly Hills Blvd,427,Corn,0,50,
8/20/2013 7:46:03 PM,78,John Doe,LP1234,9021 Beverly Hills Blvd,427,Corn,0,40,
8/20/2013 7:55:56 PM,79,John Doe,LP1234,9021 Beverly Hills Blvd,427,Corn,0,1,
8/20/2013 8:13:58 PM,80,John Doe,,9021 Beverly Hills Blvd,427,Corn,0,50,
8/21/2013 8:05:25 PM,81,John Doe,LP1234,9021 Beverly Hills Blvd,427,Corn,0,5,
8/22/2013 7:33:03 PM,82,John Doe,LP1234,9021 Beverly Hills Blvd,427,Corn,0,50,
8/22/2013 7:40:42 PM,83,John Doe,LP1234,9021 Beverly Hills Blvd,427,Corn,0,5,
8/22/2013 8:05:25 PM,84,John Doe,LP1234,9021 Beverly Hills Blvd,427,Corn,0,5,000,

更新 #2


我删除了原始的 report.csv,发现下一次编写报告的调用从 IIS 产生了 404 错误。显然 WriteAllText() 不再写了。不幸的是,我也不知道该怎么做。我已经更改了代码,试图在写入发生之前删除任何以前的版本,但仍然一无所获

修改后的代码

if (System.IO.File.Exists(filePath + fileName))
  System.IO.File.Delete(filePath + fileName);

System.IO.File.WriteAllText(filePath + fileName, csv);
return Json(filePath + fileName, JsonRequestBehavior.AllowGet);

【问题讨论】:

  • @tnw "FooMoney(十进制类型)"
  • 自定义对象的属性。这是一个小数。
  • 不妨看看这个问题:stackoverflow.com/questions/17810211/…
  • 我怀疑WriteAllText 是罪魁祸首。如果您只是将其打印到屏幕上或在调试器中检查它,csv 会是什么样子?
  • @MikeHometchko 那么你的问题在这里有问题。如果csv 变量的值没有逗号,并且您将该值直接写入文件,那么您的文件将没有这些逗号。 WriteAllText 方法绝对没有在其中注入逗号。

标签: c# csv file-io


【解决方案1】:

使用row.FooMoney.ToString("f") 应该可以防止写入千位分隔符。

如果您使用的是覆盖默认行为的奇怪文化设置,您可以通过row.FooMoney.ToString("f", CultureInfo.InvariantCulture) 强制执行此操作。

请注意,如果您使用的是 .NET 4 或更高版本,您可以通过以下方式提高效率:

System.IO.File.WriteAllLines(System.IO.Path.Combine(filePath, fileName),
   record.Rows.Select(row => row.FooName + "," + row.FooMoney.ToString("f")));

【讨论】:

  • 请注意,CultureInfo.InvariantCulture 还会更改格式的其他方面。可能非常重要的是它强制 . 作为小数分隔符,而不是 ,,这可能是 OP 无论如何都想要的。
  • 我很欣赏您的回复,但不幸的是这不是文化设置。不过,我会在那里查看优化后的 WriteAllLines,感谢您的建议!
  • @MikeHometchko WriteAllText 只是写一个字符串,所以那里没有发生任何转换......
  • @ReedCopsey 你会这么想,不是吗?我现在找不到任何其他合乎逻辑的解释......我不知疲倦地运行我的代码,好像它是“如何不编程......”书中的一个问题。
  • @MikeHometchko 你试过csv += row.FooMoney.ToString("f", CultureInfo.InvariantCulture);了吗?
【解决方案2】:

您的 filePath 变量将包含相对于您的 Web 应用程序的路径,而不是相对于您的文件系统的路径。 WriteAllText 需要文件系统上的路径。

要获取物理路径,您可以执行Server.MapPath("~/Temp"),这将返回c:\websites\mysite\Temp 或其他任何内容。从那里,您应该使用Path.Combine(filePath, fileName) 获取您的完整文件路径并将文件保存到该位置。

【讨论】:

  • 很好,感谢您的帮助...它现在在本地完美运行...但在我的实时测试台上抛出 500 错误。我认为这与路径/路由有关。有什么想法吗?
  • 500 应该会登录到您机器的事件查看器中。我的猜测是 IIS 用户帐户无权在文件系统中的该目录上写入。您需要为适当的用户添加文件系统权限(取决于您如何设置 IIS,您需要确定它是哪个用户)。
  • 实际上是我原来的问题导致了这个问题,如果你愿意,可以看看更多绿色检查的机会:P stackoverflow.com/questions/19935331/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-04-19
  • 2017-01-14
  • 1970-01-01
  • 2014-05-31
  • 2020-12-18
  • 2017-12-09
  • 2011-11-08
相关资源
最近更新 更多