欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JAVA进阶版:IO

程序员文章站 2022-05-04 09:55:41
...


IO流的种类图:
JAVA进阶版: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();
	}
}
相关标签: # JAVA进阶