最近翻出来好久没有看的kindle,准备继续我的阅读之路。当然,也是因为发现了一个非常好的 获取电子书资源的网站 ,又燃起了我的阅读兴趣。

然而,往kindle里传输电子书的方式一共有四种:

  • 直接在kindle商城购买正版电子书,会同步到kindle上。但是我不买书哦
  • 通过连接电脑传输。还得连电脑,可真费劲。
  • 给你的kindle发邮件,把电子书带到邮件的附件里,就可以同步到kindle上。这个是很常用的方式,但是邮箱这种东西,就是收垃圾电子邮件的,我这几年都没有主动发过邮件了。
  • 在你的iOS、Android版本的kindle应用上打开电子书,也会同步到kindle。我要是用了app了我还用kindle干啥?
  • 所以说,亚马逊这种西方互联网公司,就缺少钻研用户心思的能力(虽然说中国互联网公司钻研的有些过分了……)你在官网上整个上传功能不就好了?这么多年了,我都没有见到过类似的功能。还在用古老的电子邮件方式来传输文件……

    诶?那我让发邮件这件事变得容易一些不就行了?写个小项目来实现吧!

    快速发邮件,都需要哪些准备?

    所以,我们的思路就是,通过代码获取到要传输到kindle的电子书,然后自动发送邮件到kindle的邮箱就好啦。

    涉及到的知识点:

  • 文件的读取和操作
  • 常用的语言是Java,就先用Java简单实现一下了,以后再用python试试。

    知识点一:文件的读取和操作

    我们用 File 类来获取即可。

    整个流程如下:

  • 指定我们存放电子书的路径,就以 /Users/xiaobai/Documents/csdn/kindle 路径为例吧。
  • 通过路径获取到该文件夹下的文件列表。使用 file.listFiles()
  • 格式的校验(万一混进去不是电子书的奇怪文件呢)
  • 遍历文件列表,通过发送邮件发送电子书。其中 mailSendService.send 方法在后面会提到
  • 将发送成功的电子书移动到已发送文件夹中。使用 file.renameTo(newFile) 方法。这里要先创建好 /Users/xiaobai/Documents/csdn/kindle/sent 这个文件夹哦。
  • 话不多说,上代码:

    public void sendKindle() {
            // 获取当前路径下的全部文件
            File currentPathFile = new File("/Users/xiaobai/Documents/csdn/kindle");
            List<File> files = Arrays.asList(currentPathFile.listFiles());
            // 过滤留下指定格式的文件
            if (CollectionUtils.isEmpty(files)) {
                log.info("当前路径下不存在其他的文件");
                return;
            List<File> fileList = files.stream().filter(o -> {
                String[] split = o.getName().split("\\.");
                return (split.length > 1 && SUFFIX_LIST.contains(split[split.length - 1]));
            }).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(fileList)) {
                log.info("未找到指定类型的文件");
                return;
            for (File file : fileList) {
                mailSendService.send("xiaobaibai@kindle.cn", file);
                File newFile = new File("/Users/xiaobai/Documents/csdn/kindle/sent/" + file.getName());
                file.renameTo(newFile);
    

    知识点二:发邮件

    邮箱后台配置

    首先你要准备一个邮箱(这不是废话么),之后需要开启邮箱的smtp协议。

    以我自己用的163邮箱为例,在设置中开启这两项,如图:

    开启之后,会生成一个授权密码,需要保存起来,在发送邮件时需要用这个密码。

    依赖引入和配置

    至于如何用Java发邮件,我们就直接用Spring Boot提供的邮件组件了。在maven配置中引入spring-boot-starter-mail依赖:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-mail</artifactId>
    </dependency>
    

    或者是在初始化Spring Boot项目时,勾选Java Mail Sender

    之后,在application.yml文件中,配置如下信息:

    spring:
      mail:
        host: smtp.163.com
        # 不用填写端口号
        port:
        # 发送邮件的邮箱地址,这里是个假的地址哈,实现时需要用真实的邮箱地址
        username: sendmailtokindle@163.com
        # 刚才在邮箱设置后台生成的授权密码
        password: UXXXXXXXXXXXXQ
        protocol: smtp
        default-encoding: UTF-8
      properties:
        mail.smtp.auth: true
        mail.smtp.starttls.enable: true
        mail.smtp.starttls.required: true
        mail.smtp.socketFactory.port: 465
        mail.smtp.socketFactory.class: javax.net.ssl.SSLSocketFactory
        mail.smtp.socketFactory.fallback: false
    

    做好邮箱的配置,我们就可以写发送邮件的代码了。发邮件的模块如下:

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.core.io.FileSystemResource;
    import org.springframework.mail.javamail.JavaMailSender;
    import org.springframework.mail.javamail.MimeMessageHelper;
    import org.springframework.stereotype.Service;
    import javax.mail.MessagingException;
    import javax.mail.internet.MimeMessage;
    import java.io.File;
    @Service
    public class MailSendService {
        @Autowired
        private JavaMailSender mailSender;
        @Value("${spring.mail.username}")
        private String from;
        public void send(String to, File file) {
            MimeMessage message = mailSender.createMimeMessage();
            try {
                MimeMessageHelper helper = new MimeMessageHelper(message, true);
                helper.setFrom(from);
                helper.setTo(to);
                helper.setSubject(file.getName());
                helper.setText("自动推送kindle书籍:" + file.getName(), false);
                FileSystemResource attachment = new FileSystemResource(file);
                helper.addAttachment(attachment.getFilename(), attachment);
            } catch (MessagingException e) {
                e.printStackTrace();
            mailSender.send(message);
    

    这里自动注入的JavaMailSender类就是发送邮件的sdk,我们通过创建一个MimeMessageHelper类,来辅助创建一个可以发送附件的MimeMessage对象。这里要注意,如果没有设置text的值,在发送邮件时会因为text为null报错,这是我趟的一个坑。

    好啦,最后我们把要发送的电子书放到路径下,然后执行第一步里的sendKindle()方法,就可以自动把电子书发送到kindle的邮箱了,而且也会将发送过的电子书自动移到已发送的文件夹里备份,防止以后重复发送。

    之后要做的,就是准备把这个功能打包成一个应用,做成一个可视化的界面,然后直接拖动电子书到界面里就可以直接发邮件出去。等我再研究研究,下一篇文章见了!