Java---IO加强(1)
RandomAccessFile
★随机访问文件,自身具备读写的方法。
new RandomAccessFile()之后,若文件不存在会自动创建,存在则不创建。——该类其实内部既封装了字节输入流,又封装了字节输出流。
该类若用write()方法写整数,每次只写它的最后一个字节。而采用writeInt()方法,则可把一个整数完整地写入。
★通过skipBytes(int x),seek(int x)来达到随机访问。
通过seek方法设置数据的指针就可以实现对文件数据的随机读写。InputStream中的skip()方法只能从头往后跳,不能反向;而seek()方法可双向随便定位。
★数据修改方面的特点
用RandomAccessFile类可以实现数据的修改,当然文件中的数据一般要有规律,以方便在编程时能够进行定位,让数据写对地方。
而用“流”实现数据修改时,则通常需要把数据从流读到数组当中,在数组中进行数据修改,然后再把修改后的数组再重新写到流中。
序列化
★ 序列化介绍
将一个对象存放到某种类型的永久存储器上称为保持。如果一个对象可以被存放到磁盘或磁带上,或者可以发送到另外一台机器并存放到存储器或磁盘上,那么这个对象就被称为可保持的。(在Java中,序列化、持久化、串行化是一个概念。)
java.io.Serializable接口没有任何方法,它只作为一个“标记者”,用来表明实现了这个接口的类可以考虑串行化。类中没有实现Serializable的对象不能保存或恢复它们的状态。
(用IO流将数据读入文件都叫序列化)
★ 对象图
当一个对象被串行化时,只有对象的数据被保存;方法和构造函数不属于串行化流。如果一个数据变量是一个对象,那么这个对象的数据成员也会被串行化。树或者对象数据的结构,包括这些子对象,构成了对象图。
★ 瞬时 transient
防止对象的属性被序列化。
演示transient:
package io.sreializable;
import java.io.Serializable;
/**
* 对象类
* @author 陈浩翔
*
* 2016-4-22
*/
public class Address implements Serializable{//实现可序列化接口
//静态变量是不会被序列化的。对于非静态变量,一般情况下都会被序列化,但如果声明成transient型则不会。
private static String address;//静态变量不属于对象的!
transient int num;//瞬时变量---该变量是不会被序列化的---不会出现在对象图中的
private String Name;//姓名
private int age;//年龄
private String tel;//电话
public Address(int num, String name, int age, String tel) {
this.num = num;
Name = name;
this.age = age;
this.tel = tel;
}
public static String getAddress() {
return address;
}
public static void setAddress(String address) {
Address.address = address;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((Name == null) ? 0 : Name.hashCode());
result = prime * result + age;
result = prime * result + ((tel == null) ? 0 : tel.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Address other = (Address) obj;
if (Name == null) {
if (other.Name != null)
return false;
} else if (!Name.equals(other.Name))
return false;
if (age != other.age)
return false;
if (tel == null) {
if (other.tel != null)
return false;
} else if (!tel.equals(other.tel))
return false;
return true;
}
@Override
public String toString() {
return "Address [num=" + num + ", Name=" + Name + ", age=" + age
+ ", tel=" + tel + "]";
}
}
package io.sreializable;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
*
* @author 陈浩翔
*
* 2016-4-22
*/
public class Serializable {
//直接抛异常了。。。做项目千万不要这样
public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
Address a1 = new Address(1, "aaa", 23, "12345678911");
Address a2 = new Address(2, "bbb", 24, "12345678912");
Address a3 = new Address(3, "ccc", 25, "12345678913");
Address a4 = new Address(4, "ddd", 26, "12345678914");
Address a5 = new Address(5, "eee", 27, "12345678915");
//对象序列化---输出,写
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("hx.txt"));
out.writeObject(a1);
out.writeObject(a2);
out.writeObject(a3);
out.writeObject(a4);
out.writeObject(a5);
out.close();
//反序列化----读
ObjectInputStream in = new ObjectInputStream(new FileInputStream("hx.txt"));
System.out.println(in.readObject());
System.out.println(in.readObject());
System.out.println(in.readObject());
System.out.println(in.readObject());
System.out.println(in.readObject());
//如果对象读完了,还读文件,就会抛出EOF异常java.io.EOFException
}
}
运行图片:
可以看到,瞬时变量的值并没有被存储起来,也就是没有被序列化!!
缓冲输入输出流
介绍:
(BufferedInputStream和BufferedOutputStream)
第一种方式:
DataInputStream in = new DataInputStream(
new BufferedInputStream(
new FileInputStream("Test.txt"));
第二种方式:
DataInputStream in = new DataInputStream(
new FileInputStream("Test.txt"));
第三种方式:
BufferedInputStream in = new BufferedInputStream(
new DataInputStream(
new FileInputStream("Test.java"));
下面我们来看实现它们运行速度的比较:
因为BufferedInputStream并没有一次读一行的方法,只能读字节,
所以在文件中,我存储的是一行占97个字节的字符串。
我让它一次读97个字节,所以和另外2种一次读一行也就差不多了。。
这是存一行字符串的时候的文件大小:
后面的字符串,每行都和第一行的一样大小!
文件一共112KB。
运行代码:
package io.buffer;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
/**
* 测试3种方法 流 的读取速度
* @author 陈浩翔
*
* 2016-4-22
*/
public class BufferedStreamDemo {
//在这里,我们简化了,直接抛异常了。
public static void main(String[] args) throws Exception {
//test1();
//test2();
test3();
}
/**
* 先new缓冲流
* @throws Exception
*/
private static void test3() throws Exception {
long time1 = System.currentTimeMillis();
BufferedInputStream in = new BufferedInputStream(
new DataInputStream(
new FileInputStream("chx.txt")));
byte b[] = new byte[97];
int n = 0;
while((n=in.read(b))!=-1){
System.out.println(new String(b,0,n));
}
long time2 = System.currentTimeMillis();
System.out.println((time2-time1)+"毫秒");
//测试程序运行时间需要多次运行取平均值的
}
/**
* 不用缓冲流
* @throws Exception
*/
private static void test2() throws Exception {
long time1 = System.currentTimeMillis();
DataInputStream in = new DataInputStream(
new FileInputStream("chx.txt"));
String str = null;
while((str=in.readLine())!=null){
System.out.println(str);
}
long time2 = System.currentTimeMillis();
System.out.println((time2-time1)+"毫秒");
//测试程序运行时间需要多次运行取平均值的
}
/**
* 在中间new缓冲流
* @throws Exception
*/
private static void test1() throws Exception {
long time1 = System.currentTimeMillis();
DataInputStream in = new DataInputStream(
new BufferedInputStream(
new FileInputStream("chx.txt")));
String str = null;
while((str=in.readLine())!=null){
System.out.println(str);
}
long time2 = System.currentTimeMillis();
System.out.println((time2-time1)+"毫秒");
//测试程序运行时间需要多次运行取平均值的
}
}
运行结果:
我是取多次运行后,最接近平均值来截图的!
第一种方式运行后的结果:
第二种方式运行后的结果:
第三种方式运行后的结果:
☆示例测试技术总结:
可以清楚的看到,第一种方式所用的时间是最短的!!!!
第二种方式最慢,和第一种方法相比,慢了8倍!!!!
方案1是最优的
1)有buffer比没有更快;
2)buffer放在中间层包装比放在外层更快;
3)按行或按块操作 比 按字节或字符操作更快(用Object流操作的速度 比 字节字符方式 更快)
4)缓冲区要结合流才可以使用,在流的基础上对流的功能进行了增强。
Java---IO加强(1)的更多相关文章
- java.IO输入输出流:过滤流:buffer流和data流
java.io使用了适配器模式装饰模式等设计模式来解决字符流的套接和输入输出问题. 字节流只能一次处理一个字节,为了更方便的操作数据,便加入了套接流. 问题引入:缓冲流为什么比普通的文件字节流效率高? ...
- Java:IO流与文件基础
Java:IO流与文件基础 说明: 本章内容将会持续更新,大家可以关注一下并给我提供建议,谢谢啦. 走进流 什么是流 流:从源到目的地的字节的有序序列. 在Java中,可以从其中读取一个字节序列的对象 ...
- Java IO之字符流和文件
前面的博文介绍了字节流,那字符流又是什么流?从字面意思上看,字节流是面向字节的流,字符流是针对unicode编码的字符流,字符的单位一般比字节大,字节可以处理任何数据类型,通常在处理文本文件内容时,字 ...
- java Io流向指定文件输入内容
package com.hp.io; import java.io.*; public class BufferedWriterTest{ public static void main(String ...
- java Io文件输入输出流 复制文件
package com.hp.io; import java.io.FileInputStream; import java.io.FileNotFoundException; import java ...
- java Io流更新文件内容
package com.hp.io; import java.io.FileOutputStream; import java.io.IOException; public class FileOut ...
- java IO流详解
流的概念和作用 学习Java IO,不得不提到的就是JavaIO流. 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...
- java.io.NotSerializableException: test.io.file.Student
java.io.NotSerializableException: test.io.file.Student at java.io.ObjectOutputStream.writeObject0 ...
- java.io.IOException: mark/reset not supported
java.io.IOException: mark/reset not supported at java.io.InputStream.reset(InputStream.java:348) at ...
- Java IO流学习总结
Java流操作有关的类或接口: Java流类图结构: 流的概念和作用 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...
随机推荐
- [c#]如何在form的webbrowser控件中获得鼠标坐标
如图这样,其实是要插入一个time的控件,这样才能使得坐标值会根据鼠标的移动而不停变化.time插件中写private void timer1_Tick(object sender, EventArg ...
- 刨根问底:对于 self = [super init] 的思考
对象初始化有两种方式:[class new] 与 [[class alloc] init] 对于后者,有分配和初始化的过程,alloc 从应用程序的虚拟地址空间上为该对象分配足够的内存,并且将新对象的 ...
- Day5 - Python基础5 常用模块学习
Python 之路 Day5 - 常用模块学习 本节大纲: 模块介绍 time &datetime模块 random os sys shutil json & picle shel ...
- 9.5noip模拟试题
题目名称 正确答案 序列问题 长途旅行 英文名称 answer sequence travel 输入文件名 answer.in sequence.in travel.in 输出文件名 answer.o ...
- Win10中英文的切换
在UAP中,涉及到中英文版本切换,在string目录下面添加资源str 读取的时候 new Windows.ApplicationModel.Resources.ResourceLoader().Ge ...
- css.day02
1.复合选择器 复合选择器 一般会有几个标签混合使用 .把多个组合成一个 称之为复合 1.1标签指定式 复合选择器 (交集选择器) 格式: 标记选择器+ 类名/ID名称 { 属性:值;} 实际情况用 ...
- oracle系统包——dbms job用法(oracle定时任务)
用于安排和管理作业队列,通过使用作业,可以使ORACLE数据库定期执行特定的任务. 一.dbms_job涉及到的知识点1.创建job:variable jobno number;dbms_job.su ...
- Oracle Pivot学习心得
今天在做一个查询报表需要将多行的查询结果转换成一行,数据格式如下 ID Type Parameter Value Machine_NO Operator UpdateTime 1 11111111 ...
- Asp.net 主题 【2】
通常我们经常看到网页,一些软件提供换肤功能,各种主题间切换.ASP.NET 2.0 中可以用Theme和skin以及CSS轻松实现这个功能. 首先简单介绍一下三种技术:主题(Theme)技术,面板(s ...
- 绘图时,根据size()和自定义rect编程的区别
在绘图的时候,很多时候编写的代码需要根据当前窗口自身的size来进行绘制,这个时候可以添加一个额外的中间rect来做过度,这样以后的绘图机制不会 随着size的变化而不断变化.你的处理逻辑可以保持不变 ...