Java IO流

什么是io流

IO指的是输入流(input)和输出流(Output),流是一种抽象概念,是对数据传输的总称。也就是说数据在设备间的传输称为流,流的本质是数据传输。IO流就是用来处理设备间数据传输问题的。常见的应用:文件复制;文件上传;文件下载。

IO流分类

按数据的走向:

输入流:数据流从数据源到程序(以InputStream、Reader结尾)

输出流:数据流从程序到目的地(OutputSttream、Writer结尾)

按处理数据的类型:

字节流:以字节为单位处理数据(以Stream结尾)

字符流:以字符为单位处理数据(Reader,Writer结尾)

按处理对象分类:

节点流:可以直接从数据源或目的地读写数据(如FileInputStream、FileReader)

处理流:不直接连接到数据源或目的地,通过对其他流的处理提高程序的性能(如BufferedInputeStream、BufferedWriter等)

IO流的使用场景

  • 如果操作的是纯文本文件,优先使用字符流

  • 如果操作的是图片、视频、音频等二进制文件。优先使用字节流

  • 如果不确定文件类型,优先使用字节流。

File类

File类是Java提供针对磁盘中的文件或目录转换对象的包装类,一个File对象可以代表一个文件或目录,File对象可以实现获取文件和目录属性的功能,可以对目录进行创建删除等。

针对文件的操作:

createNewFile() 创建新文件

delete()               删除文件

exist()                 判断文件是否存在

getAbsolutePath()获取绝对路径

getName()           获取文件名

针对目录的操作:

exists()                查询目录是否存在

isDirectory()        判断当前路径是否为目录

mkdir() /mkdirs()   创建目录/创建多级目录

getParentFile() 获取当前目录的父级目录

list()                         返回一个字符串数组包括目录中的文件和路径

listFiles()             返回一个File数组用此抽象路径名表示的目录中的文件

文件字节流

字节输入流(FileInputStream)

创建字节输入流对象:

//括号里面为输入文件的绝对路径
FileInputStream fis=new FileInputStream("D:/java/a.txt");

字节输入流读取数据的步骤:

1.创建字节输入对象。

2.调用字节输入流对象的读数据方法(调用read()方法)。

3.关闭流对象(调用close()方法)。

字节输出流(FileOutputStream)

创建字节输出流对象:

//括号里为写入文件的绝对路径
FileOutputStream fos=new FileOutputStream("d:/animal.jpeg");

字节输出流写数据的步骤:

1.创建字节输出流对象。

2.调用字节输出流对象的方法

3.关闭字节输出流对象

写数据默认是在第一行数据头部写入,如若换行则需要在数据最后加/r/n

public FileOutputStream(String name,boolean append) 
//若第二个参数为ture,则在第一行数据尾部写入

字节缓冲流:

字节缓冲输出流 BufferOutputStream:该类实现缓冲输出流。 通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用

BufferOutputStream fis=new BufferOutputStream("");//参数为读取数据的绝对路径

字节缓冲输入流 BufferedInputStream:创建BufferedInputStream将创建一个内部缓冲区数组。 当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充。

BufferedInputStream fos=new BufferedInputStream("");//写入数据的路径

字节输入输出流代码展示:

import java.io.FileInputStream;
import java.io.FileOutputStream;

public class FileStreamBuffedDemo {
	public static void main(String[] args) throws Exception {    //异常处理:可以直接throws,也可以在代码中用try···catch···
		FileInputStream fis=new FileInputStream("d:/picture/dog.jpeg");
		FileOutputStream fos=new FileOutputStream("d:/animal1.jpeg");
			byte[] b=new byte[1024];//字节缓冲区,一次读取一个字节数组的数据,提高读取效率
			int temp=0;
			while((temp=fis.read(b))!=-1) {
				fos.write(b,0,temp);
			}
			    fos.flush();        //将数据从内存中写入磁盘中
				if(fis!=null) {
					fis.close();    //关闭输入流对象
				}		
				if(fos!=null) {
					fos.close();    //关闭输出流对象
				}
			
		}
	}

字符流

        

字符流中和编码解码问题相关的两个类

FileReader:它读取字节,并使用指定的编码将其解码为字符

            方法:read();//可以读取一个字节的数据,也可以读取一个字节数组的数据。        

FileWriter:使用指定的编码将写入的字符编码为字节

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class FileCopyTools2 {
public static void main(String[] args) {
	FileReader fr=null;
	FileWriter fw=null;
	try {
		fr=new FileReader("d:/aa.txt");
		fw=new FileWriter("d:/aaa.txt");
		char[] ch=new char[1024];//字符缓冲区
		int temp=0;
		while((temp=fr.read(ch))!=-1) {
			fw.write(ch,0,temp);
		}
		fw.flush();
	}catch(Exception e) {
	e.printStackTrace();	
	}finally {
		 
			try {              //此处使用try···catch··将异常捕获,第一个案例是通过throws将异常抛出
				if(fr!=null){
				fr.close();}
				if(fw!=null) {
					fw.close();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

}
}

注意:每创建一个流对象,最后都要将其关闭。

字符缓冲流:

BufferedReader:针对字符输入流的缓冲流对象,提供了方便的按行读取的方法readline(),一次读取一整行的数据,效率高。

public class BufferedReaderDemo1 {
public static void main(String[] args) {
	FileReader fr=null;
	BufferedReader br=null;
	try {
		fr=new FileReader("d:/aa.txt");
		br=new BufferedReader(fr);
		String temp="";
		while((temp=br.readLine())!=null) {
			System.out.println(temp);
		}
	}catch(Exception e) {
		e.printStackTrace();
	}finally {
		try {
			if(br!=null)
				br.close();
			if(fr!=null)
				fr.close();
		}catch(Exception e) {
			e.printStackTrace();
		}
	}
}
}

BufferedWriter:针对字符输出流的缓冲对象,提供了newline方法,可实现换行操作

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;

public class BufferedWriterDemo {
public static void main(String[] args) {
	FileWriter fw=null;
	BufferedWriter br=null;
	try {
		fw=new FileWriter("d:/aa.txt");
		br=new BufferedWriter(fw);
		br.write("ggg");
		br.newLine();//此处进行换行
		br.write("sf");
		br.flush();    //文件输出结果为ggg
                                      sf
	}catch(Exception e) {
		e.printStackTrace();
	}finally {
		try {
			if(br!=null)
				br.close();
			if(fw!=null)
				fw.close();
		}catch(Exception e) {
			e.printStackTrace();
		}
	}
}
}

转换流

当用户输入一串字符时,用字节流read方法只能读取其第一位,若想要读取整串字符时需用到BuferedReader缓冲流其参数只能是一个Reader对象,故通过InputStreamReader流对字节流System.in(System.out)转换成Reader()对象,至此就可以通过BufferedReader的对象调用readline方法进行整行读取。

代码演示:

public class ConvertStream {
public static void main(String[] args) {
	BufferedReader br=null;
	BufferedWriter bw=null;
	 try {
		 br=new BufferedReader(new InputStreamReader(System.in));  //将字节流转为字符流
		 bw=new BufferedWriter(new OutputStreamWriter(System.out));
		 String str=br.readLine();
		 bw.write(str);
		 bw.flush();
		
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}finally {
		try {
			if(bw!=null)
			 bw.close();
			if(br!=null)
			 br.close();
		}catch(Exception e) {
			e.printStackTrace();
		}
		 
	}
}
}

字节数组流

用于流和数组之间转化

ByteArrayInputStream:将字节数组作为数据源。

ByteArrayOutputStream:将字节数组作为目的地。

public class ByteArrayDemo {
public static void main(String[] args) {
	byte[] b="sadsa".getBytes();
	ByteArrayInputStream bis=null;
	StringBuilder sb=new StringBuilder();
		try {	
			bis=new ByteArrayInputStream(b);//其参数是一个字节数组对象,这个字节数组就是数据源
			int i=0;
			while((i=bis.read())!=-1) {
				sb.append((char)i);
			}
			System.out.println(sb.toString());
			}catch(Exception e) {
				e.printStackTrace();
			}finally {
				try {
					bis.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
}
}

数据流

数据流将“基本数据类型与字符串类型”作为数据源,从而让输入输出流操作Java基本数据类型与字符串类型
DataInputStream和DataOutputStream提供了所有基本类型数据方法

 DataOutputStream dos = null;
        DataInputStream dis = null;
        try {
            dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("d:/aaa.txt")));
            dos.writeBoolean(true);
            dos.writeChar('as');
            dos.writeDouble(dsa);
            dos.writeInt(23);
            dos.flush();
            dis = new DataInputStream(new BufferedInputStream(new FileInputStream("d:/aaa.txt")));
            //直接读取数据,注意:读取的顺序要与写入的顺序一致,否则不能正确读取
            System.out.println(dis.readBoolean());
            System.out.println(dis.readChar());
            System.out.println(dis.readDouble());
            System.out.println(dis.readInt());

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if(dos!=null){
                    dos.close();
                }
                if(dis!=null){
                    dis.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }

对象流

Java的序列化和反序列化

对象序列化的作用:持久化:把对象的字节序列永久的保存到硬盘上。

                                网络通信:在网络上传送对象的字节序列

对象的序列化:把Java对象转换为字节序列的过程
对象的反序列化:把字节序列恢复为Java对象的过程

序列化使用的类和接口:

 将对象序列化到文件中和反序列化:

package com.io_study;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class ObjectStream {
public static void main(String[] args) {
	ObjectOutputStream oos=null;
	ObjectInputStream ois=null;
	try {
		oos=new ObjectOutputStream(new FileOutputStream("d/"));
		ois=new ObjectInputStream(new FileInputStream("d:/aaa"));
		User u=new User(1,"hh","24");
		oos.writeObject(u);
	User u1=new User(2,"123","312");
	ois.readObject();
		oos.flush();
	}catch(Exception e) {
		e.printStackTrace();
	}finally {
		
			try {
				if(oos!=null) {
				oos.close();
				}
				if(ois!=null) {
					ois.close();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	
}
}

随机访问流

1.RandomAccessFile可以实现两个作用:①实现对一个文件做读和写的操作。

                                                                  ②可以访问文件的任意位置。
2.三个核心方法:
①构造方法RandomAccessFile(String name, String mode):name用来确定文件;mode取r(读)或者rw(读写),通过mode可以确定流对文件的访问权限
②seek(long a):用来定位流对象读写文件的位置,a确定读写位置距离文件开头的字节个数
③getFilePointer() :获取流的当前读写位置。

       

 RandomAccessFile raf = null;
        try {
            raf = new RandomAccessFile("d:/aaaa.txt","rw");
            //将数据写入文件中
            int[] arr = new int[]{10,20,30,40,50,60,70,80,90,100};
            for (int i = 0; i < arr.length; i++) {
                raf.writeInt(arr[i]);
            }
            //将数据隔三个读出
            for (int i = 0; i < arr.length; i+=3) {
                raf.seek(i*4);
                System.out.print(raf.readInt() + "\t");;
            }
            System.out.println();
            //将第四个数据替换成110
            raf.seek(4*3);
            raf.writeInt(110);
            //将数据隔三个读出
            for (int i = 0; i < arr.length; i+=3) {
                raf.seek(i*4);
                System.out.print(raf.readInt() + "\t");;
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if(raf!=null){
                    raf.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }


File类在IO中的作用


当以文件作为数据源或自标时,除了可以使用字符串作为文件以及位置的指定以外,我们也可以使用File类指定。

BufferedReader br = null;
br = new BufferedReader(new FileReader(new File("路径")));

Apache IO包

FileUtils的使用

常用方法:
        读入文件内容
        readFileToString(文件需要写入的内容,字符集)

String con = FileUtils.readFileToString(new File("d:/aaa"),"UTF-8");
System.out.println(con);

      将已筛选的目录拷贝到新位置:
       copyDirectory(File srcDir, File destDir, FileFilter filter)

String destFilePath = "d:/aaa";

//将已筛选的目录复制,并保持原文件日期的新位置。
FileUtils.copyDirectory(file, new File(destFilePath), new FileFilter() {
    @Override
    public boolean accept(File pathname) {
        if(pathname.isDirectory()) return true;
        else {
            boolean b1 = pathname.getName().endsWith(".txt");
            boolean b2 = pathname.getName().endsWith(".jpg");
            return b1 || b2;
        }
    }
});

IOUtils的使用

常用方法:
        将输入流或数组中的内容转换为字符串
          toString(InputStream input, String encoding)

String con = IOUtils.toString(new FileInputStream("d:/aaaa"),"UTF-8");
System.out.println(con);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大狗晋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值