Символы C# и UTF-16

Вариант 1:

Таким образом, для первого варианта вы можете установить конечный байт, который не будет нигде в вашем фактическом сообщении. Вы можете создать строку, например, для "END", преобразовать ее в байтовый массив и отправить через вашу Java-программу. После получения вы можете использовать decode (), чтобы преобразовать его в строку и сравнить. :

Примечание. Конечный байт, который вы отправите, должен быть меньше или равен размеру фрагмента для декодирования и получения точного конечного байта.

byte_array = bytearray()

# receive the data in small chunks and print it
while True:
    data = connection.recv(64)
    command = data.decode()
    if command != "END":
        # output received data
        logger.debug("Data: %s" % data)
        byte_array.extend(data)

    else:
        # no more data -- quit the loop
        logger.debug("no more data.")
        break

logger.info("Generating response...")
connection.send(generate_response(byte_array))
logger.info("Sent response.")

Вариант 2:

Для второго варианта вам потребуется изменить цикл while для выполнения в соответствии с метаданными. Я считал, что метаданные будут состоять из первого чанка, который будет количеством чанков, которые будут отправлены. Это может быть что-то вроде:

byte_array = bytearray ()

# receive the data in small chunks and print it
loop_count = 0
count = 1
meta = 1
while loop_count >= count:
    data = connection.recv(64)
    if(meta):
        count = int(data.decode()) # first chunk is the number of chunks that will be sent 
        meta = 0
    logger.debug("Data: %s" % data)
    byte_array.extend(data)
    loop_count = loop_count + 1
else:
    # no more data
    logger.debug("no more data.")
logger.info("Generating response...")
connection.send(generate_response(byte_array))
logger.info("Sent response.")

[1114 ] Вариант 3:

Он также будет работать нормально, при условии, что вы уверены, что не будет никакой задержки в сети, и единственной проблемой будет то, что вашей java-программе придется ждать ответа от сервера python до истечения времени ожидания происходит

Вариант 4:

Вы можете использовать неблокирующий сокет, который будет работать до тех пор, пока он не будет получен в течение заранее определенного периода времени. Хотя я не рекомендую это для вашей ситуации, вы можете прочитать об этом и посмотреть, соответствует ли это вашим потребностям.

7
задан Dutow 30 March 2009 в 13:40
поделиться

3 ответа

Строка класс представляет блок текста в кодировке UTF-16, и каждый char в строке представляет значение кода UTF-16.

Хотя нет типа BCL, который представляет одну кодовую точку Unicode, есть поддержка символов Unicode за пределами Плоскость 0 в виде перегрузок метода, принимающая строку и индекс вместо простого char . Например, статический метод GetUnicodeCategory (char) в классе System.Globalization.CharUnicodeInfo имеет соответствующий GetUnicodeCategory ( string, int) , который распознает простой символ или суррогатную пару, начиная с указанного индекса.


Чтобы перебирать текстовые элементы в строке , вы можете использовать методы в Класс System.Globalization.StringInfo . Здесь "

10
ответ дан 6 December 2019 в 11:53
поделиться

Я только знаю эту проблему от Java и проверил документацию char прежде, чем ответить и действительно поведение является в значительной степени тем же в.NET/C# и Java.

Это кажется этим действительно a char определяется, чтобы быть 16 битов и определенно ничего не может содержать за пределами Плоскости 0. Только String/string способно к обработке тех символов. В a char- массив это будет представлено как два суррогатных символа.

4
ответ дан 6 December 2019 в 11:53
поделиться

C # System.String прекрасно поддерживает UTF-32, но вы не можете перебирать строку, как это массив System.Char, или использовать IEnumerable.

например:

// iterating through a string NO UTF-32 SUPPORT
for (int i = 0; i < sample.Length; ++i)
{
    if (Char.IsDigit(sample[i]))
    {
        Console.WriteLine("IsDigit");
    }
    else if (Char.IsLetter(sample[i]))
    {
        Console.WriteLine("IsLetter");
    }
}

// iterating through a string WITH UTF-32 SUPPORT
for (int i = 0; i < sample.Length; ++i)
{
    if (Char.IsDigit(sample, i))
    {
        Console.WriteLine("IsDigit");
    }
    else if (Char.IsLetter(sample, i))
    {
        Console.WriteLine("IsLetter");
    }

    if (Char.IsSurrogate(sample, i))
    {
        ++i;
    }
}

. Обратите внимание на небольшую разницу в вызовах Char.IsDigit и Char.IsLetter. И этот String.Length - это всегда количество 16-битных «символов», а не количество «символов» в смысле UTF-32.

Не по теме, но поддержка UTF-32 совершенно не нужна приложению для обработки международные языки, если у вас нет специального экономического обоснования для малоизвестного исторического / технического языка.

3
ответ дан 6 December 2019 в 11:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: