1.IS与OS
1)输入与输出
JAVA IO
IO:input,output 输入与输出
java用输入与输出两个方向表示读写操作:
输入:从外界到我们写的程序的方向,是读数据的操作
输出:从我们写的程序到外界的方向,是写数据的操作
2)节点流与处理流
java将流分为两类:节点流和处理流
节点流:又称为低级流,是真实连接程序与另一端的"管道",负责实际搬运数据的流。读写一定是建立在节点流的基础上进行的。
处理流:又称为高级流或过滤流,不能独立存在,必须连接在其他流上,这样当数据流经当前流时可以对其做某种加工处理,来简化我们对该数据的操作
3)IS与OS常用方法
(1)文件流
文件流:java.io.FileInputStream和FileOutputStream
文件流是一对低级流,用于读写文件中的数据。功能与RAF一致,但是读写形式不同,RAF是基于指针的随机读写形式,而文件流是基于JAVA标准IO的顺序读写形式,读写的灵活度不如RAF,但是借助强大的流连接可以完成很多RAF不容易完成的工作。
(2)创建FOS对象(重写模式)
public class FOSDemo {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("fos.txt");
String line = "南大街啊哈附件还房贷福怕才能字符串啊啊吉萨u";
byte[] data = line.getBytes("UTF-8");
fos.write(data);
System.out.println("写出完毕!");
fos.close();
}
}
(3)创建FOS对象(追加模式)
public class FOSDemo {
public static void main(String[] args) throws IOException {
//向文件中写入一行字符串
/*
文件流的常用的构造器:
FileOutputStresm(String fileName)
FileOutputStresm(File file)
以上两种方式创建的文件流逝覆盖模式,即:如果指定的文件已经存在,
则会将该文件原有的数据清除,之后通过当前写出的内容都会写入到文件中
FileOutputStresm(String fileName,boolean append)
FileOutputStresm(File file,boolean append)
重载的构造器允许我们在传入宇哥boolean值参数,如果该值为true
则是追加模式,操作的文件存在时该文件原有的内容都保留,通过当前流写入的数据会陆续追加到文件末尾
*/
// FileOutputStream fos = new FileOutputStream("fos.txt");
FileOutputStream fos = new FileOutputStream("fos.txt",true);
String line = "南大街啊哈附件还房贷福怕才能字符串啊啊吉萨u";
byte[] data = line.getBytes("UTF-8");
fos.write(data);
// String line = "来个华子";
// byte[] data = line.getBytes("UTF-8");
// fos.write(data);
System.out.println("写出完毕!");
fos.close();
}
}
3)创建FIS对象
import java.io.*;
public class FISDemo {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("fos.txt");
//1从文件中将字节都读取回来
byte[] data = new byte[2014];
int len = fis.read(data);
System.out.println("实际读取了"+len+"个字节");
//2将字节还原为字符串
String str = new String(data,0,len,"UTF-8");
System.out.println(str.length());
System.out.println(str);
fis.close();
}
}
(4)read()和write(int d)方法
import java.io.*;
/**
* 使用文件流完成文件的复制,利用块读写方法进行复制
* 1:创建文件输入流读取源文件
* 2:创建文件输出流写复制的文件
* 3:循环从源文件读取一组数字(10k)并写入复制文件
* 4:关闭流
*/
public class CopyDemo {
public static void main(String[] args) throws IOException {
FileInputStream fl = new FileInputStream("fos.txt");
FileOutputStream file = new FileOutputStream("fos_cp.txt");
int len = 0;
byte[] bat = new byte[10];
while ((len = fl.read(bat))!=-1) {
file.write(bat, 0, len);
}
System.out.println("复制完毕!");
fl.close();
file.close();
}
}
(5)read(byte[] b)和write(byte b)方法
import java.io.*;
import java.nio.Buffer;
/**
* 缓冲流
* java.io.BufferedInputStream和BufferedOutputStream
* 缓冲字节流是一对高级流,在流连接中使用的目的是提高读写效率
*
* 缓冲流内部维护一个byte数组作为缓冲区,默认大小为8k。所以无论我们读写方式如何,
* 到缓冲流时都会同意转换为块操作来保证读写效率
*/
public class CopyDemo2 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("IDEA.zip");
BufferedInputStream bis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream("IDEA_copy.zip");
BufferedOutputStream bos = new BufferedOutputStream(fos);
int d = 0;
long start = System.currentTimeMillis();
while((d= bis.read())!= -1){
bos.write(d);
}
long end = System.currentTimeMillis();
System.out.println("复制完毕!耗时为"+(end-start)+"ms");
bis.close();
bos.close();
}
}
3.缓冲流
1)BOS基本工作原理
在向硬件设备做写出操作时, 增大写出次数无疑会降低写出效率,为此我们可以使用缓冲输出流来一次性批量写出若干数据减少写出次数来提高写出效率。
BufferedOutputStream缓冲输出流内部维护着一一个缓冲区,每当我们向该流写数据时, 都会先将数据存入缓冲区,当缓冲区已满时,缓冲流会将数据一次性全部写出。
2)BOS实现输出缓冲
FileOutputStream fos = new FileOutputStream("IDEA_copy.zip");
BufferedOutputStream bos = new BufferedOutputStream(fos);
3)BOS的fluah()方法
缓冲流的flush方法用于强制将缓冲区中已经缓存的数据一次性写出
频繁调用该方法会降低写出效率,但是可以保证写出数据的即时性
import java.io.*;
/**
* 缓冲输出流写出数据的缓冲问题
*/
public class BOS_flush {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("bos.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
String str = " 费话费还,好我成立的呢车子活动is后赛后安徽到合肥的爱吃那厉害啊";
byte[] data = str.getBytes("UTF-8");
bos.write(data);
/*
缓冲流的flush方法用于强制将缓冲区中已经缓存的数据一次性写出
频繁调用该方法会降低写出效率,但是可以保证写出数据的即时性
*/
bos.flush();
System.out.println("写出完毕!");
bos.close();
}
}
4)BIS基本工作原理
在读取数据时若以字节为单位读取数据,会导致读取次数过于频繁从而大大的降低读取效率。为此我们可以通过提高一次读取的字节数量减少读写次数来提高读取的效率。
BufferedInputStream是缓冲字节输入流。其内部维护着一个缓冲区(字节数组) , 使用该流在读取一个字节时该流会尽可能多的一次性读取若干字节并存入缓冲区,然后逐一的将字节返回,直到缓冲区中的数据被全部读取完毕,会再次读取若干字节从而反复。这样就减少了读取的次数,从而提高了读取效率。
BIS是一个处理流,该流为我们提供了缓冲功能。
5)BIS实现输入缓冲
FileInputStream fis = new FileInputStream("IDEA.zip");
BufferedInputStream bis = new BufferedInputStream(fis);
import java.io.*;
import java.nio.Buffer;
/**
* 缓冲流
* java.io.BufferedInputStream和BufferedOutputStream
* 缓冲字节流是一对高级流,在流连接中使用的目的是提高读写效率
*
* 缓冲流内部维护一个byte数组作为缓冲区,默认大小为8k。所以无论我们读写方式如何,
* 到缓冲流时都会同意转换为块操作来保证读写效率
*/
public class CopyDemo2 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("IDEA.zip");
BufferedInputStream bis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream("IDEA_copy.zip");
BufferedOutputStream bos = new BufferedOutputStream(fos);
int d = 0;
long start = System.currentTimeMillis();
while((d= bis.read())!= -1){
bos.write(d);
}
long end = System.currentTimeMillis();
System.out.println("复制完毕!耗时为"+(end-start)+"ms");
bis.close();
bos.close();
}
}
4.对象流
1)对象序列化概念
2)使用OOS实现对象序列化
Person 类
import java.io.Serializable;
import java.util.Arrays;
/**
* 使用当前流测试对象流的对象的读写操作
*
* 需要被对象流序列化的类必须实现接口:java.io.Serializable;
* 并且如果这个类的属性是引用类型的,那么这个类型也要实现接口
*
* Serializable接口是一个签名接口,这个接口中没有定义任何抽象方法
* 该接口是编译器敏感的接口,当编译器编译一个类发现实现了序列化借口是
* 会在编译的class文件中添加方法:用于将当前类实例按照其接口转换为一组字节
*/
public class Person implements Serializable{
private String name;
private int age;
private String gender;
/*
transient关键字修饰的属性早该对象序列化时你会被忽略
忽略不必要的属性可以达到对象瘦身的目的。
*/
private transient String[] otherInfo;
public Person(String name, int age, String gender, String[] otherInfo) {
this.name = name;
this.age = age;
this.gender = gender;
this.otherInfo = otherInfo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String[] getOtherInfo() {
return otherInfo;
}
public void setOtherInfo(String[] otherInfo) {
this.otherInfo = otherInfo;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
", otherInfo=" + Arrays.toString(otherInfo) +
'}';
}
}
实现类
import java.io.*;
import java.sql.SQLOutput;
/**
* 对象流
* java.io.ObjectInputStream和ObjectOutputStream
* 对象流也是一对高级流,作用是方便我们读写java中任何对象
* (主要功能就是将对象与字节相互转换)
*/
public class OOSDemo {
public static void main(String[] args) throws IOException {
String name = "janelee";
int age = 23;
String gender = "男";
String[] otherfo = {"山东滨州人","java程序员","爱好写作"};
Person p = new Person(name,age,gender,otherfo);
System.out.println(p);
//将Person对象写入到文件Person.obj文件中
FileOutputStream fos = new FileOutputStream("Person.obj");
ObjectOutputStream oos = new ObjectOutputStream(fos);
/*
对象流的写出对象方法:writeObject在实际操作时可能会抛出异常NotSerializableException
这是因为写出的对象所属的类没有实现序列化接口:Serializable
并且如果这个类的属性是引用类型的,那么这个类型也要实现该接口
在调用下面的writeObject方法时,对象会经过两个流:
对象流:首先对象流将该对选哪个按照其结构转换为一组字节(这个过程称为对象序列化)
然后再将这组字节通过对象流连接(这里是文件流)的流写出
文件流:将对象流所转换的字节写入文件(写入了磁盘)
将数据写入磁盘的过程称为:数据持久化
*/
oos.writeObject(p);
System.out.println("写出完毕!");
oos.close();
}
}
3)使用OIS实现对象反序列化
4)Serializable接口
对象流的写出对象方法:writeObject在实际操作时可能会抛出异常NotSerializableException
这是因为写出的对象所属的类没有实现序列化接口:Serializable
并且如果这个类的属性是引用类型的,那么这个类型也要实现该接口
需要被对象流序列化的类必须实现接口:java.io.Serializable;
并且如果这个类的属性是引用类型的,那么这个类型也要实现接口
Serializable接口是一个签名接口,这个接口中没有定义任何抽象方法
该接口是编译器敏感的接口,当编译器编译一个类发现实现了序列化借口是
会在编译的class文件中添加方法:用于将当前类实例按照其接口转换为一组字节
5)Transient关键字
transient关键字修饰的属性早该对象序列化时你会被忽略
忽略不必要的属性可以达到对象瘦身的目的。