Skip to content

Instantly share code, notes, and snippets.

@relyky
Last active February 24, 2023 05:34
Show Gist options
  • Save relyky/d12b4bfdb4a62a0faebbaed260de1cc4 to your computer and use it in GitHub Desktop.
Save relyky/d12b4bfdb4a62a0faebbaed260de1cc4 to your computer and use it in GitHub Desktop.
NET6, Encoding, Big5, No data is available for encoding 950, MemoryStream, FileStream
/// 問題描述 (Error Descrption)
/// 在 .NET Core 內使用 Encoding.GetEncoding(950) 方法時,出現錯誤訊息:
/// System.NotSupportedException: No data is available for encoding 950
/// 解決方法 (Solution)
/// 你可以加上 Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
/// 解決這個問題,其主要的原因為簡化了編碼,導致部分編碼不包含在當中。
/// ref→[[.NET Core] System.NotSupportedException: No data is available for encoding 950 錯誤解決方法](http://dog0416.blogspot.com/2019/11/net-core-systemnotsupportedexception-no.html)
/// ref→[VS Code C# - System.NotSupportedException: No data is available for encoding 1252](https://stackoverflow.com/questions/49215791/vs-code-c-sharp-system-notsupportedexception-no-data-is-available-for-encodin)
public void ReadBig5File()
{
// register and get Big5 Encoding
System.Text.Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); // 註冊Big5等編碼
System.Text.Encoding Big5Enc = Encoding.GetEncoding(950);
// open file
var fi = new FileInfo(@"C:\Temp\Input2.csv");
using var file = new StreamReader(fi.FullName, Big5Enc);
string line = file.ReadLine();
while(line != null)
{
Console.WriteLine($"讀取一行:" + line);
...
// next
line = file.ReadLine();
}
}
/// 寫檔編碼為 Big5,要求欄位有固定保留長度,
/// 如:地址固定給 200 bytes 空間、金額 20 bytes 空間等等。
string PadWord(string word, int padSize)
{
//※ 別忘了要先註冊才能在 .NET5/.NET6 使用。
System.Text.Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
var Bi5Enc = Encoding.GetEncoding(950); // Big5 Encoder 也可以事先備好才不用一直重建。
int big5Len = Bi5Enc.GetByteCount(word);
return word + new String(' ', padSize - big5Len);
}
//## ====== 應用:Big5 編碼寫檔 ====== ====== ======
StringBuilder line = new StringBuilder();
line.Append(PadWord("A123", 10));
line.Append(PadWord("不定長度的地址3號", 50));
line.Append(PadWord("123,000元", 20));
line.AppendLine(); // 第一行結束
line.Append(PadWord("A2212", 10));
line.Append(PadWord("不定長度的地址長一點23號", 50));
line.Append(PadWord("4,123,000元", 20));
line.AppendLine(); // 第二行結束
line.Append(PadWord("A34545", 10));
line.Append(PadWord("短地址", 50));
line.Append(PadWord("1,000元", 20));
line.AppendLine(); // 第三行結束
File.WriteAllText(@"C:\temp\big5.txt", line.ToString(), Bi5Enc);
//## ====== 結果 ====== ====== ======
A123 不定長度的地址3號 123,000元
A2212 不定長度的地址長一點23號 4,123,000元
A34545 短地址 1,000元
void GenerateBig5File(List<YourInfo> dataList)
{
try
{
// register and get Big5 Encoding
System.Text.Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); // 註冊Big5等編碼
Encoding big5Enc = Encoding.GetEncoding(950);
//## 暫寫入記憶體檔
using var ms = new MemoryStream();
using var sr = new StreamWriter(ms, big5Enc);
foreach (var item in dataList)
{
StringBuilder sb = new StringBuilder();
sb.Append(PadWord(item.ID, 20));
sb.Append(PadWord(item.NAME1, 50));
sb.Append(PadWord(item.ADD1, 20));
sb.Append(PadWord(item.ADD2, 30));
sb.Append(PadWord(item.ADD3, 20));
sb.AppendLine();
// 寫入一行
sr.Write(sb.ToString());
}
// 寫入尾行
string tailLine = $"TAIL={dataList.Count:0000000}".PadRight(140, ' ') + Environment.NewLine;
sr.Write(tailLine);
//## 寫入實體檔
sr.Flush();
ms.Flush();
string path = Path.Combine(TargetFolder, TargetFilename);
using var file = new FileStream(path, FileMode.Create, FileAccess.Write);
file.Write(ms.GetBuffer(), 0, (int)ms.Length);
}
catch (Exception ex)
{
throw new ApplicationException("匯出失敗!" + ex.Message, ex);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment