流是相对于程序而言的,并不是相对文件!!!!
你就理解为一个抽水泵,可以更快的读取文件,比如为什么你冲了VIP你下载速度才那么快,想一下就知道里面多了一个水泵,水泵也贵的呀,谁会这么便宜给你用!
这张图一定要记住,四大基类:inputStream、OutputStream、Reader、Writer。后面的什么都差不多相同,只不过各有各的神奇功能。如果这张图捋不清或者不理解,后面学起来就很难。
@Test
public void test1() {
//定义成员变量 方便finnal下面拿到
FileInputStream is =null;
try {
//创建实例
is = new FileInputStream("G:\\测试\\1111.jpg");
//读取文件一个字节一个字节读
int read =is.read();
System.out.println("文件字节数"+is.available());
System.out.println("---------------------------");
System.out.println(read);
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}finally {
if(is !=null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
方法二
@Test
public void test2() {
FileInputStream is =null;
try {
is = new FileInputStream("G:\\测试\\1111.jpg");
//以为1024byte读取
byte[] b =new byte[1024];
int lenght =is.read(b);
while(lenght !=-1) {
for(byte bt :b) {
//输出详细读取图片二进制的多少
System.out.print(bt);
}
lenght =is.read(b);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}finally {
if(is !=null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Test
public void test3() {
FileInputStream is =null;
FileOutputStream os =null;
try {
is = new FileInputStream("G:\\测试\\1111.jpg");
//复制输出到G:\\111.jpg
os=new FileOutputStream("G:\\111.jpg");
byte[] b =new byte[1024];
int lenght =is.read(b);
while(lenght !=-1) {
//通过文件字节输入流读取的信息,输出到一个文件中
//这里要注意,读多少我们就写多少,不能直接写出数组中所有数据
os.write(b,0,lenght);
lenght =is.read(b);
}
System.out.println("ok.....");
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}finally {
if(is !=null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(os !=null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Test
public void test1() throws IOException {
//读文件,java文件 用字符流
FileReader readr =new FileReader("F:\\实训三\\8月份所学的\\8.25\\ch12\\test\\com\\uplooking\\ch12\\FileTest1.java");
//以容量100来读
char[] ch =new char[100];
//读取文件的长度
int length = readr.read(ch);
while(length !=-1) {
//当长度不为-1的时候执行
//注意:读多少,写多少
//错误的写法
//System.out.print(new String(ch));
//这是正确的写法
//输出读到的容量
System.out.println(new String(ch,0,length));
//重新计算
length =readr.read(ch);
}
//读完之后要关闭资源,以免造成浪费
readr.close();
}
@Test
public void test2() throws IOException {
FileReader readr =new FileReader("F:\\实训三\\8月份所学的\\8.25\\ch12\\test\\com\\uplooking\\ch12\\FileTest1.java");
//复制文件输出到G:\\123.java
FileWriter write =new FileWriter("G:\\123.java");
char[] ch =new char[100];
int length = readr.read(ch);
while(length !=-1) {
//读多少,写多少
write.write(ch,0,length);
length =readr.read(ch);
}
readr.close();
write.close();
}
运用这个缓冲流和没有缓冲流之间的对比,查看效率
@Test
public void test1() throws IOException {
//统计开始的时间
long num1 =System.currentTimeMillis();
InputStream is =new FileInputStream("F:\\实训三\\101787.mp4");
BufferedInputStream bis =new BufferedInputStream(is);
OutputStream os =new FileOutputStream("F:\\\\实训三\\101.mp4");
BufferedOutputStream bos =new BufferedOutputStream(os);
byte[] bt=new byte[300];
int length =bis.read(bt);
while(length !=-1) {
// 每次读取后,写入到一个新文件中(文件复制)
bos.write(bt,0,length);
length =bis.read(bt);
}
//用完之后要关闭
is.close();
bis.close();
bos.close();
os.close();
System.out.println("ok....");
long num2 =System.currentTimeMillis();
System.out.println(num2-num1);
//21
}
@Test
public void test2() throws IOException {
//统计开始的时间
long num1 =System.currentTimeMillis();
InputStream is =new FileInputStream("F:\\实训三\\101787.mp4");
OutputStream os =new FileOutputStream("F:\\\\实训三\\102.mp4");
byte[] bt=new byte[300];
int length =is.read(bt);
while(length !=-1) {
// 每次读取后,写入到一个新文件中(文件复制)
os.write(bt,0,length);
length =is.read(bt);
}
//用完之后要关闭
is.close();
os.close();
System.out.println("ok....");
long num2 =System.currentTimeMillis();
System.out.println(num2-num1);
//157
//明显比没有水泵传输得快
}
@Test
public void test1() throws IOException {
//字符输入
//直接访问
Reader read =new FileReader("F:\\实训三\\8月份所学的\\8.25\\ch11-01\\"
+ "test\\com\\uplooking\\ch1102\\MapTest1.java");
//流上流 水泵一样 叫处理流
BufferedReader reader =new BufferedReader(read);
char[] ch = new char[1024];
int length =reader.read(ch);
//length ==-1 说明读到了文件的尾部(说明文件读取完成了)
while(length !=-1) {
//我要打印
System.out.print(new String(ch,0,length));
length =reader.read(ch);
}
read.close();
reader.close();
}
@Test
public void test2() throws IOException {
Reader read =new FileReader("F:\\实训三\\8月份所学的\\8.25\\ch11-01\\"
+ "test\\com\\uplooking\\ch1102\\MapTest1.java");
BufferedReader reader =new BufferedReader(read);
//创建新的文件
File file =new File("F:\\实训三\\12345.java");
//写
Writer we =new FileWriter(file);
BufferedWriter writer =new BufferedWriter(we);
char[] ch = new char[1024];
int length =reader.read(ch);
//length ==-1 说明读到了文件的尾部(说明文件读取完成了)
while(length !=-1) {
//我要打印
writer.write(ch,0,length);
length =reader.read(ch);
}
read.close();
reader.close();
writer.close();
we.close();
}
@Test
public void test1() throws FileNotFoundException {
//打印流
File file =new File("F:\\实训三\\println.txt");
PrintStream out =new PrintStream(file);
//重新设置标准输出
//此时控制台不会出现打印内容 ,打到了F:\\实训三\\println.txt 里面
System.setOut(out);
System.out.println("打印了");
System.out.println("打印了");
System.out.println("打印了");
System.out.println("打印了");
System.out.println("122344");
System.out.println("1223.4154");
}
@Test
public void test2() throws FileNotFoundException {
//打印流 字符流
File file =new File("F:\\实训三\\println1.txt");
PrintWriter pw =new PrintWriter(file);
pw.print("打印了");
pw.print("Hello");
pw.print("you");
pw.close();
}
@Test
public void test3() throws FileNotFoundException {
//打印流 字节流
File file =new File("F:\\实训三\\println2.txt");
PrintStream out =new PrintStream(file);
out.print("打印了");
}
当学习数据流的时候我们先从数据流的输出开始,然后再学输入
@Test
public void test1() throws IOException {
//指明文件
File file =new File("F:\\实训三\\shiyan.txt");
//输出字节
OutputStream os =new FileOutputStream(file);
//数据流的输出
DataOutputStream dos =new DataOutputStream(os);
dos.writeChar('大');
dos.writeChar('中');
dos.writeChar('国');
dos.writeByte(100);
dos.writeBoolean(true);
dos.writeDouble(123.45666);
//String类型
dos.writeUTF("这里是广东省");
dos.close();
os.close();
System.out.println("ok.........");
}
会得到我们看不到的文件形式,得让数据回流编译才能弄出来
@Test
public void test2() throws IOException {
//定义所在的文件
File file =new File("F:\\实训三\\shiyan.txt");
//输入流
InputStream is =new FileInputStream(file);
//数据输入流
DataInputStream dis =new DataInputStream(is);
//之前是怎么写输出数据流的格式
//返回来的输入数据流的格式得和之前的一模一样才行
//我觉得这是一件很苦逼的工作。。。
char c1 =dis.readChar();
char c2 =dis.readChar();
char c3 =dis.readChar();
byte bt =dis.readByte();
boolean b =dis.readBoolean();
double db =dis.readDouble();
String str =dis.readUTF();
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
System.out.println(bt);
System.out.println(b);
System.out.println(db);
System.out.println(str);
System.out.println("ok.........");
dis.close();
is.close();
}
序列化不需要你再重新new一个对象,可以从别人传过来的对象直接改造,方便很多
Serializable关键字是接口,但它里面什么内容都没有,作用是为了标识这个类是用来序列化的
@Test
public void test1() throws IOException {
//完成person对象的序列化
File file =new File("F:\\实训三\\PersonClass.obj");
OutputStream out =new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(out);
Person p1 =new Person(10055,"李四",true);
System.out.println("ok");
oos.writeObject(p1);
out.close();
}
@Test
public void test2() throws IOException, ClassNotFoundException {
//转换成功但出现寻址是因为什么
//是因为没有在person那边重写toString方法
//完成person对象的反序列化
//间接访问
File file =new File("F:\\实训三\\PersonClass.obj");
InputStream inputStream =new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(inputStream);
Object obj =ois.readObject();
if(obj instanceof Person) {
Person p1 =(Person)obj;
System.out.println(p1);
}
ois.close();
inputStream.close();
System.out.println("ok.......");
//如果不加序列号就会报错
//因为反序列化的时候所带的标识不一样
//当你写序列化和反序列化的时候记得带上标识
}
Person类 也是接下来的步骤一
package com.objectStreamTest01.ch01;
import java.io.Serializable;
/*
* Serializable接口没有抽象方法,它是一个标识接口
* 标识实现了这个接口的类,是可以序列化的
*/
public class Person implements Serializable{
private int id;
private String name;
//不参与序列化 默认为假
private transient boolean sex;
public Person() {
super();
}
public Person(int id, String name, boolean sex) {
super();
this.id = id;
this.name = name;
this.sex = sex;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isSex() {
return sex;
}
public void setSex(boolean sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", sex=" + sex + "]";
}
}
步骤二 序列化是成功的
步骤三 添加age属性
步骤四 java.io.InvalidClassException
添加UID(如果你不手动添加它也会自动给,根据属性,但它是长整形的为了避免混乱。如果你不添加,以后会出现序列化和反序列化错误。所以以后知道这个类参与序列化和反序列化老实点添加UID,对你没有害处)
transient关键字是表示这个属性不参与序列化工作,只能添加在属性。
修改了person里面属性,还是能反序列化编译,不因改变了属性和构造器不能成功
Person2类
package com.objectStreamTest01.ch01;
import java.io.Serializable;
/*
* Serializable接口没有抽象方法,它是一个标识接口
* 标识实现了这个接口的类,是可以序列化的
*/
public class Person2 implements Serializable{
//添加了UID
/**
*
*/
private static final long serialVersionUID = 5787331249166359638L;
private int id;
private String name;
//不参与序列化 默认为假
private transient boolean sex;
//添加了age属性
private transient int age;
//添加地方String属性
private String city;
public Person2(int id, String name, boolean sex, int age, String city) {
super();
this.id = id;
this.name = name;
this.sex = sex;
this.age = age;
this.city = city;
}
public Person2() {
super();
}
public Person2(int id, String name, boolean sex) {
super();
this.id = id;
this.name = name;
this.sex = sex;
}
public Person2(int id, String name, boolean sex, int age) {
super();
this.id = id;
this.name = name;
this.sex = sex;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isSex() {
return sex;
}
public void setSex(boolean sex) {
this.sex = sex;
}
public String toString() {
return "Person2 [id=" + id + ", name=" + name + ", sex=" + sex + "]"+age;
}
}
单元测试
@Test
public void test3() throws IOException {
//完成person对象的序列化
//重新弄一个person做因为没有serialVersionUID反序列例子
File file =new File("F:\\实训三\\PersonClass1.obj");
OutputStream out =new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(out);
Person2 p1 =new Person2(10015,"TOM",true,15,"佛山");
System.out.println("ok");
oos.writeObject(p1);
out.close();
}
@Test
public void test4() throws IOException, ClassNotFoundException {
//完成person对象的反序列化
//间接访问
File file =new File("F:\\实训三\\PersonClass1.obj");
InputStream inputStream =new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(inputStream);
Object obj =ois.readObject();
if(obj instanceof Person2) {
Person2 p1 =(Person2)obj;
System.out.println(p1);
}
ois.close();
inputStream.close();
System.out.println("ok.......");