IO
IO就是Input 和 Output
通过IO可以完成对硬盘文件的读和写。
流的分类
一种方式是按照流的方向进行分类的
以内存作为参照物:
从内存中出去的叫做输入(input)或者叫做读(read)
写进内存里边的叫做输出(output)或者叫做写(write)
另一种方式就是按照字节的方式不同进行分类的
有的流是按照字节的方式来读取数据的,一个读取一个字节byte
还有一种流就是万能的,什么类型都可以读取,文本、图片、声音文件、视频文件等。
最主要分为两类
输入流、输出流
字节流、字符流
IO流的四大家族
InputStream :字节输入流
OutputStream:字节输出流
Reader:字符输入流
Write:字符输出流
他们的顶级父类都是抽象类
所有的流都实现了Closeable接口,它们都可以关闭的,都有close()方法
所有的流都实现了Flushable接口, 它们都可以刷新的,都有flush()方法
这里我挑一些比较常用的流来进行讲解
转换流:将字节流转换成字符流
InputStreamReader:字节输出流转字符输出流
OutputStreamWriter:字节输入流转字符输入流
数据缓冲流
BufferedReader:数据缓冲字符输入流
BufferedWriter:数据缓冲字符输出流
BufferedInputStream:数据缓冲字节输入流
BufferedOutputStream:数据缓冲字节输出流
输出流
PrintStream
PrintWriter
数据专属流
DataInputStream
DataOutputStream
对象专属流
ObjectInputStream
ObjectOutputStream
这里我挑一些比较常用的流的方法
一、FileInputStream 文件字节输入流
文件字节输入流是万能的,任何文件都可以采用这个流来进行读取
1. read():读的方法,一次读一个字节byte
public class FileInputStreamTestA{
public static void main(String [] args){
//采用的是绝对路径,当然也可以使用相对路径
FileInputStream fis=null;
try{
fis=new FileInputStream("F:\\temp.txt");
//进行读
//声明一个int值来接收查询出来的
//查询出来几个值返回多少值 如果没查到值返回的是-1
int a=0;
//通过while循环来进行读
while(true){
a=fis.read();
//进行判断,上边说到,如果返回-1就说明里边的字节已经读取完毕了。
if(a == -1){
break;
}
System.out.println(a);
}
//这里说一种比较简单的while循环的写法
while(a=fis.read()!=-1){
System.out.println(a);
}
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}finally{
// 写在finally语句中表示一定确保关闭
try{
if (fis == null) {//避免空指针异常
//关闭的前提是确保流不能为null,如果流是空的在关闭就没必要
fis.close();
}
}catch (IOException e){
e.printStackTrace();
}
}
}
}
2. read(byte[])读的第二种方法,一次读取.length个字节
相比上边的read()方法来说提高了执行效率,减少了内存和硬盘的交互。
public FileInputStreamTestB{
public static void main(String[] args) {
//文件路径F:\temp 在java中\表示转义
//都是采用绝对路径
FileInputStream fis=null;
try{
fis=new FileInputStream("F:\\temp");
//开始读
byte [] bytes= new byte[4];//准备一个长度为4的数组
// while (true){
// int reads=fis.read(bytes);//read(bytes)读取的是几个字节 读取到的字节数量
// if (reads==-1){
// break;
// }
// System.out.print(new String(bytes,0,reads));//把byte数组转成字符串
// }
int reads=0;
while ((reads=fis.read(bytes))!=-1){//另一种读的方式 循环的方式
System.out.print(new String(bytes,0,reads));
}
}catch (FileNotFoundException e){
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 写在finally语句中表示一定确保关闭
try{
if (fis == null) {//避免空指针异常
//关闭的前提是确保流不能为null,如果流是空的在关闭就没必要
fis.close();
}
}catch (IOException e){
e.printStackTrace();
}
}
}
}
3.available()方法:返回流当中没有读到的字节数量
public class FileInputStreamTestC{
public static void main(String[] args) {
//文件路径F:\temp 在java中\表示转义
//都是采用绝对路径
FileInputStream fis=null;
try{
fis=new FileInputStream("F:\\temp");
//开始读
//available()
System.out.println("总字节的数量为:"+fis.available());
byte[] bytes=new byte[fis.available()];//这种方式不适合太大文件,因为byte数组不能太大
int read = fis.read(bytes);
//还剩下几个字节没读
System.out.println("读了"+read+"个字节");
System.out.println("还剩下"+fis.available()+"个字节没读");
}catch (FileNotFoundException e){
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 写在finally语句中表示一定确保关闭
try{
if (fis == null) {//避免空指针异常
//关闭的前提是确保流不能为null,如果流是空的在关闭就没必要
fis.close();
}
}catch (IOException e){
e.printStackTrace();
}
}
}
}
4.skip()方法:跳过几个字节不读
public static void main(String[] args) {
//文件路径F:\temp 在java中\表示转义
//都是采用绝对路径
FileInputStream fis=null;
try{
fis=new FileInputStream("F:\\temp");
//开始读
//skip(Long n)
fis.skip(3);
System.out.println(fis.read());
}catch (FileNotFoundException e){
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 写在finally语句中表示一定确保关闭
try{
if (fis == null) {//避免空指针异常
//关闭的前提是确保流不能为null,如果流是空的在关闭就没必要
fis.close();
}
}catch (IOException e){
e.printStackTrace();
}
}
}
二、FileOutputStream 文件字节输出流
文件字节输出流是负责写的,从文件存到硬盘
1.write()方法:通过byte数组进行写的
public class FileOutputStreamTestA{
public static void main(String[] args) {
//字节输出流
FileOutputStream fos=null;
try {
//这种写入的方法如果没有文件会创建之后写入,如果有就会把源文件清空在进行写入
//已追加的方式在文件末尾写入不会清空源文件 true
fos=new FileOutputStream("F:\\temp",true);
//开始写
byte [] bytes={97,98,99,100};
//将byte数组全部写出
// fos.write(bytes);
//向文件中写入字符串
String a="你好呀!!";
byte[] b = a.getBytes();//getBytes() 把字符串转换为byte数组
fos.write(b);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
通过FileInputStream和FileOutputStream来实现文件的拷贝
拷贝是一边读一边写的
文件是随意的 万能的 什么文件都可以进行拷贝
public class CopyTest{
public static void main(String[] args) {
FileInputStream fis=null;
FileOutputStream fos=null;
try {
//创建一个输入流对象
fis=new FileInputStream("F:\\temp");//读
fos=new FileOutputStream("F:\\temps");//写
//完成一边读一边写
byte[] bytes=new byte[1024*1024];//(一次最多拷贝1M)
int reads=0;
while ((reads=fis.read(bytes))!=-1){//读多少写多少 边读边写
fos.write(bytes,0,reads);
}
// 刷新
fos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
三、FileReader 文件字符输入流
该类只能读取文本文件也就是txt文件
read()方法:读取文件中的值
public class FIleReaderTest{
public static void main(String[] args) {
FileReader fileReader=null;
try {
fileReader=new FileReader("F:\\temp");
char[] chars=new char[1];
//第一种读的方式
// fileReader.read(chars);
// for (char c:
// chars) {
// System.out.print(c);
// }
// 第二种读的方式
int i=0;
while ((fileReader.read(chars))!=-1){
System.out.print(chars);
}
//第三种
// while (true){
// int read = fileReader.read(chars);
// if (read == -1){
// break;
// }
// System.out.println(chars);
//
// }
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (fileReader != null) {
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
FIleWriter 文件字符输出流
只能输出文本文件txt
writer()方法:来进行写入的方法
public static void main(String[] args) {
FileWriter fw=null;
try {
fw=new FileWriter("F:\\temp",true);
char[] chars={'你','好','呀'};
fw.write(chars);
} catch (IOException e) {
e.printStackTrace();
}finally {
if (fw != null) {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
BufferedWriter 带有缓冲区的字符输出流
public class BufferedWriterTest{
public static void main(String[] args) {
//这种类只能获取字符流,所以如果是字节流,需要通过转换流转换为字符流。
try {
//第一种获取方式:获取字符流的方法在里边可以直接写字符流
BufferedWriter bw=new BufferedWriter(new FileWriter("F:\\temp",true));
//第二种获取方式:先获取一个转换流通过转换流把字节流转换为字符流。
BufferedWriter bw2=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("F:\\temp",true)));
bw.write("我是字符输出流的写");
bw.write("\n");
bw2.write("我是转换流的写");
bw2.write("\n");
bw.flush();
bw.close();
bw2.flush();
bw2.close();
//看结果可以看出两种方式都能进行写入
} catch (IOException e) {
e.printStackTrace();
}
}
}
这个是带有缓冲区的字符输出流
带有缓冲区的字符输入流跟这个一样在这里就不进行演示了。
DataOutputStream 数据专属字节输出流
这个类可以将数据连同数据的类型一并写入文件中
这个文件不是普通文本文档,用记事本打开是乱码
public class DataOutputStreamTest{
public static void main(String[] args) {
try {
//创建数据专属的字节输出流
DataOutputStream dos=new DataOutputStream(new FileOutputStream("F:\\data"));
//写数据
byte b=100;
short s=200;
int i=300;
long l=400;
float f=1.0f;
double d=3.14;
boolean sex=false;
char c='a';
//写
//把数据和数据的类型一并写到文件当中
dos.writeByte(b);
dos.writeShort(s);
dos.writeInt(i);
dos.writeLong(l);
dos.writeFloat(f);
dos.writeDouble(d);
dos.writeBoolean(sex);
dos.writeChar(c);
dos.flush();
dos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
现在通过数据专属输出流写进了文件中现在开始进行读。
DataInputStream 数据专属字节输入流
DataOutputStream写的文件,只能使用激光DataInputStream去读,并且读的时候需要提前知道写入的顺序
读的顺序需要和写的顺序一致,
public class DataInputStreamTest{
public static void main(String[] args) {
try {
DataInputStream dis=new DataInputStream(new FileInputStream("F:\\data"));
//按照刚才写入顺序来进行读
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 sex = dis.readBoolean();
char c = dis.readChar();
//输出
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(sex);
System.out.println(c);
dis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}