java中的输入输出流2
一、IO流的划分与区别【字节流与字符流】?
IO流用来读写文件的内容
流--数据的流动轨迹。
1.按照数据的流动方向
输入流---将数据读取到我们的处理程序中所形成的数据的流动轨迹就是输入流【读取数据】
输出流---将我们程序处理以后的数据写出到某一个文件中所形成的数据的流动轨迹就是输出流【写出数据】
2.按照每一次读写数据的大小
(1)字节流---每一次读写一个字节【8位2进制】的数据量的流【字节流】
由于所有的数据都可被换算成字节,所以字节流是可以读写任何类型的数据 【文本,视频,音频,图片】
(2)字符流---每一次读写一个字符【16位2进制】的数据量的流【字符流】
不能读写任何类型的数据,只能读写文本类型的数据。
IO流的综合划分
二、常用的字节输入与字节输出流类
1.字节输出流---顶级类OutputStream
public abstract class
1.1public class FileOutputStream extends OutputStream
构造方法
FileOutputStream(File file) 通过File对象创建一个不可追加的字节输出流。 |
FileOutputStream(File file, boolean append) 通过File对象创建一个是否追加的字节输出流。 |
FileOutputStream(String name) 通过String 对象创建一个不可追加的字节输出流。 |
FileOutputStream(String name, boolean append) 通过String对象创建一个是否追加的字节输出流 |
package com.wangxing.fileoutput;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.security.KeyStore.TrustedCertificateEntry;
/**
* 字节输出流---OutPutStream[抽象类]-->它的子类FileOutPutStream
* @author 14336
*
*/
public class FileOutPutStreamDemo1 {
public static void main(String[] args) throws Exception {
//字节输出流--OutPutStream[抽象类]
//FileOutputStream 构造方法
//FileOutputStream(File file)通过File对象创建一个不可追加的字节输出流
//File file--File类型输出路径
String path1="D:/1网星/Java基础/lianxiproject/20201231InOutStreamDemo1/myfile.txt";
File file=new File(path1);
FileOutputStream fileOutputStream1=new FileOutputStream(file);
//FileOutputStream outputStream2=new FileOutputStream("/20201231InOutStreamDemo1/myfile.txt");
//上转型对象子类赋值给父类
//OutputStream stream=new FileOutputStream(file);
//FileOutputStream(String name)通过String对象创建一个不可追加的字节输出流
//String name --String类型输出路径
String path2="D:/1网星/Java基础/lianxiproject/20201231InOutStreamDemo1/myfile2.txt";
FileOutputStream fileOutputStream2=new FileOutputStream(path2);
//FileOutputStream fileOutputStream22=new FileOutputStream("D:/1网星/Java基础/lianxiproject/20201231InOutStreamDemo1/myfile2.txt");
//OutputStream outputStream=new FileOutputStream(path2);
//FileOutputStream(File file,boolean append)通过File对象创建一个是否追加的字节输出流
//File file--File类型输出路径
//boolean append --是否追加【true追加/false不可追加】
String path3="D:/1网星/Java基础/lianxiproject/20201231InOutStreamDemo1/myfile3.txt";
File file3=new File(path3);
FileOutputStream fileOutputStream3=new FileOutputStream(file3,true);
//FileOutputStream fileOutputStream3=new FileOutputStream(new File("D:/1网星/Java基础/lianxiproject/20201231InOutStreamDemo1/myfile3.txt"),true);
//OutputStream outputStream=new FileOutputStream(file3,false);
//FileOutputStream(String name,boolean append)通过String对象创建一个是否追加的字节输出流
//String name---String类型输出路径
//boolean append--是否追加【true追加/false不追加】
String path4="D:/1网星/Java基础/lianxiproject/20201231InOutStreamDemo1/myfile4.txt";
FileOutputStream fileOutputStream4=new FileOutputStream(path4,true);
//FileOutputStream fileOutputStream44=new FileOutputStream("D:/1网星/Java基础/lianxiproject/20201231InOutStreamDemo1/myfile4.txt",true);
//OutputStream outputStream=new FileOutputStream(path4,false);
}
}
实例方法;
void | write(byte[] b) 将 b.length个字节从指定的字节数组写入此文件输出流。 |
void | write(byte[] b, int off, int len) 将 len字节从位于偏移量 off的指定字节数组写入此文件输出流。 |
void | write(int b) 将指定的字节写入此文件输出流。 |
void | close() 关闭此文件输出流并释放与此流相关联的任何系统资源。 |
package com.wangxing.fileoutput;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
public class FileOutPutStreamDemo2 {
public static void main(String[] args) throws Exception {
//FileOutputStream实例方法
/*
//void write(byte[] b)将b.length个字节从指定的字节数组写入此文件输出流
String path1="D:/1网星/Java基础/lianxiproject/20201231InOutStreamDemo1/myfile.txt";
FileOutputStream fileOutputStream=new FileOutputStream(path1,true);
String info="hello";//被写出的数据String
byte[] b=info.getBytes();
fileOutputStream.write(b);
fileOutputStream.close();
*/
/*
//void write(byte[] b,int off,int len)将len字节从位于偏移量off的指定字节数组写入此文件输出流
String path1="D:/1网星/Java基础/lianxiproject/20201231InOutStreamDemo1/myfile.txt";
FileOutputStream fileOutputStream=new FileOutputStream(path1,true);
String info="helloworld";//被写出的数据String
byte[] b=info.getBytes();
fileOutputStream.write(b,5,5);
fileOutputStream.close();
*/
//void write(int b)将指定的字节写入此文件输出流
String path1="D:/1网星/Java基础/lianxiproject/20201231InOutStreamDemo1/myfile3.txt";
FileOutputStream fileOutputStream=new FileOutputStream(path1,true);
fileOutputStream.write(98);
String info ="HelloWorld";//被写出的数据String
byte[] bytearray=info.getBytes();
for (byte b : bytearray) {
fileOutputStream.write(b);
}
fileOutputStream.close();
}
}
2.字节输入流---顶级类InputStream
public abstract class
2.1public class FileInputStream extends InputStream
//构造方法
FileInputStream(File file) 通过File对象创建一个字节输入流 |
FileInputStream(String name) 通过String对象创建一个字节输入流 |
package com.wangxing.fileinput;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
public class FileInputStreamDemo1 {
public static void main(String[]args) throws Exception{
//字节输入流--InputSteram[抽象类]
//FileInputStream 构造方法
//FileInputStreaml(File file)通过File对象创建一个字节输入流
//File file--File类型输入路径
//String path1="D:/1网星/Java基础/lianxiproject/20201231InOutStreamDemo1/myfile.txt";
String path1="D:"+File.separator+"1网星"+File.separator+"Java基础"+File.separator+"lianxiproject"+File.separator+"20201231InOutStreamDemo1"+File.separator+"myfile.txt";
File file=new File(path1);
FileInputStream fileInputStream=new FileInputStream(file);
FileInputStream fileInputStream2=new FileInputStream("D:"+File.separator+"1网星"+File.separator+"Java基础"+File.separator+"lianxiproject"+File.separator+"20201231InOutStreamDemo1"+File.separator+"myfile.txt");
InputStream inputStream=new FileInputStream(file);
//FileInputStream(String name)通过String对象创建一个字节输入流
//String name--String类型的输入路径
String path2="D:/1网星/Java基础/lianxiproject/20201231InOutStreamDemo1/myfile.txt";
FileInputStream fileInputStream3=new FileInputStream(path2);
FileInputStream fileInputStream4=new FileInputStream("D:/1网星/Java基础/lianxiproject/20201231InOutStreamDemo1/myfile.txt");
InputStream inputStream2=new FileInputStream(path2);//上转型
}
}
实例方法:
int | read() 从该输入流读取一个字节的数据。 返回值:读取到的具体字节数据的int型,如果到达文件末尾返回-1 |
int | read(byte[] b) 从该输入流读取最多 b.length个字节的数据为字节数组。 返回值:读取的总字节数, 如果到达文件末尾返回-1 |
void | close() 关闭此文件输入流并释放与流相关联的任何系统资源。 |
package com.wangxing.fileinput;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class FileInputStreamDemo2 {
public static void main(String[] args) throws Exception {
//FileInputStream 实例方法
//int read(byte[] b)
//从该输入流读取最多b.length个字节的数据为字节数组
//返回值:读取的总字节数,如果到达文件末尾返回-1
/*
String path1="D:/1网星/Java基础/lianxiproject/20201231InOutStreamDemo1/myfile.txt";
File file=new File(path1);
FileInputStream fileInputStream=new FileInputStream(file);
byte bytearray[] = new byte[15];
//=new byte[(int) file.length()];
//int len=
fileInputStream.read(bytearray);
fileInputStream.close();
String info =new String(bytearray);
System.out.println("info=="+info);
//System.out.println("len=="+len);
*
*/
//int read()
//从该输出流读取一个字节数据
//返回值:读取到的具体字节数据的int型,如果达到文件末尾返回-1;
String path1="D:/1网星/Java基础/lianxiproject/20201231InOutStreamDemo1/myfile.txt";
File file=new File(path1);
FileInputStream fileInputStream=new FileInputStream(file) ;
//int len=fileInputStream.read();从该输入流读取一个字节数据
byte bytearray[]=new byte[(int)file.length()];//用于保存读取来的数据
int len=0;//被读取来的数据所对应的值
int index=0;//字节数组下标
//持续读取知道文件末尾【-1】
while ((len=fileInputStream.read())!=-1) {
//保存读取的数据到数组
bytearray[index]=(byte)len;
index++;
}
fileInputStream.close();
String info=new String(bytearray);
System.out.println("info=="+info);
}
}
上面的字节输入输出流只能读写字节数组,不能直接控制基本数据类型的数据的读写
3.DataOutputStream 字节输出流
3.1.public class DataOutputStream extends FilterOutputStream implements DataOutput
DataOutputStream
构造方法
DataOutputStream(OutputStream | 创建一个新的数据输出流,以将数据写入指定的底层输出流。 |
//OutputStream out--底层输出流[FileOutputStream]
实例方法:
void | writeBoolean(boolean v) 将 boolean写入底层输出流作为1字节值。 |
void | writeByte(int v) 将 byte作为1字节值写入底层输出流。 |
void | writeChar(int v) 将 char写入底层输出流作为2字节值,高字节优先。 |
void | writeDouble(double v) 双参数传递给转换 long使用 doubleToLongBits方法在类 Double ,然后写入该 long值基础输出流作为8字节的数量,高字节。 |
void | writeFloat(float v) 浮子参数的转换 int使用 floatToIntBits方法在类 Float ,然后写入该 int值基础输出流作为一个4字节的数量,高字节。 |
void | writeInt(int v) 将底层输出流写入 int作为四字节,高位字节。 |
void | writeLong(long v) 将 long写入底层输出流,为8字节,高字节为首。 |
void | writeShort(int v) 将 short写入底层输出流作为两个字节,高字节优先。 |
void | writeUTF(String str) 使用 modified UTF-8编码以机器无关的方式将字符串写入基础输出流。 |
void | flush() 刷新此数据输出流。 |
void | close() 关闭此输出流并释放与此流相关联的任何系统资源。 |
package com.wangxing.dataoutput;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class DataOutputStreamDemo1 {
public static void main(String[] args) throws Exception {
//DataOutputStream 可以直接写出基本数据类型,无需转换成字节数组
//将被写出的基本数据类型的数据转换成2进制形式写出,保存在文件中的数据是乱码
//DataOutputStream 构造方法
//DataOutputStream(OutputStream)创建一个新的数据输出流,以将数据写入指定的底层输出流
//OutputStream out--底层输出流[FileOutputStream]
String path1="D:/1网星/Java基础/lianxiproject/20201231InOutStreamDemo1/data1.txt";
File file=new File(path1);
//FileInputStream fileInputStream=new FileInputStream(file);//OutputStream的子类对象
OutputStream outputStream=new FileOutputStream(file,true);//OutputStream的上转型对象
//OutputStream的子类对象/OutputStream的上转型对象--底层输出流
DataOutputStream dataOutputStream=new DataOutputStream(outputStream);//高级输出流
//DataOutputStream 实例方法
/*
*
* void writeBoolean(boolean v) 将 boolean写入底层输出流作为1字节值。
void writeByte(int v) 将 byte作为1字节值写入底层输出流。
void writeChar(int v) 将 char写入底层输出流作为2字节值,高字节优先。
void writeDouble(double v) 双参数传递给转换 long使用 doubleToLongBits方法在类 Double ,然后写入该 long值基础输出流作为8字节的数量,高字节。
void writeFloat(float v) 浮子参数的转换 int使用 floatToIntBits方法在类 Float ,然后写入该 int值基础输出流作为一个4字节的数量,高字节。
void writeInt(int v) 将底层输出流写入 int作为四字节,高位字节。
void writeLong(long v) 将 long写入底层输出流,为8字节,高字节为首。
void writeShort(int v) 将 short写入底层输出流作为两个字节,高字节优先。
void writeUTF(String str) 使用 modified UTF-8编码以机器无关的方式将字符串写入基础输出流。
void flush() 刷新此数据输出流。
void close() 关闭此输出流并释放与此流相关联的任何系统资源。
*/
dataOutputStream.writeInt(1001);//int 1001 4
dataOutputStream.writeChar('\t');//char \t 2
dataOutputStream.writeBoolean(true);// boolean true 1
dataOutputStream.writeChar('\t');//char \t 2
dataOutputStream.writeDouble(12.5);//double 12.5
dataOutputStream.writeChar('\t');//char \t 2
dataOutputStream.writeUTF("zhangsan");//String [UTF-8] zhangsan 8
dataOutputStream.flush();
dataOutputStream.close();
outputStream.close();
}
}
4.DataInputStream 字节输入流
4.1public class DataInputStream extends FilterInputStream implements DataInput
构造方法:
DataInputStream(InputStream | 创建使用指定的底层InputStream的DataInputStream。 |
实例方法:
boolean | readBoolean() | |
byte | readByte() | |
char | readChar() | |
double | readDouble() | |
float | readFloat() | |
int | readInt() | |
long | readLong() | |
short | readShort() | |
String | readUTF() | |
void | close() |
package com.wangxing.datainput;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
public class DataInputStreamDemo1 {
public static void main(String[] args) throws Exception {
//DataInputStream 可以直接读取基本数据类型数据,无需转换成字节数组
//DataInputStream 构造方法
//DataInputStream(InputStream in) 创建一个新的数据输入流,以将从底层输入流中读取数组
//InputStream in --底层输入流【FileInputStream】
String path1="D:/1网星/Java基础/lianxiproject/20201231InOutStreamDemo1/data1.txt";
File file1=new File(path1);
FileInputStream fileInputStream=new FileInputStream(file1);//InputStream的子类对象
//InputStream inputStream=new FileInputStream(file1);//InputStream的上转型对象
//InnputStream的子类对象/InputStream的上转型对象--底层输入流
DataInputStream dataInputStream=new DataInputStream(fileInputStream);//高级输入流
//DataInputStream 实例方法
/*
boolean readBoolean()
byte readByte()
char readChar()
double readDouble()
float readFloat()
int readInt()
long readLong()
short readShort()
String readUTF()
void close()
*/
int intvalue=dataInputStream.readInt();//int 1001 4
char c=dataInputStream.readChar();//char \t 2
boolean b=dataInputStream.readBoolean();//boolean true 1
char d=dataInputStream.readChar();//char \t 2
double e=dataInputStream.readDouble();//double 12.5 8
char f=dataInputStream.readChar();//char \t 2
String string=dataInputStream.readUTF();//String [tuf-8] zhangsan 8
dataInputStream.close();
fileInputStream.close();
System.out.println(intvalue+" "+b+" "+e+" "+string);
}
}
三、什么是序列化?如何实现序列化?
因为我们做操作的java对象可能需要在多台计算机之间传递。
序列化-----将一个java对象转换成2进制流数据过程。
反序列化---2进制流数据转换成一个java对象的过程。
1.如何实现序列化?
1.1为被序列化的java对象的生成类实现一个序列化接口【Serializable】
public interface Serializable
特殊----该接口中一个方法都没有。
类的序列化由实现java.io.Serializable接口的类启用。 不实现此接口的类将不会使任何状态序列化或反序列化。 可序列化类的所有子类型都是可序列化的。
1.2通过java提供ObjectOutputStream类的writeObject(Object obj)
ObjectOutputStream
构造方法
ObjectOutputStream(OutputStream out) | 创建一个写入指定的OutputStream的ObjectOutputStream。 |
实例方法:
void | writeObject(Object obj) 将指定的对象写入ObjectOutputStream。 |
将java对象序列化到记事本文件。
package com.wangxing.objectinoutput;
import java.io.Serializable;
//为被序列化的java对象的生成类实现一个序列化接口【SeriaLizable】
public class Student implements Serializable {
public void testStudent(){
System.out.println("Student类的实例方法testStudent");
}
}
package com.wangxing.objectinoutput;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
public class ObjectOutputStreamDemo1 {
public static void main(String[] args) throws Exception {
//ObjectOutputStream 构造方法
//ObjectOutputStream(OutputStream out)创建一个写入指定的OutputStream的ObjectOutputStream
String path1="D:/1网星/Java基础/lianxiproject/20201231InOutStreamDemo1/student.txt";
File file=new File(path1);
FileOutputStream fileOutputStream=new FileOutputStream(file);
//OutputStream outputStream=new FileOutputStream(file);
ObjectOutputStream objectOutputStream=new ObjectOutputStream(fileOutputStream);
//ObjectOutputStream 实例方法
//void writeObject(Object obj)将指定对象写入ObjectOutoutStream
Student student=new Student();
objectOutputStream.writeObject(student);
objectOutputStream.flush();
objectOutputStream.close();
fileOutputStream.close();
}
}
将上面序列化到记事本文件中的java对象,反序列化回来成一个可使用的java对象。此时就需要ObjectInputStream类的Object readObject()方法读取对象。
ObjectInputStream类
构造方法:
ObjectInputStream(InputStream | 创建从指定的InputStream读取的ObjectInputStream。 |
实例方法:
Object | readObject() 从ObjectInputStream读取一个对象。 |
package com.wangxing.objectinoutput;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.OutputStream;
public class ObjectInputStreamDemo1 {
public static void main(String[] args) throws Exception {
//ObjectInputStream 构造方法
//ObjectInputStream(InputStream in)创建从指定的InputStream读取的ObjectInputStream
String path1="D:/1网星/Java基础/lianxiproject/20201231InOutStreamDemo1/student.txt";
File file=new File(path1);
FileInputStream fileInputStream=new FileInputStream(file);
//InputStream inputStream=new FileInputStream(file);
ObjectInputStream inputStream=new ObjectInputStream(fileInputStream);
//ObjectInputStream 实例方法
//object readObject()从ObjectputStream读取一个对象
Object object=inputStream.readObject();
Student student=(Student)object;
inputStream.close();
fileInputStream.close();
student.testStudent();
}
}
各输入输出流之间的关系
用字节输入输出流完成复制功能
package com.wangxing.copy;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* 使用FileInputStream+FileoutputStream完成复制
* 复制--一边读一边写
* 使用字节流拷贝文件的时候,文件类型随意,什么样的文件都可以拷贝
*/
public class Copy01 {
public static void main(String[] args) throws Exception {
//创建输入输出流
FileInputStream fileInputStream = null;
//FileOutputStream fileOutputStream = null;
//1.创建一个输入流
//需要读取的文件路径
String path1="D:\\copy01.txt";
File file=new File(path1);
fileInputStream=new FileInputStream(file);
//2.创建一个输出流
//需要往哪里输出?
//往C盘复制不行,提示拒绝访问
//String path2="C:\\copy01.txt";
//改正方法有两种
//1.不能直接在目录后面跟要复制的文件,需要自己新建一个文件加一级路径才可以
//String path2="C:\\test\\copy01.txt;
//2. 换一个盘创建就行
//String path2="D:\\桌面文件\\"+file.getName();
String path2="D:\\1网星\\Java基础\\lianxiproject\\20201231InOutStreamDemo1\\copy01.txt";
File file2=new File(path2);
FileOutputStream fileOutputStream=new FileOutputStream(file2,false);
//一边输入,一边输出
byte[] bytes=new byte[1024*1024];//(一次读取1mb 1kb==1024 1mb=1kb*1024)
int read=0;
//fileInputStream.read(bytes) 往byte数组里读取,返回值是:读取到的字节数量。(不是字节本身)
//fileInputStream.read();这个方法的返回值是:读取到的“字节”本身。
while((read=fileInputStream.read(bytes))!=-1){
fileOutputStream.write(bytes,0,read);
}
// 刷新,输出流最后要刷新
fileOutputStream.flush();
if (fileOutputStream!=null) {
fileOutputStream.close();
}
if (fileInputStream!=null) {
fileInputStream.close();
}
}
}