当前位置:

首页 > 编程开发 > Java中如何使用字符流读写二进制文件?

Java中如何使用字符流读写二进制文件?

使用字符流读取文件(非文本)以Java的字符流读取文件为例:它只能读取0-65535之间的字符,可以看出来字符都是正数,但是二进制的byte是可以为负数的。但是读取的时候会被当做正数来读取,或者是无法在编码表中找到的字符会返回一个奇怪的符号(你可能见过那个奇怪的“?”)。但是在某些情况下,必须要使用字符来显示二进制数据,也不是没有办法的,下面就来介绍一个我们什么的方式–base64编码。Base64编码base64编码简介base64是网络上常见的用于传输8Bit字节码的编码方式之一,Base

本文目录

      使用字符流读取文件(非文本)

      以Java的字符流读取文件为例:它只能读取0-65535之间的字符,可以看出来字符都是正数,但是二进制的byte是可以为负数的。但是读取的时候会被当做正数来读取,或者是无法在编码表中找到的字符会返回一个奇怪的符号(你可能见过那个奇怪的 “?”)。

      但是在某些情况下,必须要使用字符来显示二进制数据,也不是没有办法的,下面就来介绍一个我们什么的方式–base64编码。

      Base64编码

      base64编码简介

      base64是网络上常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。Base64编码是从二进制到字符的过程,可以用在HTTP环境下传递较长的标识信息。采用Base64编码后具有不可读性,需要解码后才能阅读。它的中文名是基于64个可打印字符来表示二进制数据。

      编码规则

      1. 把3个字节变成4个字节.

      2. 没76个字符加一个换行符。

      3. 最后的结束符也要处理。

      编码方式的缺点

      从编码规则可以看出来,base64要求把每三个8Bit的字节转换成四个6Bit的字符(38 = 46 = 24),然后把6Bit再添加两位高位0,组成四个8Bit的字节。也就是说,转换后的字符串理论上将要比原来的长1/3(33%)。

      这里这是介绍一个概念,关于更加详细的内容,如果感兴趣的话,可以取收集了解更多。

      Base64在 Java 里的应用

      Java的Base64工具类提供了一套静态方法获取下面三种BASE64编解码器:

      • 基本:输出被映射到一组字符A-Za-z0-9+/,编码不添加任何行标,输出的解码仅支持A-Za-z0-9+/。

      • URL:输出映射到一组字符A-Za-z0-9+_,输出是URL和文件。

      • MIME:输出隐射到MIME友好格式。输出每行不超过76字符,并且使用’\r’并跟随’\n’作为分割。编码输出最后没有行分割。

      分别对应如下几个方法:

      Encoder basicEncoder = Base64.getEncoder();
      Encoder mimeEncoder = Base64.getMimeEncoder();
      Encoder urlEncoder = Base64.getUrlEncoder();

      我写了一个简单的工具类来进行测试 基本(basic) 的编码器。。

      package com.dragon;
      
      import java.io.BufferedInputStream;
      import java.io.ByteArrayOutputStream;
      import java.io.File;
      import java.io.FileInputStream;
      import java.io.FileNotFoundException;
      import java.io.IOException;
      import java.io.InputStream;
      import java.io.UnsupportedEncodingException;
      import java.util.Base64;
      import java.util.Base64.Decoder;
      import java.util.Base64.Encoder;
      
      /**
       * @author Alfred
       * */
      public class Base64Util {
      	private static Encoder encoder = Base64.getEncoder();
      	private static Decoder decoder = Base64.getDecoder();
      	private static String ENCODE = "UTF-8";
      	private static int LENGTH = 1024;
      	
      	/**
      	 * 静态方法:
      	 * 将文件等二进制数据(文本和非文本都可以)
      	 * 转为base64字符串。
      	 * @throws IOException 
      	 * @throws FileNotFoundException 
      	 * 
      	 * */
      	public static String dataToBase64(File src) throws FileNotFoundException, IOException {
      		Encoder encoder = Base64.getEncoder();
      		
      		int len = (int)src.length();
      		byte[] bar = new byte[(int)len];
      		int hasRead = 0;
      		byte[] b = new byte[LENGTH];
      		//使用专门处理 byte 的IO流比较方便,一次性读取较大文件对内存压力较大
      		try (InputStream in = new BufferedInputStream(new FileInputStream(src));
      				ByteArrayOutputStream bos = new ByteArrayOutputStream(len)) {
      			while ((hasRead = in.read(b)) != -1) {
      				bos.write(b, 0, hasRead);
      			}
      			bar = bos.toByteArray();
      		}
      		return encoder.encodeToString(bar);
      	}
      	
      	public static String dataToBase64(String src) throws UnsupportedEncodingException {
      		return encoder.encodeToString(src.getBytes(ENCODE));
      	}
      	
      	public static byte[] base64ToData(String src) {
      		return decoder.decode(src);
      	}
      }

      将图片转为Base64字符串进行读写

      import java.io.BufferedReader;
      import java.io.BufferedWriter;
      import java.io.File;
      import java.io.FileNotFoundException;
      import java.io.FileReader;
      import java.io.FileWriter;
      import java.io.IOException;
      import java.io.UnsupportedEncodingException;
      import java.io.Writer;
      import java.nio.file.Path;
      import java.nio.file.Paths;
      
      public class Base64Test {
      	public static void main(String[] args) throws FileNotFoundException, IOException {
      		testPic();
      	}
      	
      	static void testPic() throws FileNotFoundException, IOException {
      		// 测试图片文件。
      		Path picPath = Paths.get("./src/com/dragon/001.jpg");
      		File picFile = picPath.toFile();
      		String picToBase64 = Base64Util.dataToBase64(picFile);
      		System.out.println(picToBase64);
      		long oldSize = picFile.length();
      		long newSize = picToBase64.getBytes("UTF-8").length;
      		System.out.println("图片原始大小(字节):" + oldSize);
      		System.out.println("转换后数据大小(字节):" + newSize);
      		System.out.println("转换后比原来扩大的比例为:" + (double)(newSize-oldSize)/(double)oldSize + " %");
      		
      		//将数据写入文件
      		try (Writer writer = new BufferedWriter(new FileWriter("./src/com/dragon/002.txt"))) {
      			writer.write(picToBase64);
      		}
      		
      		//从文件中读取数据
      		String line = null;
      		try (BufferedReader reader = new BufferedReader(new FileReader("./src/com/dragon/002.txt"))){
      			line = reader.readLine();
      		}
      		System.out.println(picToBase64.equals(line));
      	}
      }

      运行截图

      Java中如何使用字符流读写二进制文件?

      说明:这里将图片转为base64字符串后,使用字符流写入了一个文本文件,然后再使用字符流读取出来,再和原来的字符串进行比较结果为 true。 所以,就完成了对图片数据的读取,可能你这里说你读取的并不是图片的二进制数据,但是其实所有的文件都是以二进制来存储的!而且,这个base64字符串,也是可以直接作为图片来使用的。

      注意:我这里已经选取了一个非常小的图片,可以看到原始大小才 3639字节,也就是不到 4 KB,但是如果转换成文字那就是不少了(所以,它会显得很长,非常长。)。

      测试图片

      Java中如何使用字符流读写二进制文件?

      然后你可能会问怎么证明这个字符串就是上面这张图片呢?这个也很好办到,如果你对前端的知识有所了解的话,应该知道前端的图片是可以使用base64字符串来表示的,下面写一个 html 文件测试一下。

      image.html

      
      
          
              
              base测试
          
          
              
          
      

      打开浏览器测试一下

      Java中如何使用字符流读写二进制文件?

      说明: 它的具体用法如下:

      图片的大小相对于字符来说,其实是很庞大了。我这里的html代码是完整的图片的base64编码字符串,然后我的博客的字数就变大了很多。

      字符串转base64编码

      public class Base64Test {
      	public static void main(String[] args) throws FileNotFoundException, IOException {
      		testStr("I love you yesterday and today!");
      	}
      	
      	static void testStr(String src) throws UnsupportedEncodingException {
      		//测试文本数据。
      		String strToBase64 = Base64Util.dataToBase64(src);
      		System.out.println("base64编码:" + strToBase64);
      		String base64ToStr = new String(Base64Util.base64ToData(strToBase64));
      		System.out.println("base64解码:" + base64ToStr);
      	}
      }

      测试截图

      Java中如何使用字符流读写二进制文件?

      base64的用处

      Base64常用于在通常处理文本数据的场合,表示、传输、存储一些二进制数据。包括MIME的email,email via MIME, 在XML中存储复杂数据。 注1:互联网上也有很多可以进行编解码的网站,如果需要使用的话,可以取尝试一下。

      注2:可以观察一下这个base64字符串的特点,我上次学习Java爬虫的时候,爬了一个网站,发现这个网站的一个 script 脚本中,含有一个json对象,其中有一个属性是 url,但是对应的链接却看不懂(base64字符串是不可读的),但是我感觉它就是base64字符串,所以我利用base64编解码网站解码一看,真的是一个网站的地址。然后,就可以写一个解码方法,当爬到这个数据时,给它解码了,哈哈。

      举一个简单的例子:

      {"url":"aHR0cHMlM0ElMkYlMkZ3d3cuYmFpZHUuY29tJTJG"}
      import java.io.UnsupportedEncodingException;
      import java.net.URLDecoder;
      import java.net.URLEncoder;
      import java.util.Base64;
      import java.util.Base64.Decoder;
      import java.util.Base64.Encoder;
      
      public class TestALittle {
      	public static void main(String[] args) throws UnsupportedEncodingException {
      		String base64Str = "aHR0cHMlM0ElMkYlMkZ3d3cuYmFpZHUuY29tJTJG";
      		String de_str = base64ToUrlEncoderToURL(base64Str);
      		System.out.println("解码:" + de_str);
      	}
      	
      	//base64解密为urlencoder,再解码为url
      	public static String base64ToUrlEncoderToURL(String base64Str) throws UnsupportedEncodingException {
      		Decoder decoder = Base64.getDecoder();
      		byte[] bt = decoder.decode(base64Str);
      		String en_str = new String(bt, 0, bt.length);
      		return URLDecoder.decode(en_str, "UTF-8");
      	}
      }

      Java中如何使用字符流读写二进制文件?

      说明: 这个例子中的 url 进行了两次编码,第一次是将url中的非西欧字符编码(可以去了解一下为什么这么做?),然后再使用base64编码。但是,如果你掌握了解码技术,解码也是很简单的。(但是如果你看不出来它是base64编码,那估计就没有办法了!)

      本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
      作者最新文章
      编程开发 Java
      相关文章 更多
      Java单元测试入门:使用JUnit 5编写第一个测试用例
      Java单元测试入门:使用JUnit 5编写第一个测试用例

      面向初学者的JUnit 5实用入门指南。从测试概念、Maven依赖配置,到手把手编写首个单元测试用例及断言验证,助你掌握Java单元测试的核心流程。

      Java变量未初始化报错解析:局部变量与成员变量默认值差异
      Java变量未初始化报错解析:局部变量与成员变量默认值差异

      深入解析Java中局部变量未初始化编译报错与成员变量自动赋予默认值的机制差异,涵盖JVM内存分配、编译期确定性赋值检查与实际排查修复方案。

      Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat
      Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat

      详细讲解在Java中获取当前系统时间并进行格式化输出的两种核心方案:基于Java 8全新日期时间API的DateTimeFormatter与传统遗留的SimpleDateFormat,包含完整代码示例、线程安全机制对比及生产选型建议。

      Java中final与static final常量的定义及初始化规则
      Java中final与static final常量的定义及初始化规则

      深入解析Java中final变量与static final常量的定义、内存语义、初始化时机及合法赋值路径,涵盖编译期常量优化与实战避坑指南。

      Java抽象方法与接口方法的区别及选型建议
      Java抽象方法与接口方法的区别及选型建议

      深入对比Java中抽象类抽象方法与接口方法的语法演进、设计意图及运行期差异,并提供清晰的架构选型决策流程与实战范例。

      Java实现HTTP请求与JSON解析的完整代码示例
      Java实现HTTP请求与JSON解析的完整代码示例

      本文提供Java标准库HttpClient发起HTTP GET/POST请求并结合Jackson进行JSON数据反序列化与序列化的完整代码示例与工程实践指南。

      Java递归出现StackOverflowError的原因分析及栈空间优化方案
      Java递归出现StackOverflowError的原因分析及栈空间优化方案

      详细分析Java递归调用出现StackOverflowError的原因,结合代码说明线程栈、栈帧和递归深度之间的关系,并介绍终止条件排查、迭代改写、减少栈帧开销以及通过-Xss调整JVM栈空间的方法。

      Java空指针异常(NPE)的代码排查与修复实例
      Java空指针异常(NPE)的代码排查与修复实例

      针对Java中常见的NullPointerException(NPE),本文从堆栈日志定位、典型代码触发场景、具体修复代码对比到防御体系进行系统讲解,提供实用且易上手的排查与修复方案。

      selenium上传文件教程本地文件路径设置方法
      selenium上传文件教程本地文件路径设置方法

      深入解析Selenium处理文件上传的技术细节,涵盖标准HTML控件的路径直接注入法与非标准控件的系统级模拟方案,提供Windows与Linux环境下的路径设置最佳实践及常见异常排查。

      大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景
      大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景

      针对大数据工程场景,系统对比Java、Scala与Python在执行性能、生态结合、开发效率和维护成本上的核心差异,给出清晰的架构选型依据与落地方案。

      查看更多
      精品专题 更多
      装机必备
      装机必备

      正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

      Windows
      Windows

      正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

      PDF教程
      PDF教程

      正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

      Mac软件 更多
      讯飞智作 网页版
      讯飞智作 网页版
      Windows/ macOS/ Linux

      讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

      火山引擎 网页版
      火山引擎 网页版
      Windows/ macOS/ Linux

      火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

      Aperty macOS版
      Aperty macOS版
      macOS

      Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

      WINDOWS 更多
      讯飞智作 网页版
      讯飞智作 网页版
      Windows/ macOS/ Linux

      讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

      火山引擎 网页版
      火山引擎 网页版
      Windows/ macOS/ Linux

      火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

      PixTV 网页版
      PixTV 网页版
      Windows

      PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。