首页 > 编程语言 >java 文件File与byte[]数组相互转换的两种方式

java 文件File与byte[]数组相互转换的两种方式

时间:2023-02-15 11:31:30浏览次数:53  
标签:文件 java File fileBytes 数组 pdf new byte

 

1.文件转byte[]

方式一:文件输入流

File file = new File("C:\\Users\\Marydon\\Desktop\\个人信用报告.pdf");
try {
FileInputStream fis = new FileInputStream(file);
// 强转成int类型大小的数组
byte[] fileBytes = new byte[(int) file.length()];
// 将pdf内容放到数组当中
fis.read(fileBytes);
// 关闭文件流
fis.close();
System.out.println(Arrays.toString(fileBytes));
} catch (IOException e) {
e.printStackTrace();
}

java 文件File与byte[]数组相互转换的两种方式_文件流

  在这里会触发一个思考题:

  将文件的长度类型long强制转换成int,真的可以吗?

  起初,我觉得这样不妥,原因在于:假设当文件的长度>Integer类型的最大值时,那就这样肯定就不行了,byte[]将不是一个完整的文件数组集合,怎么办?

  我首先想到的是:

  我们在进行文件流的读写操作时,通常使用的是这种方式

java 文件File与byte[]数组相互转换的两种方式_JAVA_02

  写到这里,我才明白,这种循环读取的方式是因为有地方可以接受读取到的字节,我们这里呢?本来就是要用数组接收的,现在接收不下,没有办法,要想实现的话,也就只能将文件拆分成多个数字集合,这样一来,和我的初衷背道而驰,我就是想要将它们融合到一个数组,显然,这种方式是行不通的。

  接下来,我就查了在Java中,数组的最大限制相关信息:

  数组的最大限制,理论值是:

java 文件File与byte[]数组相互转换的两种方式_数组_03

  相当于2G的大小,对应应用内存的话是4G(源自网络,不知其真假性,如果有好心人进行测试一下,欢迎留言)

  当我创建一个最大的数组时,结果如下:

java 文件File与byte[]数组相互转换的两种方式_数组_04

  数组所需内存超过了Java虚拟机的内存,GAME OVER。

  然后,继续查:
  了解到:Java数组最大容量同时受两方面限制

  一是:数组可索引的最大元素(也就是Integer的最大值);二是:应用程序可用的内存量(也就是JVM的容量)。
  走到这里,基本上恍然大悟啦:

  只要我们能将文件成功转换成单个数组,就说明:

  文件的长度必然<数组容量的最大值,否则运行起来肯定报错。

  所以,上述代码中将文件的长度类型long强制转换成int,是完全可以的,如果不可以(也就是文件超过了数组最大容量) ,那就不用考虑将文件转单个数组的实现方式啦。

  另外,如果你想用BufferInputStream来加快读取速度的话,也是可以哒。

  对于有强迫症的人来说,强转还是很让人不舒服的,可以使用下面代码,一劳永逸

  推荐使用

File file = new File("C:\\Users\\Marydon\\Desktop\\个人信用报告.pdf");
try {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
// 以字节流的大小来指定数组大小
byte[] fileBytes = new byte[bis.available()];
// 将pdf内容放到数组当中
bis.read(fileBytes);
// 关闭文件流
bis.close();
System.out.println(Arrays.toString(fileBytes));
} catch (IOException e) {
e.printStackTrace();
}

方式二:原生工具类Files(不推荐)

  使用条件:>=JDK1.8

try {
// 方式一
byte[] bytes = Files.readAllBytes(Paths.get("C:\\Users\\Marydon\\Desktop\\个人信用报告.pdf"));
// 方式二
// bytes = Files.readAllBytes(new File(("C:\\Users\\Marydon\\Desktop\\个人信用报告.pdf")).toPath());
System.out.println(Arrays.toString(bytes));
} catch (IOException e) {
e.printStackTrace();
}

java 文件File与byte[]数组相互转换的两种方式_Desktop_05

  但是,这种方式比较鸡肋,大文件(100多兆)读取容易内存溢出。

java 文件File与byte[]数组相互转换的两种方式_文件流_06

  如果发现读取完毕,获得的数组始终为空[],很有可能是你的原文件已经被破坏

java 文件File与byte[]数组相互转换的两种方式_文件流_07

2.byte[]转文件 

方式一:文件输出流

// 文件流
byte[] fileBytes = {37, 80, 68, 70, 45, 49, 46, 52, 10, 37, -30, -29, -49, -45, 10, 50, 32, 48, 32, 111, 98, 106, 10, 60, 60, 47, 84, 121, 112, 101, 47, 88, 79};
try {
// 将要输出的文件
File outFile = new File("C:\\Users\\Marydon\\Desktop\\aa.pdf");
// 文件转输出流
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(outFile));
// 将文件流写入文件
bos.write(fileBytes);
bos.close();
} catch (IOException e) {
e.printStackTrace();
}

  上面提供的文件字节数组,是无法转成正常文件的哦,我这里仅提供实现方法

方式二:原生工具类Files

// 文件流
byte[] fileBytes = {37, 80, 68, 70, 45, 49, 46, 52, 10, 37, -30, -29, -49, -45, 10, 50, 32, 48, 32, 111, 98, 106, 10, 60, 60, 47, 84, 121, 112, 101, 47, 88, 79};
try {
// 将数组输出到指定文件当中
Files.write(Paths.get("C:\\Users\\Marydon\\Desktop\\aa.pdf"), fileBytes);
} catch (IOException e) {
e.printStackTrace();
}

  

写在最后

  哪位大佬如若发现文章存在纰漏之处或需要补充更多内容,欢迎留言!!!

作者:​​Marydon​​



标签:文件,java,File,fileBytes,数组,pdf,new,byte
From: https://blog.51cto.com/u_15964717/6058998

相关文章

  • JavaScript 中 ?. 和 ?? 分别是什么?
    ?.和??是JavaScript中的两个新操作符,分别是可选链操作符(optionalchainingoperator)和空值合并操作符(nullishcoalescingoperator)。?.操作符?.可选链操作符用于......
  • java json对象转json字符串(带转义符)(json对象嵌套json字符串)
    1.情景展示如上图所示,这一个标准的json字符串,双引号需要使用反斜杠\进行转义,一般情况下,我们是用不到这种json字符串的,在java中,json字符串的通常表现形式是这种:......
  • java 实体类Bean与Map互相转化
     1.情景展示java对象与Map之间进行相互转换,如何实现? 2.分析通过org.apache.commons.beanutils.BeanUtils类来实现所需jar包<dependency><groupId>com......
  • Java 枚举类转json对象
     1.情景展示 如上图所示,我想要将枚举类转换成json对象,key对应属性名称,value对应属性值,效果如下:{"IvcVoucherCode":"200","IvcVoucherStatus":"票据模板下载成功"}......
  • java8 Lambda表达式遍历并移除元素,报错:ConcurrentModificationException的解决办法
     1.情景展示已知json对象MainExt需要把值为空数组的key移除掉,下面是执行代码执行结果报错:java.util.ConcurrentModificationException 2.原因分析大致过......
  • CentOS7中使用Dockerfile部署后台jar包
    场景使用Dockerfile定制镜像来部署Tomcat项目在上面使用Tomcat部署项目之外,还可以使用Dockfile基于openjdk部署jar包项目。注:关注公众号霸道的程序猿获取编程相关电子书、......
  • CentOS中使用Dockerfile部署带websocket的SpringBoot的jar包
    场景CentOS7中使用Dockerfile部署后台jar包在上面使用Dockerfile定制的镜像部署了一个普通的jar包, 如果是jar包里面包含websocket的使用,流程也是一样。websocket所使用的......
  • CentOS中使用Dockerfile部署初始化sql文件的mysql
    场景Docker中部署mysql数据库CentOS中使用Dockerfile部署带websocket的SpringBoot的jar包在上面部署Mysql镜像和会使用Dockerfile的基础上。如果要实现定制化一个mysql镜像,......
  • filebeat+elasticsearch+kibana
    一、到elasticsearch官网下载filebeat+elasticsearch+kibanahttp://www.elasticsearch.cn/ 二、新增fbeat用户tar-xzvffilebeat-7.16.3-linux-x86_64.tar.gz-C......
  • Makefile Tab键
    https://blog.csdn.net/weixin_44980842/article/details/123167307MakefileTab键 MakefileTab键 MakefileTab键 MakefileTab键......