#java #jakarta-mail
#java #джакарта-почта
Вопрос:
Я пытаюсь получить размер MimeMessage. Метод getSize() просто всегда возвращает значение -1.
Это мой код:
MimeMessage m = new MimeMessage(session);
m.setFrom(new InternetAddress(fromAddress, true));
m.setRecipient(RecipientType.TO, new InternetAddress(toAddress, true));
m.setSubject(subject);
MimeBodyPart bodyPart = new MimeBodyPart();
bodyPart.setContent(body, "text/html");
Multipart mp = new MimeMultipart();
mp.addBodyPart(bodyPart);
m.setContent(mp);
m.getSize(); // -1 is returned
ЭТО ОТВЕТ НА МОЙ ВОПРОС:
ByteArrayOutputStream os = new ByteArrayOutputStream();
m.writeTo(os);
int bytes = os.size();
Ответ №1:
Более эффективным решением, но требующим внешней библиотеки, является следующее:
public static long getReliableSize(MimeMessage m) throws IOException, MessagingException {
try (CountingOutputStream out = new CountingOutputStream(new NullOutputStream())) {
m.writeTo(out);
return out.getByteCount();
}
}
Как CountingOutputStream, так и NullOutputStream доступны в Apache Common IO. Это решение не требует работы с временным байтовым буфером (запись, выделение, перераспределение и т.д.)
Комментарии:
1. Я вижу огромную разницу в количестве байтов, возвращаемых из библиотеки apache, когда сравниваю его с выводом Java mime message.getSize(). есть идеи по этому поводу?
Ответ №2:
Решение, предоставляемое Apache Commons, хорошее, но конструктор NullOutputStream() теперь устарел. Вместо этого используйте синглтон:
CountingOutputStream out = new CountingOutputStream(NullOutputStream.NULL_OUTPUT_STREAM);
Ответ №3:
попробуйте вызвать mp.getSize(), чтобы посмотреть, что он возвращает, MimeMessage вызывает его только для mp. Также из MIME message API
Возвращает размер содержимого этой части в байтах. Возвращает -1, если размер не может быть определен.
На данный момент вы не передали никакого содержимого в сообщение, что может быть причиной возвращаемого значения -1.
Комментарии:
1. Что вы имеете в виду, что я не передал никакого содержимого? Я выполнил m.setContent (mp)
2. BodyPart.getSize() возвращает -1
3. добавьте некоторое содержимое в тело .. после этого должен получиться приблизительный размер.
4. Если кто-то все еще смотрит на это, MimeMessage и MimeBodyPart запускают getSize() для объекта содержимого или потока содержимого. Они задаются конструкторами, но не setContent(), поэтому, даже если getContent() возвращает данные, getSize() ошибочно вернет значение -1. Используйте отладчик для отслеживания внутренних данных, поскольку они могут храниться в нескольких местах в datahandler. Например, вложения могут быть измерены путем вызова available() во входном потоке источника данных datahandler.