Java 邮件下载附件 Office 365 速度慢
Java Mail Slow downloading attachment Office 365
我正在阅读一个 office 365 邮件帐户的收件箱并下载它的附件(txt 文件)。它适用于小于 2 MB 的小文件,但当我尝试处理 20 MB 的文件时,它真的很慢。我在两台不同的机器(Linux和Windows)上测试代码,速度是一样的,真的很慢。
String user = "mail@mail.com";
String password = "mypassword";
try{
boolean foundSites = false;
// Get a Properties object
Properties properties = new Properties();
properties.put("mail.imaps.host", host);
properties.put("mail.imaps.port", port);
properties.put("mail.imaps.starttls.enable", SSL);
//properties.put("mail.imap.fetchsize", "1000000");
Session emailSession = Session.getDefaultInstance(properties);
//create the POP3 store object and connect with the pop server
Store store = emailSession.getStore("imaps");
store.connect(host, user, password);
//create the folder object and open it
Folder emailFolder = store.getFolder("INBOX");
emailFolder.open(Folder.READ_ONLY);
// retrieve the messages from the folder in an array and print it
Message[] messages = emailFolder.getMessages();
System.out.println("messages.length---" + messages.length);
LocalDateTime now = LocalDateTime.now();
int year = now.getYear();
int month = now.getMonthValue();
int day = now.getDayOfMonth();
for (int i = messages.length - 1; i >= 0; i--) {
Message message = messages[i];
Calendar cal = Calendar.getInstance();
cal.setTime(message.getReceivedDate());
int yearMessage = cal.get(Calendar.YEAR);
int monthMessage = cal.get(Calendar.MONTH) + 1;
int dayMessage = cal.get(Calendar.DAY_OF_MONTH);
if(year == yearMessage && month == monthMessage && day == dayMessage)
{
//The real code is doing this with 20 Subjects (20 emails)
if(message.getSubject().equalsIgnoreCase("Integration - Site Info") && foundSites != true)
{
System.out.println("found Integration - Site Info");
Multipart multipart = (Multipart) message.getContent();
List<File> attachments = new ArrayList<>();
for (int j = 0; j < multipart.getCount(); j++) {
BodyPart bodyPart = multipart.getBodyPart(j);
if(Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition()))
{
InputStream is = bodyPart.getInputStream();
File f = new File("./attachments/"
+ "sites_"+Integer.toString(day)+"-"+Integer.toString(month)+"-"+Integer.toString(year)+".csv");
FileOutputStream fos = new FileOutputStream(f);
byte[] buf = new byte[4096];
int bytesRead;
while((bytesRead = is.read(buf))!=-1) {
fos.write(buf, 0, bytesRead);
}
fos.close();
attachments.add(f);
foundSites = true;
break;
}
}
}
}
if(foundSites)
{
break;
}
} catch (Exception e) {
System.out.println(e);
}
我可以创建线程,但还有其他选择吗?
附带说明:
我尝试使用 python 的代码,速度显着提高。
======================================
更新 1:
我更改了 saveFile 方法,代码简化了很多,但仍然是每秒 10 KB 的相同下载速度。
MimeBodyPart bodyPart = (MimeBodyPart) multipart.getBodyPart(j);
if(Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition()))
{
bodyPart.saveFile("./attachments/"
+ "sites_"+Integer.toString(day)+"-"+Integer.toString(month)+"-"+Integer.toString(year)+".csv");
我也使用了探查器,结果是:
修复这些 common mistakes。
使用 MimeBodyPart.saveFile 保存附件来简化您的代码。
由于您使用的是 "imaps" 协议而不是 "imap" 协议,因此请将 mail.imaps.fetchsize
属性 设置为足够大的值以获得您想要的性能而无需使用比您想要使用的更多的内存。或者,如果您不在乎使用多少内存并且确信自己总是有足够的内存,则将 mail.imaps.partialfetch
设置为 false。
我正在阅读一个 office 365 邮件帐户的收件箱并下载它的附件(txt 文件)。它适用于小于 2 MB 的小文件,但当我尝试处理 20 MB 的文件时,它真的很慢。我在两台不同的机器(Linux和Windows)上测试代码,速度是一样的,真的很慢。
String user = "mail@mail.com";
String password = "mypassword";
try{
boolean foundSites = false;
// Get a Properties object
Properties properties = new Properties();
properties.put("mail.imaps.host", host);
properties.put("mail.imaps.port", port);
properties.put("mail.imaps.starttls.enable", SSL);
//properties.put("mail.imap.fetchsize", "1000000");
Session emailSession = Session.getDefaultInstance(properties);
//create the POP3 store object and connect with the pop server
Store store = emailSession.getStore("imaps");
store.connect(host, user, password);
//create the folder object and open it
Folder emailFolder = store.getFolder("INBOX");
emailFolder.open(Folder.READ_ONLY);
// retrieve the messages from the folder in an array and print it
Message[] messages = emailFolder.getMessages();
System.out.println("messages.length---" + messages.length);
LocalDateTime now = LocalDateTime.now();
int year = now.getYear();
int month = now.getMonthValue();
int day = now.getDayOfMonth();
for (int i = messages.length - 1; i >= 0; i--) {
Message message = messages[i];
Calendar cal = Calendar.getInstance();
cal.setTime(message.getReceivedDate());
int yearMessage = cal.get(Calendar.YEAR);
int monthMessage = cal.get(Calendar.MONTH) + 1;
int dayMessage = cal.get(Calendar.DAY_OF_MONTH);
if(year == yearMessage && month == monthMessage && day == dayMessage)
{
//The real code is doing this with 20 Subjects (20 emails)
if(message.getSubject().equalsIgnoreCase("Integration - Site Info") && foundSites != true)
{
System.out.println("found Integration - Site Info");
Multipart multipart = (Multipart) message.getContent();
List<File> attachments = new ArrayList<>();
for (int j = 0; j < multipart.getCount(); j++) {
BodyPart bodyPart = multipart.getBodyPart(j);
if(Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition()))
{
InputStream is = bodyPart.getInputStream();
File f = new File("./attachments/"
+ "sites_"+Integer.toString(day)+"-"+Integer.toString(month)+"-"+Integer.toString(year)+".csv");
FileOutputStream fos = new FileOutputStream(f);
byte[] buf = new byte[4096];
int bytesRead;
while((bytesRead = is.read(buf))!=-1) {
fos.write(buf, 0, bytesRead);
}
fos.close();
attachments.add(f);
foundSites = true;
break;
}
}
}
}
if(foundSites)
{
break;
}
} catch (Exception e) {
System.out.println(e);
}
我可以创建线程,但还有其他选择吗?
附带说明: 我尝试使用 python 的代码,速度显着提高。
====================================== 更新 1:
我更改了 saveFile 方法,代码简化了很多,但仍然是每秒 10 KB 的相同下载速度。
MimeBodyPart bodyPart = (MimeBodyPart) multipart.getBodyPart(j);
if(Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition()))
{
bodyPart.saveFile("./attachments/"
+ "sites_"+Integer.toString(day)+"-"+Integer.toString(month)+"-"+Integer.toString(year)+".csv");
我也使用了探查器,结果是:
修复这些 common mistakes。
使用 MimeBodyPart.saveFile 保存附件来简化您的代码。
由于您使用的是 "imaps" 协议而不是 "imap" 协议,因此请将 mail.imaps.fetchsize
属性 设置为足够大的值以获得您想要的性能而无需使用比您想要使用的更多的内存。或者,如果您不在乎使用多少内存并且确信自己总是有足够的内存,则将 mail.imaps.partialfetch
设置为 false。