2011-10-06 36 views
3

想知道如果你有更好的建议,我已经想出了。写入文件和格式化行。需要的结果

我有要求以特定格式编写文本文件 每个字段必须从所述位置开始,并且必须用空格填充,直到下一个字段。

例子:

 Field   Position in the row 
     Name    1 
     Surname   20 
     Address   50 
     Country   90 
     DOB    120 
     MaritalStatus 160 

下面是我的原型的尝试,有没有这样做的一个整洁的更好的办法? 需要在单元测试中测试行中的位置是否正确?

有什么建议吗?

   class Program 
       { 
        static void Main(string[] args) 
        { 
         Customer customer=new Customer(); 
         customer.Name = "Jo"; 
         customer.Surname = "Bloggs"; 
         customer.Address = " 1 NewYork Road"; 
         customer.Country = "UK"; 
         customer.DOB = "29/04/1990"; 
         customer.MaritalStatus = "Married"; 

         StringBuilder sb=new StringBuilder(); 
         CreateHeader(customer,sb); 
         sb.AppendLine(""); 
         CreateRow(customer, sb); 
         sb.AppendLine(""); 

         IOExtensions.WriteToFile(sb.ToString(), "TestFile.txt"); 

        } 

        private static void CreateHeader(Customer customer,StringBuilder sb) 
        { 
         /* 
          * 
          Field   Position in the row 
          Name    1  
          Surname   20 
          Address   50 
          Country   90 
          DOB    120 
          MaritalStatus 160 

          */ 
         //First Field 
         sb.Append(FormatValue("Name", 19)); 
         sb.Append(FormatValue("Surname", 29)); 
         sb.Append(FormatValue("Address", 39)); 
         sb.Append(FormatValue("Country", 29)); 
         sb.Append(FormatValue("DOB", 39)); 

         //Last field does not matter 
         sb.Append(FormatValue("MaritalStatus", 9)); 


        } 
        private static void CreateRow(Customer customer, StringBuilder sb) 
        { 
         /* 
          * 
          Field   Position in the row 
          Name   1 
          Surname   20 
          Address   50 
          Country   90 
          DOB    120 
          MaritalStatus 160 

          */ 
         //First Field 
         sb.Append(FormatValue(customer.Name, 19)); 
         sb.Append(FormatValue(customer.Surname, 29)); 
         sb.Append(FormatValue(customer.Address, 39)); 
         sb.Append(FormatValue(customer.Country, 29)); 
         sb.Append(FormatValue(customer.DOB, 39)); 

         //Last field does not matter 
         sb.Append(FormatValue(customer.MaritalStatus, 19)); 


        } 

        private static string FormatValue(string value, int maxLength) 
        { 
         //TODO ADD OTHER STUFF HERE 
         return value.PadRight(maxLength, ' '); 
        } 
       } 

       public static class IOExtensions 
       { 
        public static void WriteToFile(string text, string path) 
        { 
         using (var fs = File.CreateText(path)) 
         { 
          fs.Write(text); 
         } 
        } 
       } 
       public class Customer 
       { 
        public string Name { get; set; } 
        public string Surname { get; set; } 
        public string Address { get; set; } 
        public string Country { get; set; } 
        public string DOB { get; set; } 
        public string MaritalStatus { get; set; } 
       } 
      } 
+2

这种问题可能更适合http://codereview.stackexchange.com – StriplingWarrior

+1

你可以使用FileHelpers http://www.filehelpers.com/default.html – kd7

回答

2

我一直这样做,这是我的建议....带上你的课并重写“ToString”函数或创建一个名为别的自定义函数。使用“PadRight”字符串函数可以使用正确的填充来创建固定长度的字段。

例(你需要添加字段到的ToString的其余部分):

  public class Customer 
      { 
       public string Name { get; set; } 
       public string Surname { get; set; } 
       public string Address { get; set; } 
       public string Country { get; set; } 
       public string DOB { get; set; } 
       public string MaritalStatus { get; set; } 

       public override string ToString() 
       { 
        return String.Format("{0}{1}{2}", 
         Name.PadRight(20), 
         Surname.PadRight(30), 
         Address.PadRight(40) 
         ); 
       } 
      } 

注:我们正在使用的长度来控制每个字段的起始位置。如果第一个字段是20个字符,那么下一个字段将从21开始,并达到您定义的长度。

现在,遍历数据并填充对象并调用customer.ToString()写出格式化的字符串。

+0

。就像你的建议,我打算重写字符串,但不知道如何在需要的位置将字符串连接到一起 – user9969

+0

PadRight()使它成为一个固定宽度的字段,所以你只需将每个字段的长度和下一个字段将在下一个位置开始。例如,姓名= 20字符和姓氏= 30,那么你做Name.PadRight(20),SurnamePadRight(30)。 – Zachary

0

建议:

  • 客户对象未在使用“CreateHeader()”方法 - 将其删除
  • 考虑重构的将writeToFile()来处理的情况下,你会发现自己通过迭代Customer对象的列表或数组。将分开写每个客户对象,而不是通过一个大字符串
+0

谢谢你的建议。只需要找到一个方法来写一个字符串到一个特定的位置,如问题所述。任何建议 – user9969

+0

@ user231465我赞成Zachary的回答。您可能会发现它符合您的需求。 – Arun

0

它看起来像FileHelpers图书馆会很好地做的伎俩。我已经将它用于CSV文件,但它似乎也处理固定宽度的文件。

+0

嗨,不能使用第三方库 – user9969

1

如果您知道每列的宽度,您可以使用String.Format来格式化该行。例如:

string s = String.Format("{0,-19}{1,-29}", customer.Name, customer.Surname); 
sb.AppendLine(string); 

当然,您的线条会稍长些。但是你可以在一个电话中完成所有事情。

负对齐值给出左对齐。正值可以在现场正确对齐。您可以使用StringBuilder.AppendFormat

请参阅Composite Formatting了解有关使用这两种方法之一进行格式设置的更多信息。

这里唯一的缺点是如果你想放在字段中的值比字段宽度长。如文档所述:

如果对齐值小于格式化字符串的长度,则忽略对齐,并将格式化字符串的长度用作字段宽度。

+0

。我想知道是否有一种方法来写只有例如“20”和该字符串写在位置20.而不是我的价值观。我有很长的名单,每列的定位。让我明白这个“{0,-19} {1,-29}”,将从30等开始在“0-19”秒之间写第一个字符串。问题是我将不得不计算很多。 – user9969

+0

@ user231465:这些值是字段的宽度,而不是起始位置。所以在你的例子中,前两个实际上是'{0,-20} {1,-30}'。是的,你必须从偏移量计算字段宽度。这不应该证明困难。 –