当前课程知识点:Java程序设计 > 第五章 输入输出 > 5.3.3-写二进制文件 > 写二进制文件
大家好
欢迎回来继续学习
Java语言程序设计
这一节我们来学习
如何写二进制文件
那么为什么
我们需要二进制文件呢
因为二进制文件的写
比文本文件的写要快很多
而且同样的信息
如果写成了二进制文件的话
它占的存储空间也比文本文件
通常来说要小很多
更多的情况下
是我们的数据本身
它就不是纯文本的
无法存储为文本文件
那么这个时候当然我们就需要
把这些信息以二进制的形式
写到文件中去
我们要将数据以二进制方式
写到二进制文件中去呢
就要使用抽象类
OutputStream的一些子类
比如说它的派生类
FileOutputStream
就是用于一般目的
非字符输出的这种写操作的
它可以将数据
按成组的字节去输出
那么DataOutputStream
具有写各种基本类型数据的方法
当然了这个类也是一个处理流
它不是直接去执行写操作的
那么它是要对数据
按照类型进行一下处理
然后让数据传给另外一个输出流
有其他的输出流
去负责那个真正的写动作
那么用DataOutputStream写的话
能够在所有计算机平台上
使用同样的数据格式
而且它其中的size方法
可以作为计数器
统计一共写入了多少字节
那么这个表里列出了
DataOutputStream的
一些主要的成员
我们看到有构造方法
有清空缓冲区域的方法
有size方法来计算字节数
还有这个write方法
是写一个字节
写这个int变量的
最低的字节到文件中去
还有其他的几个write方法
是按照不同的类型去写数据
比如说写一个布尔数据
writeByte写一个字节
还有writeByte
是将一个字符串中
每个字符去掉高八位
只取低八位写出到输出流中
另外底下也都是几个
写各种基本数据类型
数据的方法都非常有用
好
接下来我们来看一个例题
将int数据写到二进制文件中去
在这个例题中
我们希望将三个int类型的
整数255 0和负1
写到一个数据文件中去
我们希望以二进制的形式
写到文件中去
而不是说写文本出去
那好我们首先要准备好
这个文件名字符串
准备好文件名字符串
还有准备好这三个
要写入的整数
接下来就要构造输出流对象
去关联到这个文件了
好
我们用文件名字符串作为参数
首先构造一个FileOutputStream
这个FileOutputStream
它就是一个原生字节流
只识别写出去的是一个一个字节
没法识别写出去的是什么int double
这些数据类型没法识别
怎么让它能够识别数据类型呢
我们还要在外面套一个处理流
接一个处理流DataOutputStream
这个DataOutputStream
就是可以将字节
首先处理成一个一个的
某种类型的数据
那这个DataOutputStream
它有这个一系列的write方法
在这里我们用了write int
去连续写入了三个整数
然后把它关闭
同样操作文件放在try块后
后面要有catch块来捕获
这个程序运行以后
就会生成一个数据文件data1.dat
这个时候我们不能用写字板
或者记事本去打开去看它
因为它不是个文本文件了
我们必须要用一个
可以阅读二进制数据的这样一个编辑器来看它
比如说ultraEdit
我们用ultraEdit
来打开就会看到里面是十六进制码的形式
从十六进制转回二进制
大家也很清楚了
一个十六进制位是四个二进制位
好
那么而每个int数据都是32位的
四个字节的
那这个时候我们可以看一下
我们写进去的就是这样的内容
下面我们就来看这个缓冲流类
当我们要需要写大量数据的时候
用这个缓冲流类能够提高写的效率
这里给出了使用
BufferedOutputStream的一个小的例子
我们看到这个
BufferedOutputStream
它也是一个处理流
它是进行缓冲的
所以它不是直接
进行那个写操作的
那构造这个BufferedOutputStream
还需要另外一个输出流
比如说我们在这个例子里边
我们先构造一个
FileOutputStream对象
以它作为参数去构造BufferedOutputStream
这是一个起缓冲作用的
当然了在这个基础之上
如果我们还需要
其他的处理功能的话
可以继续以它为参数
去构造另外一个处理流
比如说这里我们又以BufferedOutputStream对象
为参数去构造一个DataOutputStream
这样我们既可以缓冲
又可以按类型去写数据
接下来我们就看一个例子
这个例子向文件中
按类型写入了多种类型的数据
现在我们继续来使用这个DataOutputStream
还是按类型写入
这回我们混合着写多个类型的数据
首先同样还是
要构造一个输出流对象
在原生字节输出流
对象的基础上
构造一个缓冲的
BufferedOutputStream
这为了提高写的效率
那接下来再接一个
DataOutputStream
这样的话就能够按照类型
去写二进制数据了
首先调用writeInt写了一个整数
然后调用writeDouble
又写了一个Double类型的数据
然后调用writeBytes
写了连续的若干字节
相当于写了一个字符串进去
每一次写完了以后
我们都显示一个信息看一下
当前这个DataOutputStream对象
DataOut它自打开以后到目前为止
一共写了多少个字节
每次都显示一下
这个显示的不是说
刚刚这一次写了多少个字节
而是总共从这个流对象打开
到目前为止一共写了多少个字节
好
在这个程序中我们没有捕获异常
所以声明了抛出异常
写完了以后我们
就关闭文件结束程序
那我们看到运行结果确实验证了
它给出的字节数
不是刚刚写入的字节数
而是到目前为止
总共写入的字节数
接下来这个例子就向文件中
写入内容为负1的一个字节
并且读取出来
这个我们还是用这个DataOutputStream
去按照类型去写
构造输出流对象的过程
仍然是一样的
那这个时候首先我们用writeByte方法
将负1写出去
writeByte方法
它是写一个字节写一个字节
那么写到文件中以后关闭它
如果这个时候
我们用这个二进制的编辑器打开看一下的时候
会看到写入的内容是FF就是八位
八位全都是1
那么就是二进制的补码负1
接下来我们再把它读回来
读回来用对应的DataInputStream
它是跟DataOutputStream是对应的
它可以按类型来读
所以在我们构造一个
FileInputStream
这个原生字节的输入流之后
在上面再接一个DataInputStream
它可以按照类型读
那么我们也用这个readByte
把它读进来
readByte它读进来以后
大家看赋值给了一个int数据
只读一个字节
怎么去赋值给int数据呢
实际上它高位都补1了
这个readByte读进来以后
赋值给这个int高位都补1了
所以结果还是全1就是负1
接下来我们输出验证一下
输出的时候我们把这个变量a
转成十六进制的字符串输出
然后我们看到输出的全都是f
一个f就是四个1
那也就是说这个int数据里面
二进制值放的全都是1
那就是二进制的补码负1
如果说我们就直接输出a
不是按十六进制的字符串
形制输出
我们就看到了
这个有符号的整数负1在这儿输出
好
现在我们再重新读一遍
用这个skip这个方法
参数给它负1
就是往后退一个位置
就刚才读过的数据
你退回去到刚才那个位置
再重读
我们再重新用什么呢
用readUnsignedByte
这个方法去读
读出来以后依然要赋值给a
那么这个时候
它的结果是高位都补0的
因为它是按照
无符号的一个字节来读的
readByte虽然读一个字节
但是认为它是一个有符号的数
所以高位补符号位
不是说总补1它是补符号位
如果你补的是正数
当然它就补0了
就是readUnsignedByte
就把它作为一个字节读进来
它又是无符号的数
所以高位就补0
这个时候
我们依然把a里面的内容
转换成十六进制字符串输出
我们看到补0的
它肯定就不输出了它只有ff
那接下来再输出一遍a本身
那这个低八位全1
如果把它认为是一个无符号数
就当做绝对值来看的话
那是什么呢
我们看到输出的结果是255
这个我们就看到writeByte
和readByte这两个方法
还有readUnsignedByte
这个方法它们的功能是什么
好
这一节我们学习了
如何向二进制文件中写数据
这节内容就是这些
-1.0-导学
--1.0-导学
-1.1-Java与面向对象程序设计简介
--第一章 Java语言基础知识--1.1-Java与面向对象程序设计简介
-1.2-基本数据类型与表达式
-第一章 Java语言基础知识--1.2-基本数据类型与表达式
-1.3-数组
--1.3.1-数组
-第一章 Java语言基础知识--1.3-数组
-1.4-算法的流程控制
--第一章 Java语言基础知识--1.4-算法的流程控制
-1.5-第一章小结
-第一章编程练习题
-课件
--外部链接
-Java环境配置、Eclipse使用、Helloworld程序详解
--使用eclipse建立Java项目、编写和运行Java程序
-Java数据类型
--Java整数类型
--Java浮点类型
--数据类型实战
--数据类型转换
--Java强制类型转换精度损失示例与表达式中的数据类型转换
-Java数组
-Java变量
--Java的变量
-命令行参数
--命令行参数的介绍
-2.0-导学
--2.0-导学
-2.1-面向对象方法的特性
--第二章 类与对象--2.1-面向对象方法的特性
-2.2-1-类声明与对象创建
--第二章 类与对象--2.2-1-类声明与对象创建
-2.2-2-数据成员
--第二章 类与对象--2.2-2-数据成员
-2.2-3-方法成员
--第二章 类与对象--2.2-3-方法成员
-2.2-4-包
--2.2-4-包
--第二章 类与对象--2.2-4-包
-2.2-5-类的访问权限控制
--第二章 类与对象--2.2-5-类的访问权限控制
-2.3-1-对象初始化
--第二章 类与对象--2.3-1-对象初始化
-2.3-2-内存回收
--第二章 类与对象--2.3-2-内存回收
-2.4-枚举类
--2.4-枚举类
--第二章 类与对象--2.4-枚举类
-2.5-应用举例
--2.5-应用举例
-2.6-第2章小结
-第二章编程练习题
-课件
--第二章课件
-3.0-导学
--3.0-导学
-3.1.1-3.1.2-类继承的概念和语法
--第三章 类的重用--3.1.1-3.1.2-类继承的概念和语法
-3.1.3-隐藏和覆盖
--第三章 类的重用--3.1.3-隐藏和覆盖
-3.2-Object 类
--第三章 类的重用--3.2-Object 类
-3.3-终结类与终结方法
--第三章 类的重用--3.3-终结类与终结方法
-3.4-抽象类
--3.4-抽象类
--第三章 类的重用--3.4-抽象类
-3.5-泛型
--3.5-泛型
--第三章 类的重用--3.5-泛型
-3.6-类的组合
--3.6-类的组合
-3.7-小结
--3.7-小结
-第三章编程练习题
-课件
--课件
-4.0-导学
--导学
-4.1-接口
--接口
--第四章 接口与多态--4.1-接口
-4.2.1-4.2.2-类型转换
--类型转换
--第四章 接口与多态--4.2.1-4.2.2-类型转换
-4.2.3-方法的查找
--方法的查找
--第四章 接口与多态--4.2.3-方法的查找
-4.3-多态的概念
--多态的概念
--第四章 接口与多态--4.3-多态的概念
-4.4-多态的应用举例
--多态的应用举例
--第四章 接口与多态--4.4-多态的应用举例
-4.5-构造方法与多态性
--构造方法和多态性
--第四章 接口与多态--4.5-构造方法与多态性
-4.6-本章小结
--本章小结
-第四章编程作业
-课件
--课件
-5.0-导学
--5.0-导学
-5.1.1-5.1.2-异常处理的概念
--第五章 输入输出--5.1.1-5.1.2-异常处理的概念
-5.1.3-5.1.5-异常的处理
--第五章 输入输出--5.1.3-5.1.5-异常的处理
-5.2-输入输出流的概念
--输入输出流的概念
--第五章 输入输出--5.2-输入输出流的概念
-5.3.1-写文本文件
--写文本文件
--第五章 输入输出--5.3.1-写文本文件
-5.3.2-读文本文件
--读文本文件
--第五章 输入输出--5.3.2-读文本文件
-5.3.3-写二进制文件
--写二进制文件
--第五章 输入输出--5.3.3-写二进制文件
-5.3.4-读二进制文件
--读二进制文件
-5.3.5-File类
--File类
-5.3.6-处理压缩文件
--处理压缩文件
-5.3.7-对象序列化
--对象序列化
-5.3.8-随机文件读写
--随机文件读写
-5.4-本章小结
--本章小结
-课件
--课件
-6.0-导学
--导学
-6.1-Java集合框架介绍
--第六章 对象群体的组织--6.1-Java集合框架介绍
-6.2-主要接口及常用的实现类
--第六章 对象群体的组织--6.2-主要接口及常用的实现类
-6.3-常用算法
--常用算法
-6.4-数组实用方法
-6.5-基于动态数组的类型(Vector, ArrayList)
--基于动态数组的类型(Vector, ArrayList)
-6.6-遍历Collection
-6.7-Map接口及其实现
-6.8-第6章小结
--第6章小结
-课件
--课件
-7.0-导学
--导学
-7.1-绘图
--绘图
-7.2-Swing基础
--Swing基础
-7.3-Swing的层次
--Swing的层次
-7.4-布局管理
--布局管理
-7.5-内部类
--内部类
-7.6-事件处理的基本概念
-7.7-事件派发机制
--事件派发机制
-7.8-顶层容器
--7.8-顶层容器
-7.9-中间层容器(一)
-7.10-中间层容器(二)
-7.11-原子组件(一)
-7.12-原子组件(二)
-7.13-原子组件(三)
-7.14-其它Swing特性
-7.15-第7章小结
-课件
--课件