Java中的字节流与字符流、缓冲流、转换流、数据流

I/O流

1、I是指Input(输入),O是指Output(输出)。

2、在Java中,文件的输入和输出是通过流(Stream)来实现的,流的概念源于Unix中管道(pipe)的概念。在Unix系统中,管道是一条不间断的字节流,用来实现程序或进程间的通信,或读写外围设备、外部文件等

3、一个流,必有源端和目的端,它们可以是计算机内存的某些区域,也可以是磁盘文件,甚至可以是Internet上的某个URL。对于流而言,我们不用关心数据是如何传输的,只需要向源端输入数据,向目的端获取数据即可

4、流按照处理数据的单位,可以分为字节流和字符流;按照流向分为输入流和输出流(注意:输入流和输出流都是站在程序的角度参照的)

字节流与字符流

字节流用于处理以字节为单位的二进制文件(如音乐、图片等)

//例:
import java.io.IOException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class Test {	
	public static void main(String[] args) {
		FileInputStream fileInputStream=null;//创建输入流变量
		FileOutputStream fileOutputStream=null;//创建输出流变量
		try {
			fileInputStream = new FileInputStream("D:\\图片\\1.jpg");//输入流实例赋值
			fileOutputStream = new FileOutputStream("D:\\图片\\2.jpg");//输出流实例赋值
			int date = 0;
			while((date=fileInputStream.read())!=-1) {//读取文件并暂存入date中,当到文件结尾,没有字节时返回-1
				fileOutputStream.write(date);//写文件,将读取到的文件写入输出实例中
			}
			fileOutputStream.flush();//确认没有残留
		} catch (Exception e) {
			e.printStackTrace();
		}finally {//释放资源
			if(fileInputStream!=null) {
				try {
					fileInputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(fileOutputStream!=null) {
				try {
					fileOutputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

以上程序运行过后,将在D:\图片目录下生成2.jpg文件,内容与1.jpg一样

但是这样一个字节一个字节读写,将会很低效,那么我们能不能一次进行多个字节的输入输出呢?答案是:可以的

import java.io.IOException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class Test {	
	public static void main(String[] args) {
		FileInputStream fileInputStream=null;//创建输入流变量
		FileOutputStream fileOutputStream=null;//创建输出流变量
		try {
			fileInputStream = new FileInputStream("D:\\图片\\1.jpg");
			fileOutputStream = new FileOutputStream("D:\\图片\\2.jpg");
			byte[] date=new byte[1024];//定义一个byte数组,指定能存入1024个数
			int length = 0;
			while((length=fileInputStream.read(date))!=-1) {//读取文件并暂存入date中并返回date个数赋值给length,当到文件结尾,没有字节时返回-1
				fileOutputStream.write(date,0,length);//写文件,将读取到的文件写入输出实例中,从date中的第一个数,输出到第1024个
			}
			fileOutputStream.flush();
		} catch (Exception e) {
			e.printStackTrace();
		}finally {//释放资源
			if(fileInputStream!=null) {
				try {
					fileInputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(fileOutputStream!=null) {
				try {
					fileOutputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

上述代码一次执行1024个字节,明显要比第一种高效很多

字符流与字节流执行过程类似,但是字节符流用于处理字节文件(文本文件)

//例
public class Test {	
	public static void main(String[] args) {
		FileReader filereader=null;//创建字符流输入流变量
		FileWriter filewriter=null;//创建字节流输出流变量
		try {
			filereader = new FileReader("D:\\Program_Files\\博客.txt");//输入流实例赋值
			filewriter = new FileWriter("D:\\Program_Files\\222.txt");//输出流实例赋值
			int date=0;
			while((date=filereader.read())!=-1) {//读取文件并暂存入date中,当到文件结尾,没有字节时返回-1
				filewriter.write(date);//写文件,将读取到的文件写入输出实例中
			}
			filewriter.flush();//确认没有残留
		} catch (Exception e) {
			e.printStackTrace();
		} finally {//释放资源
			if(filereader!=null) {
				try {
					filereader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(filewriter!=null) {
				try {
					filewriter.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

以上代码是将一个文本文档传到另一个地方(222.txt)

但是,同样的问题,低效。解决办法,也是相当雷同。如下:

public class Test {	
	public static void main(String[] args) {
		FileReader filereader=null;
		FileWriter filewriter=null;
		try {
			filereader = new FileReader("D:\\Program_Files\\博客.txt");
			filewriter = new FileWriter("D:\\Program_Files\\222.txt");
			int length=0;
			char[] date=new char[1024];//指定数组大小,即一次传输的量
			while((length=filereader.read(date))!=-1) {
				filewriter.write(date,0,length);;
			}
			filewriter.flush();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if(filereader!=null) {
				try {
					filereader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(filewriter!=null) {
				try {
					filewriter.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

缓冲流

上面说到的I/O流都是直接访问硬盘,进行文件的读写操作,虽然我们通过改变一次传输的量的方式,使效率提高,但仍不足够
缓冲流是一种装饰器类,目的是让原字节流、字符流新增缓冲的功能以提高读取或写入。简单的说,通过缓存存取,间接输入输出
用于字节流:
缓冲字节输入流:
BufferedInputStream(InputStream in):
缓冲字节输出流:
BufferedOutputStream(OutputStream out):

public class Test {	
	public static void main(String[] args) {
		FileInputStream fileInputStream = null;
		FileOutputStream fileOutputStream = null;
		BufferedInputStream bufferedInputStream=null;
		BufferedOutputStream bufferedOutputStream=null;
		try {
			fileInputStream = new FileInputStream("D:\\图片\\1.jpg");
			fileOutputStream = new FileOutputStream("D:\\图片\\2.jpg");
			bufferedInputStream=new BufferedInputStream(fileInputStream);
			bufferedOutputStream=new BufferedOutputStream(fileOutputStream);
			int length = 0;
			byte[] date =new byte[1024];
			while((length=bufferedInputStream.read(date))!=-1) {
				bufferedOutputStream.write(date,0,length);
			}
			bufferedOutputStream.flush();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if(fileInputStream!=null) {
				try {
					fileInputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(fileOutputStream!=null) {
				try {
					fileOutputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(bufferedInputStream!=null) {
				try {
					bufferedInputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(bufferedOutputStream!=null) {
				try {
					bufferedOutputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

用于字符流(也是相当的雷同)
缓冲字符输入流:
BufferedReader(Reader in):
缓冲字符输出流:
BufferedWriter(Writer out):

public class Test {	
	public static void main(String[] args) {
		FileInputStream fileInputStream = null;
		FileOutputStream fileOutputStream = null;
		BufferedInputStream bufferedInputStream=null;
		BufferedOutputStream bufferedOutputStream=null;
		try {
		FileReader filereader=null;
		FileWriter filewriter=null;
		BufferedReader bufferedReader=null;
		BufferedWriter bufferedWriter=null;
		try {
			filereader = new FileReader("D:\\Program_Files\\1.txt");
			filewriter = new FileWriter("D:\\Program_Files\\222.txt");
			bufferedReader=new BufferedReader(filereader);
			bufferedWriter=new BufferedWriter(filewriter);
			int length=0;
			char[] car=new char[1024];
			while((length=bufferedReader.read(car))!=-1) {
				bufferedWriter.write(car,0,length);;
			}
			bufferedWriter.flush();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if(filereader!=null) {
				try {
					filereader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(filewriter!=null) {
				try {
					filewriter.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(bufferedWriter!=null) {
				try {
					bufferedWriter.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(bufferedReader!=null) {
				try {
					bufferedReader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

转换流

由于文件自身编码方式和程序运行时使用的默认编码方式不一致,致使程序读取或输出字符文件时可能会出现乱码,这时可以使用字节流操作文件,然后再将字节流转换成字符流,这一转换过程可以借助转换流实现

public class Test {	
	public static void main(String[] args) {
		InputStreamReader inputStreamReader=null;//定义转换流变量
		OutputStreamWriter outputStreamWriter=null;
		FileInputStream fileInputStream=null;//定义字节流变量
		FileOutputStream fileOutputStream=null;
		try {
			fileInputStream=new FileInputStream("D:\\Program_Files\\1.txt");//字节流实例化
			fileOutputStream=new FileOutputStream("D:\\Program_Files\\2.txt");
			inputStreamReader = new InputStreamReader(fileInputStream);//转换流实例化
			outputStreamWriter = new OutputStreamWriter(fileOutputStream);
			int length=0;
			char[] car=new char[1024];
			while((length=inputStreamReader.read(car))!=-1) {
				outputStreamWriter.write(car,0,length);;
			}
			outputStreamWriter.flush();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {//释放资源
			if(fileInputStream!=null) {
				try {
					fileInputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(fileOutputStream!=null) {
				try {
					fileOutputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(inputStreamReader!=null) {
				try {
					inputStreamReader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(outputStreamWriter!=null) {
				try {
					outputStreamWriter.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

数据流

通过DataInputStream和DataOutputStream数据流可以直接操作基本数据类型和字符串

public class Test {	
	public static void main(String[] args) {
		try {
			double a=9.9;
			DataOutputStream dateoutputstream= new DataOutputStream(new FileOutputStream("D:\\qwe.conj"));//实例化数据流
			dateoutputstream.writeDouble(a);//输出数据
			dateoutputstream.flush();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		try {
			DataInputStream dataInputStream=new DataInputStream(new FileInputStream("D:\\qwe.conj"));//实例化数据流
			double q=dataInputStream.readDouble();//读入数据		
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

但是,需要注意的是,数据流可以输出不同的基本数据类型的数据和字符串类型的数据,但是在读取的时候,需要分别用相应的类型的方法和正确的顺序进行读取。

你可能感兴趣的:(Java中的字节流与字符流、缓冲流、转换流、数据流)