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 ...
 
随机推荐
- UWP中的消息提示框(一)
			
不管什么平台,应用内难免会出现一些消息提示框,下面就来聊聊我在UWP里用到的消息提示框. 弹窗也可按是否需要用户操作促发一些逻辑进行分为两大类. 不需要用户干涉的一类: MessageDialog:操 ...
 - MyCat的初步了解
			
MyCat 1 开源数据库中间件 MyCat 如今随着互联网的发展,数据的量级也是撑指数的增长,从GB到TB到PB.对数据的各种操作也是愈加的困难,传统的关系性数据库已经无法满足快速查询与插入数据 ...
 - <%@ Application Codebehind="Global.asax.cs" Inherits="XXX.MvcApplication" Language="C#" %>
			
<%@ Application Codebehind="Global.asax.cs" Inherits="XXX.MvcApplication" Lan ...
 - Mono 4.0 发布,开源跨平台 .Net 框架
			
快速使用Romanysoft LAB的技术实现 HTML 开发Mac OS App,并销售到苹果应用商店中. <HTML开发Mac OS App 视频教程> 土豆网同步更新:http: ...
 - 一个基于jQuery写的弹窗效果(附源码)
			
最近项目中频繁遇到需要弹出窗口的功能,一直使用浏览器默认的Alert和Confirm弹窗,感觉视觉效果不是那么好,而从网上下载的话又找不到合适的,找到的话有些也是十分臃肿,有时候感觉学习配置的功夫自己 ...
 - Spring Cloud Stream整合RabbitMQ
			
简介 Spring Cloud Stream是一个构建消息驱动微服务的框架,应用程序通过input(相当于consumer).output(相当于producer)来与Spring Cloud Str ...
 - php.ini Xdebug配置
			
在此记录: xdebug.profiler_output_dir="H:\install\phpStudy\tmp\xdebug"xdebug.trace_output_dir=& ...
 - 【LEETCODE】32、LeetCode的第35题,查找插入的位置
			
凉凉,看来想做好一个题还不容易啊... 有点难受... 1.看看题目吧 Given a sorted array and a target value, return the index if the ...
 - python Trojan 模块(我忘记几了)—— 通信隧道建立
			
0X01 SSH的建立 我想,第一步先实现简单的ssh通信再说,类似其他那种高端的C&C将逐步研究 对于ssh,python有个module叫paramiko,对没错看起来像日语单词 The ...
 - 修改linux(kali)和windows双系统下默认启动系统和启动延时
			
我的公众号,正在建设中,欢迎关注: windows和kali双系统安装完成后kali是默认的启动系统,现将windows设置为默认启动系统并更改选择系统等待时间 1.开机时当运行到系统选择菜单时记下w ...