¿Cuál es la mejor manera de crear un archivo de ancho fijo en C#. Tengo un montón de campos con longitudes para escribir. Digamos 20,80.10,2 etc. todos alineados a la izquierda. ¿Hay una forma fácil de hacer esto?Creación de un archivo de ancho fijo en C#
Respuesta
Usted puede utilizar fácilmente string.Format a la almohadilla un valor con espacios por ejemplo,
string a = String.Format("|{0,5}|{1,5}|{2,5}", 1, 20, 300);
string b = String.Format("|{0,-5}|{1,-5}|{2,-5}", 1, 20, 300);
// 'a' will be equal to "| 1| 20| 300|"
// 'b' will be equal to "|1 |20 |300 |"
¿No puedes usar el archivo de texto estándar? Puede leer los datos línea por línea.
No necesariamente, el archivo de texto no puede ser leído por otra aplicación # C, pero una trama principal que necesita un archivo de texto con formato concreto. –
uso String.Format()
Trate de usar myString.PadRight (totalLengthForField, ' ')
Puede utilizar un StreamWriter y en la escritura (cadena) el uso de llamadas de cadena. Format() para crear una cadena que tenga el ancho correcto para el campo dado.
Utilice la función .PadRight (para datos alineados a la izquierda) de la clase String. Entonces:
handle.WriteLine(s20.PadRight(20));
handle.WriteLine(s80.PadRight(80));
handle.WriteLine(s10.PadRight(10));
handle.WriteLine(s2.PadRight(2));
¿Quiere decir que quiere rellenar todos los números a la derecha con espacios?
Si es así, String.PadRight o String.Format debería ponerlo en marcha.
Puede usar ASCIIEncoding.UTF8.GetBytes (texto) para convertirlo a una matriz de bytes. Luego escriba las matrices de bytes en el archivo como un registro de tamaño fijo.
UTF8 varía en el número de bytes necesarios para representar algunos caracteres, UTF16 es un poco más predecible, 2 bytes por carácter.
Puede utilizar http://www.filehelpers.com/
FileHelpers Proveedores: www.filehelpers.com
He aquí un ejemplo: http://www.filehelpers.com/quick_start_fixed.html
Los diversos relleno/mensajes de formato antes funcionarán suficientemente, pero que pueden estar interesados en la aplicación de ISerializable.
He aquí un artículo de MSDN sobre Object Serialization in .NET
Este es un sistema que hice para un módulo de escritura del mismo ancho fijo configurable. Está configurado con un archivo XML, la parte pertinente buscando de esta manera:
<WriteFixedWidth Table="orders" StartAt="1" Output="Return">
<Position Start="1" Length="17" Name="Unique Identifier"/>
<Position Start="18" Length="3" Name="Error Flag"/>
<Position Start="21" Length="16" Name="Account Number" Justification="right"/>
<Position Start="37" Length="8" Name="Member Number"/>
<Position Start="45" Length="4" Name="Product"/>
<Position Start="49" Length="3" Name="Paytype"/>
<Position Start="52" Length="9" Name="Transit Routing Number"/>
</WriteFixedWidth>
StartAt le indica al programa si sus posiciones son base 0 o 1-basados. Lo hice configurable porque estaría copiando las compensaciones de las especificaciones y quería que la configuración se asemejara a la especificación tanto como fuera posible, independientemente del índice inicial que eligiera el autor.
El atributo Nombre en las etiquetas de Posición se refiere a los nombres de las columnas en una DataTable.
El siguiente código fue escrito para .Net 3.5, usando LINQ-to-XML, por lo que el método asumió que pasaría un XElement con la configuración anterior, que puede obtener después de usar XDocument.Load(filename)
para cargar el archivo XML, luego llame al .Descendants("WriteFixedWidth")
en el objeto XDocument
para obtener la configuración elemento.
public void WriteFixedWidth(System.Xml.Linq.XElement CommandNode, DataTable Table, Stream outputStream)
{
StreamWriter Output = new StreamWriter(outputStream);
int StartAt = CommandNode.Attribute("StartAt") != null ? int.Parse(CommandNode.Attribute("StartAt").Value) : 0;
var positions = from c in CommandNode.Descendants(Namespaces.Integration + "Position")
orderby int.Parse(c.Attribute("Start").Value) ascending
select new
{
Name = c.Attribute("Name").Value,
Start = int.Parse(c.Attribute("Start").Value) - StartAt,
Length = int.Parse(c.Attribute("Length").Value),
Justification = c.Attribute("Justification") != null ? c.Attribute("Justification").Value.ToLower() : "left"
};
int lineLength = positions.Last().Start + positions.Last().Length;
foreach (DataRow row in Table.Rows)
{
StringBuilder line = new StringBuilder(lineLength);
foreach (var p in positions)
line.Insert(p.Start,
p.Justification == "left" ? (row.Field<string>(p.Name) ?? "").PadRight(p.Length,' ')
: (row.Field<string>(p.Name) ?? "").PadLeft(p.Length,' ')
);
Output.WriteLine(line.ToString());
}
Output.Flush();
}
El motor es StringBuilder, que es más rápido que la concatenación de cadenas inmutables juntos, especialmente si se está procesando archivos de varios megabytes.
Solo tengo que decir que esta es una idea brillante, ¡me encanta! +1 – Mohgeroth
No puedo hacer referencia a 'Namespaces.Integration'. ¿Puede proporcionar más detalles al respecto? – vikas
Vikas, puede encontrar más información aquí, https://msdn.microsoft.com/en-us/library/bb353813(v=vs.110).aspx. Si su documento XML usa un espacio de nombre, entonces es cuando se utiliza Namespaces.Integration. – CodingSerge
estoy usando un método de extensión de cadena, si el XML comentando puede parecer exagerado para esto, pero si quiere que otros desarrolladores reutilizar ...
public static class StringExtensions
{
/// <summary>
/// FixedWidth string extension method. Trims spaces, then pads right.
/// </summary>
/// <param name="self">extension method target</param>
/// <param name="totalLength">The length of the string to return (including 'spaceOnRight')</param>
/// <param name="spaceOnRight">The number of spaces required to the right of the content.</param>
/// <returns>a new string</returns>
/// <example>
/// This example calls the extension method 3 times to construct a string with 3 fixed width fields of 20 characters,
/// 2 of which are reserved for empty spacing on the right side.
/// <code>
///const int colWidth = 20;
///const int spaceRight = 2;
///string headerLine = string.Format(
/// "{0}{1}{2}",
/// "Title".FixedWidth(colWidth, spaceRight),
/// "Quantity".FixedWidth(colWidth, spaceRight),
/// "Total".FixedWidth(colWidth, spaceRight));
/// </code>
/// </example>
public static string FixedWidth(this string self, int totalLength, int spaceOnRight)
{
if (totalLength < spaceOnRight) spaceOnRight = 1; // handle silly use.
string s = self.Trim();
if (s.Length > (totalLength - spaceOnRight))
{
s = s.Substring(0, totalLength - spaceOnRight);
}
return s.PadRight(totalLength);
}
}
... y usted puede usar material .NET FileStream estándar para escribir un archivo, por supuesto. – Darren
respuesta de Darren a esta pregunta ha inspirado usar métodos de extensión, pero en lugar de extender String
, extendí StringBuilder
. Escribí dos métodos:
public static StringBuilder AppendFixed(this StringBuilder sb, int length, string value)
{
if (String.IsNullOrWhiteSpace(value))
return sb.Append(String.Empty.PadLeft(length));
if (value.Length <= length)
return sb.Append(value.PadLeft(length));
else
return sb.Append(value.Substring(0, length));
}
public static StringBuilder AppendFixed(this StringBuilder sb, int length, string value, out string rest)
{
rest = String.Empty;
if (String.IsNullOrWhiteSpace(value))
return sb.AppendFixed(length, value);
if (value.Length > length)
rest = value.Substring(length);
return sb.AppendFixed(length, value);
}
El primero silenciosamente ignora cadena demasiado tiempo y simplemente corta el final de la misma, y el segundo vuelve cortó parte a través out
parámetro del método.
Ejemplo:
string rest;
StringBuilder clientRecord = new StringBuilder();
clientRecord.AppendFixed(40, doc.ClientName, out rest);
clientRecord.AppendFixed(40, rest);
clientRecord.AppendFixed(40, doc.ClientAddress, out rest);
clientRecord.AppendFixed(40, rest);
- 1. Enteros de ancho fijo en C++
- 2. Escribiendo/analizando un archivo de ancho fijo usando Python
- 3. archivos Parse de ancho fijo
- 4. de ancho fijo, espacio delimitado archivo .txt en MySQL
- 5. CSS ancho fijo en un lapso
- 6. Campos de ancho fijo de inserción masiva
- 7. Ancho de trazo fijo en SVG
- 8. Android: fuente de ancho fijo en AlertDialog
- 9. Determine el ancho de un ancho DIV dinámico Multivolpea de DIV 3 ancho de columna fijo
- 10. Crear un botón de ancho fijo en CSS
- 11. ¿Cómo importar un archivo plano de ancho fijo en la base de datos utilizando SSIS?
- 12. CSS - ancho fijo SPAN/div
- 13. ¿Cómo agregar un div de ancho fijo al lado de un div de ancho automático?
- 14. Mantener el ancho de la tabla fijo
- 15. Creación de un archivo .MSG de Outlook en C#
- 16. Fuentes con verdadero ancho fijo en WPF
- 17. Diseñar un diseño de tabla columnas de ancho fijo y fijo + colspan
- 18. ¿Mantiene el ancho fijo del panel de un contenedor dividido?
- 19. ¿Por qué no es un patrón de ancho fijo?
- 20. Como llegar a la altura NSAttributedString a un ancho fijo
- 21. Ancho de columna fijo en la tabla HTML
- 22. Bootstrap: ancho de canal fijo en el diseño de fluido?
- 23. Dos columnas, izquierda con ancho fijo, derecha con ancho dinámico
- 24. En Android, ¿cómo crear EditText de ancho fijo?
- 25. UILabel con ancho fijo y altura flexible
- 26. dividir una cadena en subcadenas de ancho fijo
- 27. WPF Vista en árbol con columnas de ancho fijo
- 28. Imagemagick: Convertir a ancho fijo, altura proporcional
- 29. ¿Es más rápido leer columnas de ancho fijo en SQLite?
- 30. Tamaño de cadena fijo en C#
Sin embargo, hay una advertencia: si los datos son más largos que el ancho especificado, no se truncarán. Por lo tanto, deberá usar data.Substring (0, width) en cualquier campo potencialmente más largo que el ancho, que se vuelve rápido (y repetitivo/no SECO). – brianary
Solo estoy siendo lento, ya que me lo perdí, pero si el resultado se muestra, entonces la fuente necesita ser de ancho fijo también – ScruffyDuck