JAVA进阶版:IO


IO流的种类图:
在这里插入图片描述

1. File

1.1 FileInputStream(文件字节输入流)

:从硬盘中输入到内存中

(1)读取字节时,超过的字节都输出-1

package javase.jingjie.IO;
/**
 * java.io.InputStream;
 *    java.io.FileInputStream;文件字节输入流
 *    按照字节方式读取文件
 * */
import java.io.*;
public class FileInputStreamTest01 {

	public static void main(String[] args) {
		
		FileInputStream fis=null;
		
		 try {
			 //1.要读取文件,先与这个文件创建一个“输入流”
			 
			 //相对路径(所有的相对都是基于根目录/项目javase.jingjie)
			 String filePath="src/javase/jingjie/IO/text.txt";//相对路径(相对的是根目录/项目javase.jingjie)
			
			 //绝对路径:加上盘符E等
			 //String filePath="E:\\java\\java chengxu\\java duixiang\\eclipse chengxu02\\src\\javase\\jingjie\\IO\\text.txt";
			 //String filePath="E:/java/java chengxu/java duixiang/eclipse chengxu02/src/javase/jingjie/IO/text.txt";
			 fis= new FileInputStream(filePath);
			
			 //2.开始读,
			 for(int n=0;n<8;n++) {
				 int i=fis.read();
				 System.out.println(i);//以字节的方式读取,如果已经读取到文件的末尾,没有值时,则读取-1
			 }
			 
		 }catch(FileNotFoundException e) {
			 e.printStackTrace();
		 }catch(Exception e) {
			 e.printStackTrace();
		 }
		 finally {
			 //为了保证流一定会释放,所以在finally语句块中执行
			 if(fis!=null) {
				 try {
					 fis.close();
				 }catch(Exception e) {
					 e.printStackTrace();//打印异常的语句,常出现在catch语句块中
				 }
			 }
		 }
	}
}

下面是text.txt

abcedf

结果:97
98
99
101
100
102
-1
-1


(2)以text.txt为读取

package javase.jingjie.IO;
import java.io.*;
public class FileInputStreamTest02 {

	public static void main(String[] args) throws Exception {
		// 1.创建流
		FileInputStream fis=new FileInputStream("src/javase/jingjie/IO/text.txt");
		
		//2.开始读
		int temp=0;
		while((temp=fis.read())!=-1) {
			System.out.println(temp);
		}
		//关闭
		fis.close();
	}
}
abcedf

结果:97
98
99
101
100
102


(3) read读取字节

package javase.jingjie.IO;
/**
 * int read(byte [] bytes)
 * 读取之前在内存中准备一个byte数组,每次读取多个字节存储到byte数组中
 * 一次读取多个字节,不是单个字节,效率变高了
 * */
import java.io.*;
public class FileInputStreamTest03 {

	public static void main(String[] args) throws Exception{
		//1.创建输入流
		FileInputStream fis= new FileInputStream("src/javase/jingjie/IO/jh.txt");
		
		//2.开始读,准备一个byte数组 
		byte [] bytes = new byte[3];//每一次最多读取3个字节
		
		//int read(byte[] bytes);该方法返回的it类型的值代表的是,读取了多少个字节
		int i1=fis.read(bytes);//3个字节
		//将byte数组转换成字符串
		System.out.println(new String(bytes));//abc
		
		int i2=fis.read(bytes);//3个字节
		System.out.println(new String(bytes));//def
		
		int i3=fis.read(bytes);//2个字节
		//System.out.println(new String(bytes));//ghf
		//真正的读取是2个字节 gh
		System.out.println(new String(bytes,0,i3));//gh  0开始,i3代表长度	
		int i4=fis.read(bytes);//-1,已经到文件的末尾,返回-1		
		System.out.println(i1);
		System.out.println(i2);
		System.out.println(i3);
		System.out.println(i4);		
		//关闭
		fis.close();	
	}
}

(4)new String(bytes,0,temp)数据转换成字符串输出

package javase.jingjie.IO;
//循环读取
import java.io.*;
public class FileInputStreamTest04 {
	public static void main(String[] args) throws Exception{	
		FileInputStream fis = new FileInputStream("src/javase/jingjie/IO/FileInputStreamTest04.java");		
		//循环读取
		byte[] bytes= new byte[1024];//每次读取1KB
		while(true) {
			int temp=fis.read(bytes);
			if(temp==-1)break;	
			//将byte数组中有效的数据转换成字符串
			System.out.println(new String(bytes,0,temp));
		}	
		//升级循环
		int temp=0;
		while((temp=fis.read(bytes))!=-1) {
			System.out.println(new String(bytes,0,temp));
		}
		fis.close();
	}
}

(5)fis.available() 读取剩余字节数 / fis.skip() 跳过字节数

package javase.jingjie.IO;
import java.io.*;
public class FileInputStreamTest05 {
	public static void main(String[] args) throws Exception{
		//1.创建流
		FileInputStream fis=new FileInputStream("src/javase/jingjie/IO/text.txt");
		
		System.out.println(fis.available());//6, 返回6个字节
		
		System.out.println(fis.read());//97
		
		//int available();//返回流中剩余的估计字节数
		System.out.println(fis.available());//5  读取一个字节97,还剩5个		
		//跳过2个字节
		fis.skip(2);
		System.out.println(fis.read());//101,  abcedf读取一个,跳过2个,读到e为101	
		fis.close();
	}
}

1.2 FileOutputStream(文件字节输出流)

:从内存输出到硬盘中

package javase.jingjie.IO;
/**
 * java.io.OutputStream;
 *    java.io.FileOutputStream;文件字节输出流
 * 将计算机内存中的数据写入硬盘文件中
 * */
import java.io.*;
public class FileOutputStreamTest01 {

	public static void main(String[] args) throws Exception{
		//1.创建文件字节输出流,谨慎使用,会将源文件内容覆盖
		//FileOutputStream fos =new FileOutputStream("src/javase/jingjie/IO/temp02.txt");
		
		//以追加方式append写入
		FileOutputStream fos =new FileOutputStream("src/javase/jingjie/IO/temp02.txt",true);
		
		//2.开始写
		String msg="HelloWorld!中国人";
		
		//将String转换成byte数组
		byte[] bytes=msg.getBytes();
		
		//将byte数组中的全部数据写入
		fos.write(bytes);//HelloWorld!中国人
		
		//将byte数组中的部分数据写入
		fos.write(bytes,0,3);//Hel  从0位置开始,读3个字节
		
		//推荐最后的时候为了保证数据完全写入硬盘,所以要刷新
		fos.flush();//强制写入
		
		//关闭流
		fos.close();
	}
}
运行多次的结果:
HelloWorld!HelHelloWorld!HelHelloWorld!HelHelloWorld!HelHelloWorld!HelHelloWorld!HelHelloWorld!HelHelloWorld!HelHelloWorld!HelHelloWorld!HelHelloWorld!HelHelloWorld!HelHelloWorld!HelHelloWorld!HelHelloWorld!HelHelloWorld!HelHelloWorld!HelHelloWorld!HelHelloWorld!HelHelloWorld!HelHelloWorld!HelHelloWorld!中国人Hel

1.3 FileReader(文件字符输入流)

package javase.jingjie.IO;
/**
 * java.io.Reader;
 *    java.io.InputStreamReader;转换流(字节输入流-->字符输入流)
 *       java.io.FileReader;文件字符输入流
 * */
import java.io.*;
public class FileReaderTest01 {

	public static void main(String[] args) {
		// 创建文件字符输入流
		FileReader fr =null;
		
		try {
			fr= new FileReader("src/javase/jingjie/IO/FileReaderTest01.java");
			
			//开始读
			char [] chars=new char[512];//1KB是1024个字节,1个字符占2个字节,所以为512个字符
			
			int temp=0;
			while((temp=fr.read(chars))!=-1) {
				//将char数组有效部分转换成字符串
				System.out.println(new String(chars,0,temp));
			}
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			if(fr!=null) {
				try {fr.close();
				}catch(Exception e) {
					e.printStackTrace();
				}
			}
		}
	}
}

1.4 FileWriter(文件字符输出流)

package javase.jingjie.IO;
/**
 * java.io.Writer;
 *   java.io.OutputStreamWriter;转换流(字节输出流-->字符输出流)
 *      java.io.FileWriter;文件字符输出流
 * */
import java.io.*;
public class FileWriterTest01 {
	public static void main(String[] args) throws Exception{
		// 创建文件字符输出流
		//FileWriter fw= new FileWrite("src/javase/jingjie/IO/temp03.txt");//覆盖
		FileWriter fw= new FileWriter("src/javase/jingjie/IO/temp03.txt",true);//追加		
		//开始写
		fw.write("我爱我的祖国!");	
		//将char数组的一部分写入
		char[] chars= {'我','是','中','国','人','!','*','#'};
		fw.write(chars,0,5);
		//刷新
		fw.flush();
		//关闭
		fw.close();
	}
}
结果:
我爱我的祖国!我是中国人

2. Buffered

  • 1.字节
    BufferedInputStream;
    BufferedOutputStream;
  • 2.字符
    BufferedReader;//带有缓冲区的字符输入流
    BufferedWriter;//带有缓冲区的字符输出流
  • 3.Buffered里面的循环while((temp=br.readLine())!=null)为null,不再是为-1;为readLine()是一行一行的读,不再是read(),一个个读。

2.1 BufferedReader

(1)带有缓冲区的字符输入流

package javase.jingjie.IO;
import java.io.*;
public class BufferedReaderTest01 {
	public static void main(String[] args) throws Exception{
		// 创建带有缓冲区的字符输入流
		//FileReader fr= new FileReader("src/javase/jingjie/IO/BufferedReaderTest01.java");
		//BufferedReader br= new BufferedReader(fr);
		
		//根据流出现的位置,流又可以分为:包装流或者处理流和节点流
		//FileReader fr是节点流。BufferedReader br包装流
		BufferedReader br= new BufferedReader(new FileReader("src/javase/jingjie/IO/BufferedReaderTest01.java"));
		
		//开始读,readLine()是一行一行的读
		String temp=null;
		while((temp=br.readLine())!=null) {
			System.out.println(temp);
		}
		//关闭
		//注意:关闭的时候只需要关闭最外层的包装流
		br.close();
	}
}

(2)字节流转换成字符流:InputStreamReader

package javase.jingjie.IO;
import java.io.*;
/**
 * BufferedReader
 * 利用转换流InputStreamReader
 * */
public class BufferedReaderTest02 {

	public static void main(String[] args) throws Exception{
		/*
		// 创建带有缓冲区的字符输入流
		FileInputStream fis=new FileInputStream("src/javase/jingjie/IO/BufferedReaderTest02.java");//文件字节输入流
		
		//转换流(将字节流转换成字符流)
		InputStreamReader isr =new InputStreamReader(fis);
		
		BufferedReader br=new BufferedReader(isr);//isr是字符流
		*/
		
		//简化
		BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream("src/javase/jingjie/IO/BufferedReaderTest02.java")));
		
		//开始读
		String temp=null;
		while((temp=br.readLine())!=null) {
			System.out.println(temp);
		}
		//关闭
		//注意:关闭的时候只需要关闭最外层的包装流
		br.close();
	}

}

(3)接收用户键盘输入:System.in

package javase.jingjie.IO;
/**
 * 接收用户键盘输入
 * */
import java.io.*;
import java.util.*;
public class BufferedReaderTest03 {

	public static void main(String[] args) throws Exception{
		/*
		//以前的方式
		Scanner s= new Scanner(System.in);//System.in是一个标准的输入流(Reader抽象),默认接收键盘的输入
		String str=s.next();
		System.out.println("您输入了: "+str);
		*/
		
		//使用BufferedReader用来接收用户的输入,空格和空格之后的字符串也能输出
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		
		//接收输入(每一次都接收一行)
		String str=br.readLine();
		System.out.println("您输入了:"+str);
		
		br.close();
	}

}

2.2 BufferedWriter

带有缓冲区的字符输出流

package javase.jingjie.IO;
/**
 * BufferedWriter
 * */
import java.io.*;
public class BufferedWriterTest01 {

	public static void main(String[] args) throws Exception{
		
		//BufferedWriter bw= new BufferedWriter(new FileWriter("src/javase/jingjie/IO/Temp04.txt"));
		
		//OutputStreamWriter-->  字节转换字符;  通过追加,获取多个结果
		BufferedWriter bw= new BufferedWriter(new OutputStreamWriter(new FileOutputStream("src/javase/jingjie/IO/Temp04.txt",true)));
		bw.write("大家好!我来自中国");
		//写入一个行分隔符
		bw.newLine();
		bw.write("我来自美国");
		//输出流 才有刷新
		bw.flush();
		//关闭
		bw.close();
	}
}
结果(运行多次的结果):

大家好!我来自中国
我来自美国大家好!我来自中国
我来自美国大家好!我来自中国
我来自美国大家好!我来自中国
我来自美国大家好!我来自中国
我来自美国大家好!我来自中国
我来自美国大家好!我来自中国
我来自美国

2.3 装饰者

package javase.jingjie.IO;
public class 装饰者 {
	public static void main(String[] args) {
		/*1.创建被装饰者
		FileReader1 fr= new FileReader1();
		2.创建装饰者
		BufferedReader1 br= new BufferedReader1(fr);
		*/
		BufferedReader1 br= new BufferedReader1(new FileReader1());
		//3.通过执行装饰者中的方法间接去执行被装饰者中的方法
		br.close();
	}
}
abstract class Reader1{
	public abstract void close();
}
/**
 * 使用BufferedReader1对FileReader1中的close方法进行扩展
 * 1.装饰者模式要求:装饰者中含有被装饰者的引用。
 * 2.装饰者模式要求:装饰者和被装饰者应该实现同一个类型
 * */
class BufferedReader1 extends Reader1{//BufferedReader1装饰者
	//关联关系
	Reader1 reader;//FileReader1就是被装饰者,也继承Reader1中所有属性
	
	//构造器
	BufferedReader1(Reader1 reader){
		this.reader=reader;
	}
	
	//对FileReader1中的close方法进行扩展
	public void close() {
		//扩展
		System.out.println("扩展代码1");
		reader.close();
		System.out.println("扩展代码2");
	}
}

/**
 * 思考:
 * 对FileReader1中的close方法进行扩展:
 * 1.继承(不推荐,代码耦合度太高,不利于项目扩展)
 * 2.装饰者模式。
 * */
class FileReader1 extends Reader1{
	public void close() {
		System.out.println("FileReader1 closed!");
	}
}

3. Data

3.1 DataInputStream(数据字节输入流)

package javase.jingjie.IO;
/**
 * DataInputStream
 * */
import java.io.*;
public class DataInputStreamTest01 {

	public static void main(String[] args) throws Exception{
		// 创建数据字节输入流
		DataInputStream dis=new DataInputStream(new FileInputStream("src/javase/jingjie/IO/temp05.txt"));
		
		//读。注意:要使用该流读取数据,必须提前知道该文件中数据的存储格式,顺序。
		//读的顺序必须和写入的顺序(dos.writeByte.......等)相同。
		byte b= dis.readByte();
		short s= dis.readShort();
		int i=dis.readInt();
		long l=dis.readLong();
		float f= dis.readFloat();
		double d=dis.readDouble();
		boolean o=dis.readBoolean();
		char c=dis.readChar();
		
		//将temp05.txt的内容输出到控制台
		System.out.println(b);
		System.out.println(s);
		System.out.println(i);
		System.out.println(l);
		System.out.println(f);
		System.out.println(d);
		System.out.println(o);
		System.out.println(c);
	}
}
结果:10
11
20
19
123.9
234.5
true
s

3.2 DataOutputStream(数据字节输出流)

package javase.jingjie.IO;
/**
 * java.io.DataOutputStream;数据字节输出流
 * 
 * 可以将内存中的“int i=10;”写入到硬盘文件中,写进去的不是字符串
 * 写进去的是二进制数据,带类型
 * */
import java.io.*;
public class DataOutputStreamTest01 {

	public static void main(String[] args) throws Exception{
		// 创建数据字节输出流
		DataOutputStream dos = new DataOutputStream(new FileOutputStream("src/javase/jingjie/IO/temp05.txt"));
		
		//准备数据
		byte b= 10;
		short s= 11;
		int i=20;
		long l=19L;
		float f= 123.9f;
		double d=234.5;
		boolean o=true;
		char c='s';
		
		//写
		dos.writeByte(b);
		dos.writeShort(s);
		dos.writeInt(i);
		dos.writeLong(l);
		dos.writeFloat(f);
		dos.writeDouble(d);
		dos.writeBoolean(o);
		dos.writeChar(c);
		dos.flush();
		dos.close();
	}
}

4. Object

4.1 反序列化ObjectInputStream

package javase.jingjie.IO;
/**
 * 反序列化
 * 结果:User[name=胡歌,霍建华,袁弘,null]  加过transien后 age为null
 * */
import java.io.*;
public class ObjectInputStreamTest01 {
	public static void main(String[] args) throws Exception{
		//1.创建反序列化流
		ObjectInputStream ois=new ObjectInputStream(new FileInputStream("src/javase/jingjie/IO/temp06.txt"));
		//2.反序列化,readObject()是Object类型
		Object o=ois.readObject();//User[name=胡歌,霍建华,袁弘]
		//输出到控制台
		System.out.println(o);
		ois.close();
	}
}

4.2 序列化ObjectOutputStream

注意:
1.Serializable接口:该接口是一个“可序列化的”,起到标识作用
2. transien:如果不想让该属性参加序列化,需要使用transient关键词修饰, transient String age;//加过transien后,序列化值为null,空

package javase.jingjie.IO;
/**
 * java.io.ObjectOutputStream;序列化java对象到硬盘(serial)
 * java.io.ObjectInputStream;将硬盘中的数据“反序列化”到jvm内存(deserial)
 * 
 * Compile 编译(java-->class)
 * DeCompile 反编译(class-->java)
 * */
import java.io.Serializable;//该接口是一个“可序列化的”,只是一个标识接口,接口中没有任何方法
import java.io.*;
public class ObjectOutputStreamTest01 {

	public static void main(String[] args) throws Exception{
		//1.创建java对象
		User u1=new User("胡歌,霍建华,袁弘","35岁"); 

		//2.创建输出流(序列化流) (JVM中的java对象状态保存到硬盘)
		ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("src/javase/jingjie/IO/temp06.txt"));
		
		//3.写
		oos.writeObject(u1);//u1必须进行过序列化,否则编不出来
		
		oos.flush();
		oos.close();
	}

}
 class User implements Serializable{//该接口是一个“可序列化的”,起到标识作用
	  String name;
	
	 //如果不想让该属性参加序列化,需要使用transient关键词修饰
	  transient String age;//加过transien后,序列化值为null,空
	 
	 User(String name,String age){
		 this.name=name;
		 this.age=age;
	 }
	 public String toString() {
		 return "User[name="+name+","+age+"]";
	 }
 }

5. Print

  • java.io.PrintStream;标准的输出流,默认打印到控制台,以字节方式
  • java.io.PrintWriter;以字符方式

5.1 PrintStream(标准的输出流)

package javase.jingjie.IO;
import java.io.*;
import java.text.*;
import java.util.*;
public class PrintStreamTest01 {
   public static void main(String[] args) throws Exception{
   	//默认是输出到控制台的
   	System.out.println("Hello,World");//Hello,World
   	
   	//上面的是下面的简写,一般用上面的
   	PrintStream ps= System.out;
   	ps.println("JAVA Is Good!!!");//JAVA Is Good!!!
   	
   	//可以改变输出方向,不再是输出到控制台,而是文本
   	//此处出现异常
   	System.setOut(new PrintStream(new FileOutputStream("src/javase/jingjie/IO/log.txt")));
   	System.out.println("绝地反击");
   	
   	//通常我们使用上面的这种方式记录日志
   	//需求:记录日志,m1方法开始执行的时间和结束的时间,记录到log文件中
   	SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:sss");//日期格式
   	System.out.println("m1方法开始执行:"+sdf.format(new Date()));//new Date()现在时间  format()日期-->字符串
   	m1();
   	System.out.println("m1方法结束执行:"+sdf.format(new Date()));
   }
   public static void m1() {
   	System.out.println("m1方法正在执行");
   }
}

结果:

绝地反击
m1方法开始执行:2019-10-25 15:55:14:014
m1方法正在执行
m1方法结束执行:2019-10-25 15:55:14:014

6.Copy复制

(1) 输入流和输出流同时用:复制粘贴

package javase.jingjie.IO;
/**
 * 关于文件复制粘贴
 * */
import java.io.*;
public class copy {
	public static void main(String[] args) throws Exception{
		//创建输入流
		FileInputStream fis= new FileInputStream("src/javase/jingjie/IO/text.txt");
		//创建输出流
		FileOutputStream fos=new FileOutputStream("e:/text.txt");//把该文件复制粘贴到E盘
		
		//一边读,一边写
		byte [] bytes= new byte[1024];//1kb
		int temp=0;
		while((temp=fis.read(bytes))!=-1) {
			//将byte数组中的内容直接写入
			fos.write(bytes,0,temp);
		}
		//刷新
		fos.flush();
		//关闭
		fis.read();
		fis.close();
	}
}

(2) 复制纯文本文件

package javase.jingjie.IO;
import java.io.*;
/**
 * 文件复制
 * 只能复制纯文本文件
 * */
public class copy02 {
	public static void main(String[] args) throws Exception{
		// 创建字符输入流、输出流
		FileReader fr=new FileReader("src/javase/jingjie/IO/copy02.java");
		FileWriter fw=new FileWriter("e:/copy02.java");//复制到E盘
		char[] chars=new char[512];
		int temp=0;
		while((temp=fr.read(chars))!=-1) {
			fw.write(chars,0,temp);
		}
		fw.flush();
		fr.close();
		fw.close();
	}
}

(3) BufferedReader和BufferedWriter完成复制

package javase.jingjie.IO;
/**
 * 使用BufferedReader和BufferedWriter完成复制
 * */
import java.io.*;
public class copy03 {
	public static void main(String[] args) throws Exception{
		//创建流
		BufferedReader br=new BufferedReader(new FileReader("src/javase/jingjie/IO/copy03.java"));
		BufferedWriter bw=new BufferedWriter(new FileWriter("e:/copy03.java"));
		String temp=null;
		while((temp=br.readLine())!=null) {
			bw.write(temp);
			bw.newLine();//每次都保证一行后换行
		}
		bw.flush();
		br.close();
		bw.close();
	}
}
发布了71 篇原创文章 · 获赞 10 · 访问量 3418

猜你喜欢

转载自blog.csdn.net/JH39456194/article/details/104075687