Поскольку я не получил ответа, я решил самостоятельно провести тестирование. Я написал файл UTF-8 с различной шириной байт:
: Basic Latin, 1 byte
٠١٢٣٤٥٦٧٨٩: Arabic, 2 bytes
₀₁₂₃₄₅₆₇₈₉: Superscripts and Subscripts, 3 bytes
: Mathematical Alphanumeric Symbols, 4 bytes
Для тех, кто не умеет читать его правильно, вот шестнадцатеричный:
0000000: 3031 3233 3435 3637 3839 3a20 4261 7369: Basi
0000010: 6320 4c61 7469 6e2c 2031 2062 7974 650a c Latin, 1 byte.
0000020: d9a0 d9a1 d9a2 d9a3 d9a4 d9a5 d9a6 d9a7 ................
0000030: d9a8 d9a9 3a20 4172 6162 6963 2c20 3220 ....: Arabic, 2
0000040: 6279 7465 730a e282 80e2 8281 e282 82e2 bytes...........
0000050: 8283 e282 84e2 8285 e282 86e2 8287 e282 ................
0000060: 88e2 8289 3a20 5375 7065 7273 6372 6970 ....: Superscrip
0000070: 7473 2061 6e64 2053 7562 7363 7269 7074 ts and Subscript
0000080: 732c 2033 2062 7974 6573 0af0 9d9f 8ef0 s, 3 bytes......
0000090: 9d9f 8ff0 9d9f 90f0 9d9f 91f0 9d9f 92f0 ................
00000a0: 9d9f 93f0 9d9f 94f0 9d9f 95f0 9d9f 96f0 ................
00000b0: 9d9f 973a 204d 6174 6865 6d61 7469 6361 ...: Mathematica
00000c0: 6c20 416c 7068 616e 756d 6572 6963 2053 l Alphanumeric S
00000d0: 796d 626f 6c73 2c20 3420 6279 7465 730a ymbols, 4 bytes.
Теперь, я написал простую программу, чтобы просто выводить кодовые это следующим образом:
using System;
class Program
{
static void Main()
{
Console.WriteLine("Codepoints:");
for (int cur = Console.Read(); cur != -1; cur = Console.Read())
Console.WriteLine("U+{0:X4}", cur);
}
}
Теперь, вот выход при запуске на моем тестовом файле:
Codepoints:
U+0030
U+0031
U+0032
U+0033
U+0034
U+0035
U+0036
U+0037
U+0038
U+0039
<cut>
U+0660
U+0661
U+0662
U+0663
U+0664
U+0665
U+0666
U+0667
U+0668
U+0669
<cut>
U+2080
U+2081
U+2082
U+2083
U+2084
U+2085
U+2086
U+2087
U+2088
U+2089
<cut>
U+D835
U+DFCE
U+D835
U+DFCF
U+D835
U+DFD0
U+D835
U+DFD1
U+D835
U+DFD2
U+D835
U+DFD3
U+D835
U+DFD4
U+D835
U+DFD5
U+D835
U+DFD6
U+D835
U+DFD7
<cut>
(Как я и предполагал, добавление Console.InputEncoding = Encoding.UTF8;
не повлияло на выход.) Как вы видите, он отлично читает символы на базовой многоязычной плоскости. Однако, когда вы начинаете входить в дополнительные плоскости, он действует как UTF-16 и начинает выводить суррогатных символов. Однако эти суррогаты по-прежнему правильно кодируют исходные символы, что привело меня к моему заключению:
Console.Read
может читать UTF-8, но выходы в UTF-16.
Это кодировка, которую использует другая программа, - тот, чей вывод вы перенаправляете на ваш вход. Если это текстовый файл, то любая текстовая кодировка была использована программой, создавшей файл. Таким образом, вы просто не знаете, если у вас есть жесткие факты об этой программе или файле. Тот факт, что он настолько неочевиден, делает перенаправление ввода-вывода главной фабрикой ошибок, вам будет намного лучше не полагаться на него. Это функция Unix, которая должна была остаться в Unix :) –
Не знаю. Почему упрек? –