Символ 1 байт или 2 байта в Java?
Я думал, что символы в java-это 16 бит, как предложено в java doc. Разве дело не в струнах? У меня есть код, который хранит объект в файле:
public static void storeNormalObj(File outFile, Object obj) {
FileOutputStream fos = null;
ObjectOutputStream oos = null;
try {
fos = new FileOutputStream(outFile);
oos = new ObjectOutputStream(fos);
oos.writeObject(obj);
oos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
oos.close();
try {
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
в основном, я пытался сохранить строку "abcd"
в файле "output"
, когда я открыл output
С редактором и удалил строковую часть none, что осталось только строка "abcd", которая составляет 4 байта в общей сложности. Кто-нибудь знает почему? Java автоматически экономит место, используя ASCII вместо UNICODE для строк, которые могут поддерживаться ASCII? Спасибо
5 ответов
(Я думаю, что "нет Строковой части" вы имеете в виду байты, которые ObjectOutputStream испускает при его создании. Возможно, вы не хотите использовать ObjectOutputStream, но я не знаю ваших требований.)
просто FYI, Unicode и UTF-8-это не одно и то же. Юникод-это стандарт, который определяет, среди прочего, какие символы доступны. UTF-8-это кодировка символов, которая определяет, как эти символы должны быть физически закодированы в 1s и 0s. UTF-8 может использовать 1 байт для ASCII (
UTF-8 является строгим надмножеством ASCII. Поэтому, даже если вы укажете кодировку UTF-8 для файла и запишете в него "abcd", он будет содержать только эти четыре байта: они имеют ту же физическую кодировку в ASCII, что и в UTF-8.
ваш метод использует ObjectOutputStream
который на самом деле имеет значительно отличную кодировку, чем ASCII или UTF-8! Если вы внимательно читаете Javadoc, если obj
это строка и уже произошла в потоке, последующие вызовы writeObject
вызовет ссылку на предыдущую строку, которая может привести к тому, что в случае повторяющихся строк будет записано гораздо меньше байтов.
Если вы серьезно относитесь к пониманию этого, вы действительно должны потратить много времени на чтение о Unicode и системах кодирования символов. Википедия имеет отличную статью о Unicode как начать.
Да,char
- Это только Unicode в контексте среды выполнения Java. Если вы хотите написать его с помощью 16-битной кодировки, используйте FileWriter
.
FileWriter outputStream = null;
try {
outputStream = new FileWriter("myfilename.dat");
int c;
while ((c = inputStream.read()) != -1) {
outputStream.write(c);
}
} finally {
if (outputStream != null) {
outputStream.close();
}
}
Если вы посмотрите на источник строки, он заметит, что он вызывает DataOutput.writeUTF для записи строк. И если вы прочитаете это, вы узнаете, что они написаны как "модифицированный UTF-8". Детали длинны, но если вы не используете не 7 бит ascii, да, это займет один байт. Если вы хотите, чтобы кровавые детали смотрели на чрезвычайно длинный javadoc в DataOutput.writeUTF()
вам может быть интересно узнать, что есть -XX:+UseCompressedStrings
опция в выпуске производительности Java Update 21 и позже. Это позволит String использовать byte[]
для строк, которые не нужны char[]
несмотря на параметры Java Hotspot VM руководство, предполагающее, что он может быть включен по умолчанию, это может быть только для выпусков производительности. Он работает только для меня, если я включаю его явно.
Так вы ожидаете ? Больше, чем кодировка UTF-8 или ASCII. Как только файл записывается в файл. Управление памятью (с точки зрения пространства) зависит от операционной системы. И ваш код не имеет контроля над этим.