Java读写二进制数据
import java.io.*;
import java.time.LocalDate;
public class Test {
public static void main(String[] args){
RandomAccessTest.test();
}
}
/*
2.3 读写二进制数据
*/
/*
2.3.2 随机访问文件
写了大半天,突然发现这个实验好像不是太严谨:
1.RandomAccessFile算长度时,应该是根据字节数算出来的
2.写字符串时,我们只是指定了码元数量,我们写的是固定码元数量的字符串
3.这样的化,我们记录的Employee.RECORD_SIZE根本就代表不了一条记录的长度
4.但是我们最后又通过RandomAccessFile的长度和Employee.RECORD_SIZE来计算记录数量
5.我觉得这个实验有问题,以后研究吧
*/
class Employee {
private String name;
private double salary;
private LocalDate hireDay;
public static final int NAME_SIZE = 30;
public static final int RECORD_SIZE = 50;
public Employee(String name, double salary, LocalDate hireDay) {
this.name = name;
this.salary = salary;
this.hireDay = hireDay;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public LocalDate getHireDay() {
return hireDay;
}
public void setHireDay(LocalDate hireDay) {
this.hireDay = hireDay;
}
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", salary=" + salary +
", hireDay=" + hireDay +
'}';
}
}
class DataIO {
//Java核心技术 卷二 第十版 2.3.2节
//写出从字符串开头开始的指定数量的码元,如果码元过少,该方法会用‘0’来补齐字符串
public static void writeFixedString(String s, int size, DataOutput output) throws IOException {
for (int i = 0; i < size; i++) {
char ch =0;
if(i<s.length())
ch = s.charAt(i);
output.write(ch);
}
}
//Java核心技术 卷二 第十版 2.3.2节
//从输入流中读入字符,直至读入size个码元,或者直至遇到具有0值的字符串,然后跳出输入字段中剩余的0值。
public static String readFixedString1(int size, DataInput in) throws IOException {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < size; i++) {
char c;
if ((c = in.readChar()) != 0) {
sb.append(c);
}
}
return sb.toString();
}
//功能和上一个方法是一样的,但是这个效率会高那么一点点
public static String readFixedString2(int size, DataInput in) throws IOException {
StringBuilder sb = new StringBuilder();
/*
int i;
for (i = 0; i < size; i++) {
char c;
if ((c = in.readChar()) == 0) {
break;
}
sb.append(c);
}
in.skipBytes(2*(size-i)); //这个地方不是太严谨
*/
//用书中代码测试一下
int i =0;
boolean more = true;
while (more && i < size) {
char ch = in.readChar();
i++;
if (ch == 0) {
more = false;
} else {
sb.append(ch);
}
}
in.skipBytes(2 * (size - i));
return sb.toString();
}
}
class RandomAccessTest {
public static void test() {
Employee[] staff = new Employee[]{
new Employee("A", 10, LocalDate.now()),
new Employee("B", 20, LocalDate.now()),
new Employee("C", 30, LocalDate.now())
};
//写入
try(DataOutputStream out = new DataOutputStream(new FileOutputStream("employee1.dat"))) {
for (Employee e : staff) {
writeData(out, e);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//读取
try(RandomAccessFile in = new RandomAccessFile("employee1.dat","r")) {
int n = (int) (in.length() / Employee.RECORD_SIZE);
Employee[] newStaff = new Employee[n];
for (int i = n - 1; i >= 0; i--) {
in.seek(i*Employee.RECORD_SIZE);
newStaff[i] = readDate(in);
}
for (Employee e : newStaff) {
System.out.println(e);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void writeData(DataOutput out, Employee employee) throws IOException {
DataIO.writeFixedString(employee.getName(), Employee.NAME_SIZE, out);
out.writeDouble(employee.getSalary());
LocalDate hireDay = employee.getHireDay();
out.writeInt(hireDay.getYear());
out.writeInt(hireDay.getMonthValue());
out.writeInt(hireDay.getDayOfMonth());
}
private static Employee readDate(DataInput input) throws IOException {
String name = DataIO.readFixedString2(Employee.NAME_SIZE, input);
double salary = input.readDouble();
int
y= input.readInt(),
m= input.readInt(),
d= input.readInt();
return new Employee(name, salary, LocalDate.of(y, m, d));
}
}
/*
2.3.3 ZIP文档
ZipFile API:
ZipFile(String name)
ZipFile(File file)
Enumeration entries()
ZipEntry getEntry(String name)
InputStream getInputStream(ZipEntry ze)
String getName()
从这个类的API中可以看出来,还有一种使用Zip的方案。先通过ZipFile对象,得到
这个压缩包中的每一条记录,然后再指定某条具体的记录,得到其中的数据。
*/
《Java核心技术卷二》笔记
Java读写二进制数据的更多相关文章
- IO流-文本IO\读写二进制数据
文本IO 一.简述 OutputStreamWriter类使用选定的编码方式吧Unicode字符流转换为字节流,InputStreamReader类将包含字节的输入流转为可以产生Unicode字符的读 ...
- 背水一战 Windows 10 (89) - 文件系统: 读写文本数据, 读写二进制数据, 读写流数据
[源码下载] 背水一战 Windows 10 (89) - 文件系统: 读写文本数据, 读写二进制数据, 读写流数据 作者:webabcd 介绍背水一战 Windows 10 之 文件系统 读写文本数 ...
- [Java] 读写字节数据,过滤流DataOutputStream和DataInputStream
package test.stream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io ...
- [Java] 读写字符串数据
package test.stream; import java.io.FileInputStream; import java.io.FileNotFoundException; import ja ...
- Java/Android 二进制数据与String互转
将经过加密的二进制数据保存到本地的方法 byte[] src = new byte[] { 122,-69, -17, 92, -76, 52, -21, -87, -10, 105, 76, -75 ...
- SQLite入门(二)读写二进制数据
//读二进制数据的函数 BOOL OpenBinDataFile(BYTE **pBUf,UINT &len) { if (pBUf == NULL) { re ...
- java读写串口数据
本博文参考自https://www.cnblogs.com/Dreamer-1/p/5523046.html 最近接触到了串口及其读写,在此记录java进行串口读写的过程. 1.导入串口支持包 需要下 ...
- java:判断二进制数据中第n位是否为1
可以使用位运算来判断. &是位的与运算符,是指二进制数按位“与”的操作, 逻辑与就是两者都为真的时候才为真,其他真假,假真,假假的运算结果都是假.二进制写法如下 1 & 1 = 1 , ...
- Qt里怎么处理二进制数据
Qt里有个专门的类QDataStream就是专门读写二进制数据的, 它与QByteArray搭配在网络编程中有奇效. 来个栗子: // write data QByteArray data; QDat ...
随机推荐
- Android零基础入门第11节:简单几步带你飞,运行Android Studio工程
原文:Android零基础入门第11节:简单几步带你飞,运行Android Studio工程 之前讲过Eclipse环境下的Android虚拟设备的创建和使用,现在既然升级了Android Studi ...
- 安卓ImageButton圆角按钮设置
首先图片要做成圆角的,使用美图秀秀,这个不多说. 之后使用设置了圆角的按钮,效果有缺陷,按钮会有灰色的边角. 类似这样: 去掉的方法是将layout的 android:src="@draw ...
- nltk处理文本
nltk(Natural Language Toolkit)是处理文本的利器. 安装 pip install nltk 进入python命令行,键入nltk.download()可以下载nltk需要的 ...
- MinGW gcc 生成动态链接库 dll 的一些问题汇总(由浅入深,很详细)
网络上关于用 MinGW gcc 生成动态链接库的文章很多.介绍的方法也都略有不同.这次我在一个项目上刚好需要用到,所以就花了点时间将网上介绍的各种方法都实验了一遍.另外,还根据自己的理解试验了些网上 ...
- Silverlight Virtualization Overview
当ListBox使用StackPanel作为容器时,如果数据源包含大量数据时,每一条数据都要创建可视化的Item来承载数据,创建这些容器就需要消耗很多时间和内存,另外滚动也非常慢,因为需要计算所有这些 ...
- SYN4505型 标准同步时钟
SYN4505型 标准同步时钟 标准同步时钟电厂时间同步使用说明视频链接: http://www.syn029.com/h-pd-245-0_310_1_-1.html 请将此链接复制到浏览器打开观看 ...
- 02、MySQL—数据库基本操作
数据库是数据存储的最外层(最大单元) 1.创建数据库 基本语法:create database 数据库名字 [库选项]; 范例:使用create database 创建数据库 库选项:数据库的相关属性 ...
- Django之用户认证auth模块使用
Auth认证模块 执行数据库迁移的那两条命令时,即使我们没有建表,django是不是也会创建好多张表?我们创建之后去看一下里面的一个叫auth_user表,既然是表,那肯定应该有对应的操作改表的方法 ...
- Spring Framework 组件注册 之 @Import
Spring Framework 组件注册 之 @Import 写在前面 向spring中注册组件或者叫javaBean是使用spring的功能的前提条件.而且spring也提供了很多种方式,让我们可 ...
- JS工具整理
1.获取今日日期:摘抄地址:https://www.cnblogs.com/carekee/articles/1678041.html getTodayFmt('yyyy-MM-dd') getTod ...