Jaki jest najlepszy sposób utworzenia pliku o stałej szerokości w języku C#. Mam kilka pól o długości do wypisania. Powiedz 20,80.10,2 itd. Wszystkie wyrównane do lewej. Czy istnieje prosty sposób na zrobienie tego?Tworzenie pliku o stałej szerokości w języku C#
Odpowiedz
Można użyć string.Format na łatwe pad wartość ze spacjami np
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 |"
Nie możesz użyć standardowego pliku tekstowego? Możesz odczytywać linię danych po linii.
Niekoniecznie, plik tekstowy nie może być odczytany przez innego C# aplikacji, ale główną ramę, która potrzebuje specjalnie sformatowany plik tekstowy. –
użycie String.Format()
Spróbuj użyć myString.PadRight (totalLengthForField, ' „)
Można użyć StreamWriter oraz w Write (string) stosowanie połączeń String. Formatuj(), aby utworzyć ciąg o właściwej szerokości dla danego pola.
Użyj funkcji .PadRight (dla wyrównanych do lewej strony) klasy String. A więc:
handle.WriteLine(s20.PadRight(20));
handle.WriteLine(s80.PadRight(80));
handle.WriteLine(s10.PadRight(10));
handle.WriteLine(s2.PadRight(2));
Masz na myśli, że chcesz wstawić wszystkie liczby po prawej stronie, używając spacji?
Jeśli tak, to String.PadRight lub String.Format powinny Cię śledzić.
Można użyć ASCIIEncoding.UTF8.GetBytes (tekst), aby przekonwertować go na tablicę bajtów. Następnie wypisz tablice bajtów do pliku jako rekord o stałym rozmiarze.
UTF8 różni się liczbą bajtów wymaganych do przedstawienia niektórych znaków, UTF16 jest nieco bardziej przewidywalny, 2 bajty na znak.
Można użyć http://www.filehelpers.com/
spróbować FileHelpers: www.filehelpers.com
Oto przykład: http://www.filehelpers.com/quick_start_fixed.html
Różne napawające/posty formatowania przed zadziała wystarczająco mało, ale może być zainteresowany w realizacji ISerializable.
Oto artykuł MSDN o Object Serialization in .NET
Jest to system, zrobiłem dla konfigurowalnego modułu stałej szerokości zapisu plików. Jest skonfigurowany z pliku XML, odpowiednia część wygląda tak:
<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 informuje program, czy Twoje pozycje są oparte na 0 lub 1-na podstawie. Zrobiłem to konfigurowalnym, ponieważ kopiowałem z offsetu ze specyfikacji i chciałem, aby konfiguracja była jak najbardziej zbliżona do specyfikacji, bez względu na to, jaki indeks początkowy wybrał autor.
Atrybut Name na znacznikach Position odnosi się do nazw kolumn w DataTable.
Poniższy kod został napisany dla .Net 3.5, używając LINQ-do-XML, więc metoda zakładała, że zostanie przekazany XElement z powyższą konfiguracją, którą możesz uzyskać po użyciu XDocument.Load(filename)
w celu załadowania pliku XML, a następnie wywołania .Descendants("WriteFixedWidth")
na obiekcie XDocument
, aby uzyskać konfigurację element.
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();
}
Silnik jest StringBuilder, który jest szybszy niż złączenie niezmienne ciągi razem, zwłaszcza jeśli jesteś przetwarzania plików multi-megabajt.
Po prostu muszę powiedzieć, że to genialny pomysł, uwielbiam to! +1 – Mohgeroth
Nie mogę odwoływać się do 'Namespaces.Integration', czy możesz podać więcej szczegółów na ten temat. – vikas
Vikas, można znaleźć więcej informacji tutaj, https://msdn.microsoft.com/en-us/library/bb353813(v=vs.110).aspx. Jeśli twój dokument XML używa przestrzeni nazw, to wtedy używa się Namespaces.Integration. – CodingSerge
Używam metodę rozszerzenia na ciąg, tak XML komentowania może wydawać OTT za to, ale jeśli chcesz innych deweloperów do ponownego wykorzystania ...
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);
}
}
... i można użyć standardowych rzeczy .NET FileStream do napisania pliku oczywiście. – Darren
odpowiedź Darrena na to pytanie zainspirowało używać metod rozszerzeń, ale zamiast rozszerzać String
, rozszerzyłem StringBuilder
. Napisałem dwie metody:
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);
}
Pierwszy dyskretnie pomija zbyt długi łańcuch i po prostu odcina koniec, a drugi powraca odciąć część poprzez out
parametr metody.
Przykład:
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. Litery integerowe o stałej szerokości w C++?
- 2. Liczby zmiennoprzecinkowe o stałej szerokości w C/C++
- 3. Utrzymaj tabelę o stałej szerokości
- 4. Pandy: histogram o stałej szerokości
- 5. Android: czcionka o stałej szerokości w AlertDialog
- 6. Czy istnieje typ bool o stałej szerokości w standardowym C++?
- 7. Pandy Pythona, zapisz DataFrame do pliku o stałej szerokości (to_fwf?)
- 8. Tworzenie wektora o stałej długości
- 9. Którą czcionkę o stałej szerokości używa przeglądarka?
- 10. Jak pozostawić wyrównanie łańcucha o stałej szerokości?
- 11. Sprawdzanie, czy czcionka jest w języku Java w stałej szerokości.
- 12. Wymuszanie czcionki o stałej szerokości w stałej szerokości przy użyciu CSS
- 13. pliki Parse stałej szerokości
- 14. Importuj plik danych o stałej szerokości bez separatora linii
- 15. Jak odczytać plik tekstowy formatu o stałej szerokości w pandach?
- 16. Chmura tagów sortowania i pozycjonowania w div o stałej szerokości
- 17. Tworzenie pliku MSMS programu Outlook w języku C#
- 18. Czy iOS ma wbudowaną czcionkę o stałej szerokości?
- 19. Jak zawijać tekst przycisku html o stałej szerokości
- 20. Czytaj stałej szerokości plik tekstowy
- 21. Wyrównanie elementów za pomocą przestrzeni stałej (o zmiennej szerokości)
- 22. stałej szerokości zmiennoprzecinkowy format numeru
- 23. Jak mogę obliczyć liczbę linii UILabel o stałej szerokości?
- 24. Tabela HTML - tabela o szerokości 100%, kombinacja stałej szerokości i kolumn kolumn UNIFORM
- 25. procentowe szerokości DIV obserwowani przez stałej szerokości div
- 26. Tworzenie obiektu DateTime w języku C#Tworzenie kodu DataTime w języku C#
- 27. Tworzenie wątków kwadratowych (o równej wysokości i szerokości) w matplotlib
- 28. C/C++ Cel zmiennej lokalnej zmiennej stałej
- 29. Tworzenie klas dynamicznych w języku C#
- 30. Tworzenie tablicy JSON w języku C#
Jest jednak jedno zastrzeżenie: jeśli dane są dłuższe niż określona szerokość, nie zostaną obcięte. Będziesz musiał użyć danych. Podciąganie (0, szerokość) na dowolnym polu potencjalnie dłuższym niż szerokość, co powoduje, że otrzymasz szczegółowe (i powtarzające się/nie-DRY) szybkie. – brianary
Tylko że jestem powolny, ponieważ tęskniłem za nim, ale jeśli wynik jest wyświetlany, to czcionka musi zostać poprawiona również szerokość – ScruffyDuck