I am reading the inbox of an office 365 Mail account and downloading the attachment of it (txt files). It works fine with small files less than 2 MB but when I tried with a 20 MB file, It is really slow. I test the code in two different machines (Linux and Windows) and the speed was the same, really slow.
String user = "[email protected]";
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);
}
I can possibly create threads, but is there any other alternative?
Just a side note: I try the code with python and the speed improve significantly.
====================================== UPDATE 1:
I did the change to saveFile method and the code simplifies a lot, but still the same downloading speed of 10 KB per second.
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");
I also use the profiler and the results are:
Fix these common mistakes.
Simplify your code by using MimeBodyPart.saveFile to save the attachment.
Since you're using the "imaps" protocol and not the "imap" protocol, set the mail.imaps.fetchsize
property to something large enough to get the performance you want without using more memory than you want to use. Or set mail.imaps.partialfetch
to false if you don't care how much memory you use and you're sure you'll always have enough.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With