2013-08-07 3 views
2

У меня есть массив байтов фиксированной длины, и я хочу сохранить в нем String. Что-то вроде:Как сохранить и прочитать строку из массива байтов фиксированной длины?

byte[] dst = new byte[512]; 
String foo = "foo"; 
byte[] src = foo.getBytes("utf-8"); 

for (int i = 0; i < src.length; i++) { 
    dst[i] = src[i]; 
} 

Но когда я хочу прочитать значение строки обратно из целевой_адреса, нет никакого способа узнать, где строка заканчивается (предполагает, что нет никакого понятия нулевых терминаторов в Java?). Должен ли я хранить длину строки в массиве байтов, прочитывать ее отдельно, чтобы узнать, сколько байтов следует читать из массива байтов?

+1

Почему вы копируете с 'src' на' dst' вообще, а не используете 'src'? –

+1

Да, вы должны сохранить длину строки, которую вы набиваете в dst, иначе как вы узнаете, сколько байтов вытягивать снова при восстановлении String из вашего массива dst byte. – anubhava

+1

'new String (dst, 0, src.length," UTF-8 ")' и вы можете использовать 'DataOutputStream.writeUTF8 (String)' без байтов. –

ответ

4

1. length + payload сценарий

Если вам нужно хранить строки байтов в массив пользовательских длины, то вы можете использовать первые 1 или 2 байта для понятия «длина».

код будет выглядеть так:

byte[] dst = new byte[256]; 
String foo = "foo"; 
byte[] src = foo.getBytes("utf-8"); 
dst[0] = src.length; 
System.arraycopy(src, 0, dst, 1, src.length); 

2. 0 сценария элемента

Или вы можете проверить массив, пока вы не найдете 0 элемент. Но нет никакой гарантии, что первый 0-элемент, который вы найдете, тот, который вам нужен.

byte[] dst = new byte[256]; 
String foo = "foo"; 
byte[] src = foo.getBytes("utf-8"); 
System.arraycopy(src, 0, dst, 0, src.length); 
int length = findLength(dst); 

private int findLength(byte[] strBytes) { 
    for(int i=0; i< dst.length; ++i) { 
     if (dst[i] == 0) { 
      return i; 
     } 
    } 
    return 0; 
} 

Мой выбор:

Я бы лично пойти с length + payload сценария.

+0

Или первые 1 или 2 байта могут использоваться, чтобы указать, сколько байтов используется для обозначения длины. Это обеспечивает гораздо более расширяемое решение. – Snps

+0

@ Правильно, вот в чем идея. –

0

Вы можете кодировать свою строку с помощью кодировки Modified UTF-8. Таким образом, вы можете использовать 0 в качестве терминатора.

Но, если возможно, вы должны придерживаться более простого подхода.

0

Я бы предложил использовать ByteArrayOutputStream для хранения данных и длины данных. Простой пример:

ByteArrayOutputStream dst = new ByteArrayOutputStream(); 
String foo = "foo"; 
byte[] src = foo.getBytes("utf-8"); 
dst.write(src.length); // write length 
dst.write(src); // write data 

ИСПЫТАНИЯ:

byte[] tmp = dst.toByteArray(); // length+data 
byte[] newsrc = new byte[tmp[0]]; // tmp[0] is length 
System.arraycopy(tmp, 1, newsrc, 0, tmp[0]); // copy data without length 
System.out.println("Result str => " + new String(newsrc, "utf-8")); // create String again 
//=> Result str => foo 

PS: Это простой пример, для реальных обработки данных, было бы лучше, чтобы зарезервировать 2 или более байт для хранения длины данные, которые вы храните.

Смежные вопросы