1.IO流
1).按流的方向分类:
1)输入流
2)输出流
2)按类型分类:
字节流:先有
按方向 抽象类
字节输入 :InputStream
字节输出 :OutputStream
字符流:后有
字符输入 :Reader
字符输出 :Writer
3)特有功能:
1)创建文件输出流 public FileOutputStream(String name):创建文件 public FileOutputStream(String pathname,boolean append):如果第二个参数为true,则自动后面追加
public FileOutputStream(String name) throws FileNotFoundException
//底层创建:创建流对象fos内存执行输出的文件aaa.txt
FileOutputStream fos = new FileOutputStream("xxx.txt") ;
2)写数据:
//abstract void write(int b ):写入单个字节
fos.write(97) ;//97---a 写入的内容是a
// void write(byte[] b):写入一个字节数组
fos.write("hello,IO".getBytes()); 写入的字节数组是hello,IO
3)释放资源
//底层:将fos流对象不再执行那个文件了
fos.close() ;
4)IO流的输入/输出方式:
1.字节输出流:
FileOutputStream的构造方法 public FileOutputStream(String pathname,boolean append):如果第二个参数为true,则自动后面追加
public class FileOutputStreamDemo {
public static void main(String[] args) throws IOException {//自己使用可以去抛异常
//创建文件字节输出流对象
// FileOutputStream fos = new FileOutputStream("fos.txt") ;
//public FileOutputStream(String pathname,boolean append)
FileOutputStream fos = new FileOutputStream("fos.txt",true) ;
//写数据
//写一个字节数组
for(int x = 0 ; x < 10 ; x++){
fos.write(("hello"+x).getBytes()) ;
//换行符号 "\r\n"
fos.write("\r\n".getBytes());
}
//释放资源
fos.close() ;
}
}
开发中,需要处理异常:
try{
*
* 可能出现问题的代码;---一旦这有问题:Jvm 就会创建异常对象
*
* } catch (异常类名 e) { //如果和当前异常类名匹配了
* //处理异常
* //System.out.println("数组角标越界了") ;
* e.printStackTrace() ;//可以看到你自己写的代码哪块出错了以及底层原码
* }finally{
*
* //释放资源
* }
2.字节输入流:
1) 构造方法:FileInputStream public FileInputStream(String name) throws FileNotFoundException:创建文件字节输入流对象 成员方法: read这些方法:都是阻塞式方法:只要文件没有读完,一直等待要读取! 1-1)abstract int read():一次读取一个字节,返回的读取的字节数
public class FileInputStreamDemo3 {
public static void main(String[] args) throws IOException {
//创建文件字节输入流对象
//FileInputStream fis = new FileInputStream("fis.txt") ;//当前项目下的fis.txt
//读取的是当前项目下的java文件FileOutputStreamDemo2.java
FileInputStream fis = new FileInputStream("FileOutputStreamDemo2.java") ;
//读:abstract int read():一次读取一个字节
//第一次读
/*int by = fis.read();
//System.out.println(by) ;//97---
//将这个字节数----变成字符
System.out.println((char)by);
System.out.println("-------------------") ;
//第二次读
by = fis.read() ;
System.out.println((char)by);
System.out.println("-------------------") ;
//第三次读
by = fis.read() ;
System.out.println((char)by);
System.out.println("-------------------") ;
//第四次读
by = fis.read() ;
System.out.println((char)by);
System.out.println("-------------------") ;
//第五次读
by = fis.read() ;
System.out.println((char)by);*/
//第六次读
/* by = fis.read() ;
System.out.println(by);
System.out.println((char)by);*/
//使用循环思想改进
/* int by = fis.read() ;
while(by!=-1){
System.out.print((char)by);
by = fis.read() ;
}*/
//在优化:将赋值,判断一块使用
//刚开始:还没还是读 字节数0
int by = 0 ;
while((by=fis.read())!=-1){
System.out.print((char)by);
}
//3)释放资源
fis.close() ;
}
}
1-2)int read(byte[] b) :一次读取一个字节数组
int read(byte[] b) :一次读取一个字节数组
*/
public class FileInputStreamDemo4 {
public static void main(String[] args) throws IOException {
//读取是当前项目下的fis2.txt文件
//创建文件字节输入流对象
FileInputStream fis = new FileInputStream("fis2.txt") ;
//优化上面代码:一般一次读取一个字节数组:数组的长度:1024或者是1024的整数倍
//最终版代码
byte[] bytes = new byte[1024] ;//提供字节缓冲区
//实际的长度:根据内容判断 :获取实际字节数
int len = 0 ;
//判断和获取一块使用
while((len=fis.read(bytes))!=-1){
System.out.println(new String(bytes,0,len)); //每次从0开始获取实际字节数---转换成字符串
}
//释放资源
fis.close() ;
}
} //读取fis2.txt 文件
adc
adc
adc
3.字节缓冲流(别名 "字节高效流"):
1)字节缓冲输入流:BufferedInputStream 构造方法 BufferedInputStream(InputStream in) 成员方法:使用InputStream的read的功能: 一次读取一个字节/一次读取一个字节数组
public class BufferedOutputSteamDemo {
public static void main(String[] args) throws IOException {
//write();
//读
read() ;
}
//读取 当前项目下的bos.txt的内容
private static void read() throws IOException {
//创建字节缓冲输入流对象
//BufferedInputStream(InputStream in)
BufferedInputStream bis = new BufferedInputStream(形式参数
是一个抽象类,需要子类对象
new FileInputStream("bos.txt")) ;
//一次读取一个字节
/* int by = 0 ;
while((by=bis.read())!=-1){
//展示出来
System.out.print((char)by);
}*/
//一次读取一个字节数组
byte[] bytes = new byte[1024] ;
int len = 0 ;
while((len=bis.read(bytes))!=-1){
//展示
System.out.println(new String(bytes,0,len));
}
//释放资源
bis.close() ;
}
}
2)字节缓冲输出流(别名 "字节高效流"):BufferedOutputStream 这个流仅仅是在内部提供了一个缓冲区(字节数组),针对文件的输出并且同时写入数据使用的还是底层流OutputStream 构造方法: public BufferedOutputStream(OutputStream out):构造一个默认的缓冲区大小,通过底层流进行输出(写入数据)
public class BufferedOutputSteamDemo {
public static void main(String[] args) throws IOException {
write();
}
private static void write() throws IOException {
//创建字节缓冲输出流对象
//public BufferedOutputStream(OutputStream out):
形式参数是一个抽象类,需要子类对象
BufferedOutputStream bos =
new BufferedOutputStream(new FileOutputStream("bos.txt")) ;
//写数据:使用的底层流的OutputStream的方法
bos.write("hello,BufferedStream".getBytes());
//释放资源
bos.close();
}
}
4.合并流:
1)SequenceInpuStream----是InputStream的子类:它这个类只能操作源文件 构造函数: public SequenceInputStream(InputStream s1,InputStream s2):将两个字节输入流对象指向的文件进行合并
public class SequenceInpuStreamTest {
public static void main(String[] args) throws IOException {
method1();
}
private static void method1() throws IOException {
//创建两个字节文件输入流对象:指向两个文件
InputStream in = new FileInputStream("FileOutputStreamDemo.java") ;
InputStream in2 = new FileInputStream("FileOutputStreamDemo2.java") ;
//封装到合并流中
SequenceInputStream sis = new SequenceInputStream(in,in2) ;
//目的地文件D:\EE_2110\day26\code\Copy.java
//BufferedOutputStream流
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("D:\\EE_2110\\day26\\code\\Copy.java")) ;
//一次读取一个字节数组
byte[] bytes = new byte[1024] ;
int len = 0 ;
while((len=sis.read(bytes))!=-1){
bos.write(bytes,0,len) ;
bos.flush() ;
}
//释放
bos.close() ;
sis.close();
}
}
public SequenceInputStream(Enumeration<? extends InputStream> e)当两个以上的文件进行复制到一个文件中
public class SequenceInpuStreamTest {
public static void main(String[] args) throws IOException {
//method1();
method2() ;//多个文件进行复制(两个以上的文件)
}
private static void method2() throws IOException {
//当前项目下的FileOutputStreamDemo.java/FileOutputStreamDemo2.java/InputAndOutputStreamCopy.java
//复制到D:\EE_2110\day26\code\\MyCopy.java
// public SequenceInputStream(Enumeration<? extends InputStream> e)
// //创建Vector集合<InputStream>
Vector<InputStream> v = new Vector<>() ;
v.add(new FileInputStream("FileOutputStreamDemo.java")) ;
v.add(new FileInputStream("FileOutputStreamDemo2.java")) ;
v.add(new FileInputStream("InputAndOutputStreamCopy.java")) ;
//类似于迭代器:获取Enumeration枚举组件接口对象
Enumeration<InputStream> enumeration = v.elements();
//直接创建合并流对象
SequenceInputStream sis = new SequenceInputStream(enumeration) ;
//封装目的地文件
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("D:\\EE_2110\\day26\\code\\MyCopy.java")) ;
//一次读取一个字节数组
byte[] bytes = new byte[1024] ;
int len = 0 ;
while((len=sis.read(bytes))!=-1){
bos.write(bytes,0,len) ;
bos.flush() ;
}
//释放
bos.close() ;
sis.close();
}
5.字符流:
1)Reader和Writer的子类进行操作文件复制:
* 如果使用Reader和Writer的子类进行操作:字符转换流(InputStreamReader/OutputStreamWriter)
* 复制文件,太麻烦了!
*
* 他们提供了具体的便捷类,可以直接操作文件 FileReader/FileWriter
* FileReader(String pathname):使用平台默认字符集:进行解码
* FileWriter(String pathname)使用平台默认字符集:进行编码
* 字符流针对文本文件操作:
* 当前项目 FileOutputStreamDemo.java------>拷贝到当前项目下;My.java
public class CopyFileTest {
public static void main(String[] args) {
//捕获异常
//创建字符输入流对象:操作源文件
FileReader fr = null ;
FileWriter fw = null ;
try {
fr = new FileReader("FileOutputStreamDemo.java") ;
fw = new FileWriter("My.java") ;
//读写操作
//一次读取一个字符数组
char[] chs = new char[1024] ;
int len = 0 ;//实际字符数
while((len=fr.read(chs))!=-1){
//写
fw.write(chs,0,len) ;
fw.flush() ;
}
} catch (IOException e) {
e.printStackTrace();
}finally {
if(fw!=null){
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fr!=null){
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
2)字符输入流:Reader:抽象类
子类:InputStreamReader:字符缓冲输入流:通向字节输入流的桥梁
* 构造方法
* InputStreamReader(InputStream in) :使用平台默认的字符集进行解码,里面包装的字节流
* InputStreamReader(InputStream in,String charsetName):使用指定的字符集进行解码
*
* 读取:
* 读一个字符read()
* 读一个字符数组read(char[] chs)
*/
public class InputStreamReaderDemo {
public static void main(String[] args) throws IOException {
//需要读取oos.txt
//创建字符缓冲输入流对象
//InputStreamReader(InputStream in)
InputStreamReader isr = new InputStreamReader(
new FileInputStream("oos.txt"),"GBK") ;
//一次读取一个字符
/* int ch = 0 ;//字符数 ()
while((ch=isr.read())!=-1){
System.out.print((char)ch);
}*/
//一次读取一个字符数组
char[] chs = new char[1024] ;
int len = 0 ;
while((len=isr.read(chs))!=-1){
System.out.print((new String(chs,0,len))) ;
}
//释放资源
isr.close() ;
}
}
3)字符流出:
* 字符流出现的原因:在字节流基础上,它会提供字符集,解决乱码问题!
* 如果使用记事本打开一个文件,(文本文件)---优先采用的就是字符流!
* 图片/音频/视频------>只能使用字节流
*
* Writer:抽象类----->子类 :字符转换输出流OutputStreamWriter:里面包装的是字节流
* 构造方法
* OutputStreamWriter(OutputStream out) :使用平台默认的编码字符集进行编码--->写入数据
* OutputStreamWriter(OutputStream out,String charsetName )使用指定的编码字符集进行编码--->写入数据
* 写的功能:
* write(int ch):写一个字符
* write(char[] chs):写字符数组
* write(char[] chs,int index,int len):写字符数组的一部分
* writer(String str):写字符串
* writer(String str,int index,int len):写字符串的一部分
*
*/
public class OutputStreamWriterDemo {
public static void main(String[] args) throws IOException {
//创建字符输出流对象
//OutputStreamWriter(OutputStream out)
// Writer out = new OutputStreamWriter(new FileOutputStream("out.txt")) ;
/*OutputStreamWriter oos = new OutputStreamWriter(
new FileOutputStream("oos.txt")) ;*///默认平台 utf-8 编码
OutputStreamWriter oos = new OutputStreamWriter(
new FileOutputStream("oos.txt"),"GBK") ;// 指定GBK 编码
oos.write("hello,字符流");
//释放资源
oos.close() ;
}
}
4)字符缓冲输入流(字符流的高效流):
BufferedReader:字符缓冲输入流 提供默认的缓冲区大小 缓冲区足够大 BufferedReader(Reader in)
特有功能: String readLine() 读取一行内容
public class BufferedReaderDemo {
public static void main(String[] args) throws IOException {
//创建字符缓冲输入流对象:读取bw.txt
BufferedReader br = new BufferedReader(new FileReader("bw.txt")) ;
//bw.txt---拷贝D盘:字符缓冲输出流 my.txt
BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\my.txt")) ;
//String readLine() 读取一行内容
/* //第一次读
String line = br.readLine() ; //readLine()阻塞式方法
System.out.println(line) ;
//第二次读
line = br.readLine() ;
System.out.println(line);
//第三次读
line = br.readLine() ;
System.out.println(line);
//第四次读
line = br.readLine() ;
System.out.println(line);
//第五次读
line = br.readLine() ;
System.out.println(line);*/
//循环改进
String line = null ;
while((line=br.readLine())!=null){
//System.out.println(line);
bw.write(line);
bw.newLine();
bw.flush();
}
//释放资源
bw.close();
br.close();
}
}
5)字符缓冲输出流 (字符流的高效流):
仅仅提供缓冲区 * BufferedWriter(Writer out) :提供默认缓冲区大小,默认值足够大:8192个长度(底层是一种字符数组) * 特有功能: * public void newLine() throws IOException :写入行的分隔符号
public class BufferedWriterDemo {
public static void main(String[] args) throws IOException {
//创建字符缓冲输出流对象
BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt")) ;
//写数据
bw.write("hello");
//调用 public void newLine() throws IOException :写入行的分隔符号
bw.newLine() ;
bw.write("world");
bw.newLine() ;
bw.write("java");
bw.newLine() ;
//字符流的使用:在关闭前最好刷新流
//public void flush()
bw.flush() ;
//关闭
bw.close();
}
}
6.序列化:
1)概念:
ObjectOutputStream
就是在将Java对象(实体类:User/Product/Order...)
变成一种流数据,他们里面的数据存储流中,
就可以在网络(服务器集群中:共享)中传输!
1)序列化:OutputStream 构造方法: public ObjectOutputStream(OutputStream out) 成员方法: public final void writeObject(Object obj) throws IOException:写入一个实体对象
2)反序列化ObjectInputStream 就是将流数据(存储的一些相关的实体类数据)-----还原成Java对象! public ObjectInputStream(InputStream in) throws IOException:将文件中的数据,进行读取 public final Object readObject()throws IOException,ClassNotFoundException
public class Person implements Serializable {
//固定的序列化版本Id
private static final long serialVersionUID = 6815664471916807752L;
public transient String name ;//transient可以标记某个成员变量不参与序列化
int age ;
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class ObjectStreamDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
write() ;
//read() ;
}
//反序列
private static void read() throws IOException, ClassNotFoundException {
//创建反序列化流对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("oos.txt")) ;
// public final Object readObject()
Object object = ois.readObject();
System.out.println(object) ;
//关闭资源
ois.close() ;
}
//序列化
private static void write() throws IOException {
//将Person对象中里面成员信息永久存储到指定文件中:序列化,前提条件:Person类型必须实现标记接口序列化!
//文件中乱码,不影响读取,通过反序列化---可以还原回来
//创建序列化流对象
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("oos.txt")) ;
//创建Person类对象
Person p = new Person() ;
p.name = "高圆圆" ;
p.age = 42 ;
//public final void writeObject(Object obj)
oos.writeObject(p) ;
//释放资源
oos.close() ;
}
}
4.Propertis类:
Propertis:属性集合类(属性列表)是一个Map,但是没有泛型,键和值都是String * * 特有功能: * public Object setProperty(String key,String value):添加键和值 * public Set<String> stringPropertyNames():获取所有 键的集合 * public String getProperty(String key):获取键对应的值 * public void store(Writer writer, String comments):将属性列表中的内容保存指定的文件中 * 参数2:给属性列表一个描述 * * public void load(Reader reader):将文件中的内容加载属性列表中
public class PropertiesTest {
public static void main(String[] args) throws IOException {
myLoad() ;
//有一个属性列表
Properties prop = new Properties() ;
prop.setProperty("孙杰","30") ;
prop.setProperty("臧永青","25") ;
prop.setProperty("陈荣昌","28") ;
prop.setProperty("陈琛","28") ;
prop.setProperty("遆子林","25") ;
prop.setProperty("于水利","26") ;
//将属性列表中的内容保存指定文件中
Writer w = new FileWriter("name.txt") ;
prop.store(w,"name's list") ;
//释放资源
w.close() ;
}
//将文件中加载进来,将属性列表中内容可以遍历
private static void myLoad() throws IOException {
Reader r = new FileReader("Lucky.txt") ;
//创建空的列表
Properties prop = new Properties() ;
//System.out.println(prop);
prop.load(r);
//System.out.println(prop);
//获取所有的值
/* Collection<Object> values = prop.values();
for(Object obj :values){
System.out.println(obj);
}*/
Set<String> keySet = prop.stringPropertyNames();
for(String key :keySet){
String value = prop.getProperty(key);
System.out.println(key+"="+value) ;
}
}
}
----------------------加载src 目录 下的文件.properties--------------------------
private static void method() throws IOException {
//文件在哪个了中要读:
//1)获取当前了类的字节码文件对象
/*Class c = Test2.class ;
//2)获取类加载器
ClassLoader classLoader = c.getClassLoader();
//3)通过类加载获取当前src目录下面的配置文件所在的输入流对象
InputStream inputStream = classLoader.getResourceAsStream("name.properties");*/
InputStream inputStream =
Test2.class.getClassLoader().getResourceAsStream("name.properties");
//创建Properties
Properties prop = new Properties() ;
prop.load(inputStream);
System.out.println(prop) ;
}