点击蓝色“Java极客技术”关注我哟

加个“星标”,一起快乐成长

01、故事背景

试想一下你现在有个业务场景需要你识别出各种类型的文件,然后进行不同的处理,这些文件不管是用户上传还是怎么来的,你都需要知道文件是什么类型,比如是一张 JPG 图片,还是一个 GIF 图片又或者是 PDF 等等其他类型的文件。这个时候你会想,这还不简单么,几行 Java 代码就搞定了。

如下:

     public static String getFileTypeByExt(String filePath) {   if (StringUtils.isBlank(filePath)) {    return null;    }   return filePath.toLowerCase().substring(filePath.lastIndexOf(".") + 1);  }

敲完过后,满心欢喜,这个需求简单的无法用言语去描述,提交了代码,更新到测试环境去了,优雅又不是风度的等着下班。

眼看马上到下班的点了,起身收拾东西准备下班,正在你关上电脑的那一刹那,说时迟那时快,测试人员突然跑过来说有个 bug,需要你看下。此时的你脑海中浮现了如下场景:

  1. bug?怎么可能,我写的代码怎么可能有 bug?
  2. 什么 bug?肯定是你不会用!
  3. 肯定没清缓存吧(但是我改的后台代码,好像不影响浏览器缓存啊,摸了下后脑勺~)
  4. 不会真有 bug 吧~~

几种情况快速的在你大脑中闪现过,但是你很自信的认为是测试人员不会用,不过你没有表现出来,淡定并且很有礼貌的说了句:哦,是么,我跟你过去看下。

走到测试人员的工位前,看着桌上有一个 jpg 图片,点击按钮上传,选中这个图片,开始上传,一顿操作猛如虎,正在准备大功告成的时候,系统弹出了一个“系统错误”的弹框出来,登上测试服务器看了日志信息,提示在处理图片的时候相关类库提示失败了。

咦,不科学啊,不会是真的,清下缓存,刷新下页面,循环重复了几次操作之后,结果还是一样的,这个时候你有点认为这是个 bug 了。但是自己回想了一下差不多半个小时前写的代码,怎么都不会有问题啊,要不换个图片试试?

就这样抱着试一试的想法,换了一张图片,惊喜的发现成功了,没有提示系统错误,正常的上传成功了。看到这个现象,内心欢喜了一下,原来是图片的问题,就说不是 bug 了。

但是等等,为什么换个图片可以,这个图片就不行呢?仔细看了一个原来的图片文件,没发现什么异常啊,就是图片的大小差不多 5M,换的图片是随便截图的只有几百 k,难道是大小的原因?但是不对啊,系统是支持上传PDF 文件的,所以大小是可以超过 5M 的啊。

咦,等等这个文件的大小怎么跟我刚刚发的 PDF 的大小一样啊,之前测试文档上传,发了一个 PDF 给测试人员,大小差不多就是这个,怎么也有一个这样大小的图片呢?然后随口问了句:你这个图片哪来的啊?只见测试人员淡定的说到:哦,我是把刚刚的 PDF 文件的后缀改成了 JPG,所以这个图片不是真的图片,我只是改了一下后缀。

听到这句话的时候你的内心是崩溃的,但是你没有表现出来,毕竟测试人员的职责就是维护系统的稳定性。

故事发生到这里,你已经知道不能使用上面那段优雅的代码了,需要考虑其他方案,简单的根据后缀名来判断文件类型进行处理是不行的了。

此时的你陷入了深深的沉思当中。。。

在走回工位的路上拿出手机给媳妇(假如有的话)发了个微信:今晚加班,不回去吃饭了。

02、解决方案

为了解决这个问题,在面向搜索引擎编程的年代,你在网上搜到了一个叫做魔数的东西(本文的重点来了),抱着试一试的想法,实践起来了。

2.1、魔数的定义

魔数有很多种定义,这里我们讨论的主要是在编程领域的定义

文件的起始几个字节的内容是固定的(或是有意填充,或是本就如此),这几个字节的内容也被称为魔数 (magic number),因此可以根据这几个字节的内容确定文件类型。

2.2、常见文件类型的魔数

package com.coocaa.ad.caeser.engine.com.test.model; /** * <br>    * <b>Function:</b><br> * <b>Author:</b>@author ziyou<br> * <b>Date:</b>2019-10-24 11:21<br> * <b>Desc:</b>无<br>    */
public enum FileType {  /** * JPEG  */  JPEG("JPEG", "FFD8FF"), /** * PNG   */  PNG("PNG", "89504E47"), /** * GIF   */  GIF("GIF", "47494638"), /** * TIFF  */  TIFF("TIFF", "49492A00"),   /** * Windows bitmap    */  BMP("BMP", "424D"), /** * CAD   */  DWG("DWG", "41433130"), /** * Adobe photoshop   */  PSD("PSD", "38425053"), /** * Rich Text Format  */  RTF("RTF", "7B5C727466"),   /** * XML   */  XML("XML", "3C3F786D6C"),   /** * HTML  */  HTML("HTML", "68746D6C3E"), /** * Outlook Express   */  DBX("DBX", "CFAD12FEC5FD746F "),    /** * Outlook   */  PST("PST", "2142444E"), /** * doc;xls;dot;ppt;xla;ppa;pps;pot;msi;sdw;db    */  OLE2("OLE2", "0xD0CF11E0A1B11AE1"), /** * Microsoft Word/Excel  */  XLS_DOC("XLS_DOC", "D0CF11E0"), /** * Microsoft Access  */  MDB("MDB", "5374616E64617264204A"), /** * Word Perfect  */  WPB("WPB", "FF575043"), /** * Postscript    */  EPS_PS("EPS_PS", "252150532D41646F6265"),   /** * Adobe Acrobat */  PDF("PDF", "255044462D312E"),   /** * Windows Password  */  PWL("PWL", "E3828596"), /** * ZIP Archive   */  ZIP("ZIP", "504B0304"), /** * ARAR Archive  */  RAR("RAR", "52617221"), /** * WAVE  */  WAV("WAV", "57415645"), /** * AVI   */  AVI("AVI", "41564920"), /** * Real Audio    */  RAM("RAM", "2E7261FD"), /** * Real Media    */  RM("RM", "2E524D46"),   /** * Quicktime */  MOV("MOV", "6D6F6F76"), /** * Windows Media */  ASF("ASF", "3026B2758E66CF11"), /** * MIDI  */  MID("MID", "4D546864"); private String key; private String value;   FileType(String key, String value) {    this.key = key;    this.value = value;    }   public String getValue() {  return value;   }   public String getKey() {    return key; }
}   

2.3、工具类

package com.test.util;  import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream; /** * <br>    * <b>Function:</b><br> * <b>Author:</b>@author ziyou<br> * <b>Date:</b>2019-10-24 11:16<br> * <b>Desc:</b>无<br>    */
public class FileUtil { /** * 获取文件投 *   * @param filePath 文件路径 * @return 16 进制的文件投信息  * @throws IOException  */  private static String getFileHeader(String filePath) throws IOException {   byte[] b = new byte[28];   InputStream inputStream = new FileInputStream(filePath);   inputStream.read(b, 0, 28); inputStream.close();    return bytes2hex(b);    }   /** * 将字节数组转换成16进制字符串   */  private static String bytes2hex(byte[] src) {   StringBuilder stringBuilder = new StringBuilder(""); if (src == null || src.length <= 0) { return null;    }   for (byte b : src) {    int v = b & 0xFF;  String hv = Integer.toHexString(v);    if (hv.length() < 2) {   stringBuilder.append(0);    }   stringBuilder.append(hv);   }   return stringBuilder.toString();    }   /** * 根据文件路径获取文件类型  *   * @param filePath 文件路径 * @return 文件类型 * @throws IOException  */  public static FileType getFileType(String filePath) throws IOException {    String fileHead = getFileHeader(filePath); if (null == fileHead || fileHead.length() == 0) {   return null;    }   fileHead = fileHead.toUpperCase(); FileType[] fileTypes = FileType.values();  for (FileType type : fileTypes) {   if (fileHead.startsWith(type.getValue())) { return type;    }   }   return null;    }
}   

2.4、使用

    public static void main(String[] args) throws IOException {
//        String filePath = "/Users/ziyou/Downloads/SpringBoot实战.pdf";   String filePath = "/Users/ziyou/Downloads/SpringBoot实战.png"; FileType fileType = getFileType(filePath); System.out.println(fileType.getKey());  }

上面的输出为PDF,说明我们的实验是成功的,所以我们可以根据魔数在校验文件的类型了。

在经过一顿操作猛如虎之后,看着屏幕的代码,你感到无比的欣慰,原来一个如此简单的需求也是要考虑很多细节的,不能太随意。

提交了代码,关上了电脑,想着自己加班这么晚,真是累,但是看着窗外灯火通明,路上车水马龙,知道还有很多人跟你一样在奋斗,瞬间又有了动力~

03、总结

今天通过一个真实的业务场景给大家介绍了编程中魔数的相关应用,希望能帮助到大家。

另外从另一个方面也告诉了我们在遇到一个需求的时候,需要的考虑一点,有时候并不是自己想的那样,需要从一开始就考虑的多一点,这样后面就会省心好多。

最后欢迎大家到我们《Java 极客技术》知识星球中一起谈论技术人生,互相成长,互相进步。

精彩回顾

令人匪夷所思的 Magic 之魔数,你真的不会相关推荐

  1. Magic Number魔数是什么

    在网上查magic number的相关介绍的时候,看到很多人的博客中说magic number之所以叫magic number,就是因为我们并不知道它有什么含义... 最后看了知乎上的回答: Magi ...

  2. Magic Number(魔数)是什么

    "魔数"有贬义词.中性词.褒义词三种用法,默认为贬义词. 1.贬义词"魔数" 指的是代码中出现的没有说明的数字.代码中突然出现一个没说明用途的数字会让其它阅读代 ...

  3. Java 中文件之魔数

    Java 中令人匪夷所思的 Magic 之魔数 先来讲讲一个故事,公司突然有一个需求,客户提交的文件,让你获取到他提交的文件到底是一个什么文件,这个不是小事一桩吗?直接上代码. public stat ...

  4. 魔数(magic number)

    魔数是编程中我们需要尽量避免使用的,但是很多人不去管也不清楚. 百度百科中解释如下:         很多类型的文件,其起始的几个字节的内容是固定的(或是有意填充,或是本就如此).根据这几个字节的内容 ...

  5. Java冷知识之——魔数(Magic Number)

    一. 编程中的魔数 在阿里巴巴Java开发手册编程规约第二节常量定义的第一条中写道: 魔法值(即魔数)指的是未经预先定义的常量,而反例中的 "Id#taobao_" 则叫做魔字符串 ...

  6. vue 里怎么通过魔数(magic number)去限制上传文件类型?

    利用 input 的 accept 属性进行限制 accept 属性规定了可通过文件上传提交的服务器接受的文件类型. <input type="file"> 不限制,上 ...

  7. python magic number_编程中的「魔数」(magic number)是什么意思?平时我们能接触到哪些魔数?...

    "魔数"有贬义词.中性词.褒义词三种用法,默认为贬义词. 1.贬义词"魔数" 指的是代码中出现的没有说明的数字.代码中突然出现一个没说明用途的数字会让其它阅读代 ...

  8. 【Java 虚拟机原理】Class 字节码二进制文件分析 一 ( 字节码文件附加信息 | 魔数 | 次版本号 | 主版本号 | 常量池个数 )

    文章目录 一.字节码文件 与 JVM 二.字节码文件示例 三.字节码文件二进制结构分析 1.魔数 2.次版本号 3.主版本号 4.常量池个数 一.字节码文件 与 JVM Java 源码编译成 Clas ...

  9. 【编程好习惯】避免使用魔数

    魔数(magic number),即在编写程序时直接在程序中运用数字,而不是采用定义宏或是const变量的方式,图1是使用了魔数的一个示例程序.其中的64是指Msk的最大字节数.从这一程序中可以看出, ...

最新文章

  1. DATAX工具同步数据从hdfs到drds性能优化
  2. AD 画图 镜像翻转元器件
  3. go ssh 执行多个命令_每天一个 Linux 命令(92): dirname 命令
  4. Java笔记-读取资源文件应该注意的问题(大文件解析、\r\n分割相关的)
  5. 数据中台 画像标签_数据中台实战:如何通过标签平台圈出产品高价值用户?...
  6. linux编译有趣c程序,12个有趣的C语言问答(详解)
  7. 一个未知高度垂直居中的简单方法
  8. RHEL5 下构建PPTP ***服务器
  9. [转载] JavaScrip ajaxt和python flask通过json传递数据的方法
  10. 20172329 2017-2018-2《程序设计与数据结构》课程总结
  11. [置顶]C++求平面最近点对
  12. WLC5520无法通过无线客户端进行网管故障解决
  13. 信息系统项目管理师-学习笔记与复习资料
  14. 大一计算机基础重点知识,2015-大一计算机基础知识点归纳.doc
  15. 探针台常见问题—如何减少LHe制冷剂消耗
  16. 火狐 ajax提交失败,Firefox下AJAX0x80040111错误的解决方法
  17. OLED工作原理及结构
  18. 项目管理经验-豆知识
  19. 大数据体系构建数据仓库
  20. word中mathtype公式编辑

热门文章

  1. Eclipse单独设置注释字体加粗
  2. 高仿网易评论列表效果之界面分析
  3. C++进阶——内存管理(一)
  4. iOS用Sketch制作APP下拉刷新的GIF动画
  5. 轻量化网络结构——MobileNet
  6. 【已解决】打开jar文件找不到或无法加载主类
  7. 一封来自大佬的密信待查收
  8. excel python插件_再见 VBA!神器工具统一 Excel 和 Python
  9. win10电脑如何隐藏下方任务栏
  10. iar定义arm版本_Keil MDK 和 IAR 两款ARM开发工具区别比较