IO流划分:
1.按流向划分:
输入流
输出流
使用输入流还是输出流的依据:
以当前程序为参照物,数据如果流出,则使用输出流;数据如果流入则使用输入流
2.按处理的单位划分:
字节流:用于读取文件的字节数据,数据不经任何处理
字符流:读取的字节数据还会转化成字符数据,读取的是以字符为单位的数据(字符流=字节流+编码/解码)
———|InputStream 抽象类 输入字节流的基类。
————| FileInputStream 读取文件数据 的输入字节流
使用FileInputStream 读取文件数据:
1. 找到目标文件
2.建立数据的输入通道
3. 读取文件的数据
public class Demo1 {
public static void main(String[] args) throws IOException {
read4();
}
//方式4:使用循环配合缓冲 数组读取
public static void read4() throws IOException{
//找到目标文件
File file = new File("F:\\a.txt");
//建立数据的通道
FileInputStream fileInputStream= new FileInputStream(file);
//读取数据
byte[] buf = new byte[1024]; //缓冲字节数组的长度一般都是1024的倍数。
int length = 0 ; //记录本次读取的自己个数。
while((length = fileInputStream.read(buf))!=-1){
System.out.print(new String(buf,0,length));
}
//关闭资源(释放资源文件)
fileInputStream.close();
}
//方式3:使用(缓冲数组)字节数组读取 , 无法完整读取一个文件的数据 12G
public static void read3() throws IOException{
//找到目标文件
File file = new File("F:\\a.txt");
//建立数据的通道
FileInputStream fileInputStream= new FileInputStream(file);
//创建一个字节数组,读取文件数据
byte[] buf = new byte[10];
int length = fileInputStream.read(buf); // read(byte[] buf) 先把读取到的数据存储到字节数组中,然后返回的是本次读取到字节数。
System.out.println("读取到的内容:"+ new String(buf,0,length));
}
//方式2: 每次读取一个字节的数据,可以读取完整文件数据。 340
public static void read2() throws IOException{
long startTime = System.currentTimeMillis();
//第一步:找到目标文件
File file = new File("F:\\美女\\1.jpg");
//第二步: 建立数据通道
FileInputStream fileInputStream = new FileInputStream(file);
//第三步:读取文件的数据
int content = 0; //用于保存读取到的数据
while((content = fileInputStream.read())!=-1){ // read() 方法如果读取了文件的末尾则返回-1表示。
System.out.print((char)content);
}
//关闭资源
fileInputStream.close();
long endTime = System.currentTimeMillis();
System.out.println("运行时间:"+ (endTime-startTime));
}
//方式一: 没法读取完整一个文件的数据
public static void read1() throws IOException{
//第一步: 找到目标文件对象
File file = new File("f:\\a.txt");
//第二步: 建立数据的输入通道
FileInputStream fileInputStream = new FileInputStream(file);
//第三步: 读取文件数据
int content = fileInputStream.read(); // 返回 的是读取的字节数据,每次只会读取一个字节。
System.out.println("读到的内容:"+ (char)content);
//第四步:关闭资源(释放资源文件)
fileInputStream.close();
}
}
——–| OutputStream 抽象类,所有输出字节字节流的父类。
————| FileOutputStream 向文件输出数据的输出字节流。
使用FileOutputStream步骤:
1. 找到目标文件
2. 建立数据的输出通道
public class Demo1 {
public static void main(String[] args) throws IOException {
write3();
}
//方式三:运用String的getBytes方法
public static void write3() throws IOException{
//找到目标文件
File file = new File("F:\\a.txt");
//建立数据的输出通道
FileOutputStream fileOutputStream = new FileOutputStream(file);
//
String data = "abcd";
byte[] buf = data.getBytes(); // 97 98 99 100
fileOutputStream.write(buf, 0, 2); // 指定开始的索引值与字节个数写出。
fileOutputStream.close();
}
//方式二: 先把数据转成字节数组然后再写出。
public static void write2() throws IOException{
//找到目标文件
File file = new File("F:\\a.txt");
//建立数据的输出通道
FileOutputStream fileOutputStream = new FileOutputStream(file,true); //第二个参数为true时,写入文件数据就是以追加的形式写入的
//准备数据, 把数据写出
String str = "\r\nhello world";
//把字符串转成字节数组
byte[] buf = str.getBytes();
//把字节数组写出
fileOutputStream.write(buf);
//关闭资源
fileOutputStream.close();
}
//方式一: 每次只能写 一个字节的数据 。
public static void write1() throws IOException{
//找到目标文件
File file = new File("f:\\a.txt");
//建立数据的输出通道
FileOutputStream fileOutputStream = new FileOutputStream(file);
//把数据写出
fileOutputStream.write('h');
fileOutputStream.write('e');
fileOutputStream.write('l');
fileOutputStream.write('l');
fileOutputStream.write('o');
//关闭资源
fileOutputStream.close();
}
}
FileOutputStream要注意的细节:
1. new FileOutputStream 的时候,如果目标文件不存在,那么会先创建目标 文件,然后再写入。
2. new FileOutputStream(file) 如果目标文件已经存在,那么会先清空 目标文件的数据,然后再写入新的数据.
3. 写入数据的时候如果需要以追加的形式写入,那么需要使用new FileOutputStream(file,true) 这个构造函数。
4. 使用write(int b)方法的时候,虽然参数接受的一个int类型的数据,但是实际上只会把数据的低八位写出,其他24位丢弃。
import java.io.File;
import java.io.FileInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.management.RuntimeErrorException;
/*
IO异常应该如何处理:
*/
public class Demo1 {
public static void main(String[] args) {
readTest();
}
//拷贝图片
public static void copyImage(){
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try{
//找到目标文件
File inFile = new File("F:\\美女\\1.jpg");
File outFile = new File("F:\\拷贝.jpg");
//建立数据的输入输出通道
fileInputStream = new FileInputStream(inFile);
fileOutputStream = new FileOutputStream(outFile);
//建立缓冲字节数组,边读边写
byte[] buf = new byte[1024];
int length = 0 ;
while((length = fileInputStream.read(buf))!=-1){
fileOutputStream.write(buf,0,length);
}
}catch(IOException e){
System.out.println("拷贝出错了...");
throw new RuntimeException(e);
//关闭资源的原则: 先开后关, 后开先关。
}finally{
try{
if(fileOutputStream!=null){
//关闭资源
fileOutputStream.close();
}
}catch(IOException e){
throw new RuntimeException(e);
}finally{
try{
if(fileInputStream!=null){
fileInputStream.close();
}
}catch(IOException e){
throw new RuntimeException(e);
}
}
}
}
public static void readTest() {
FileInputStream fileInputStream = null;
try{
File file = new File("F:\\a.txt");
//建立文件的输入流通道
fileInputStream = new FileInputStream(file);
//建立缓冲字节数组读取文件数据
byte[] buf = new byte[1024];
int length = 0 ; //记录本次读取的字节个数
//读取文件的数据
while((length = fileInputStream.read(buf))!=-1){
System.out.println(new String(buf,0,length));
}
}catch(IOException e){
//如何处理???
System.out.println("读取文件出错...");
throw new RuntimeException(e); // 把真正的异常原因包装到RuntimeException中然后再抛出。 (糖衣炮弹)
}finally{
try{
//关闭资源()
if(fileInputStream!=null){
fileInputStream.close();
System.out.println("关闭资源成功...");
}
}catch(IOException e){
System.out.println("关闭资源失败...");
throw new RuntimeException(e);
}
}
}
}
缓冲输入字节流的作用: 提高我们读取文件数据的效率。
输入字节流的体系:
———-| InputStream 抽象类 所有输入字节流的基类
————–| FileInputStream 读取文件数据的输入字节流
————–|BufferedInputStream 缓冲输入字节流 该类的本质其实只是在内部维护了一个8kb的字节数组而已。
凡是缓冲流都没有读写文件的能力
public class Demo1 {
public static void main(String[] args) throws IOException {
//readTest();
String[] arr = {"a","a","a"};
}
public static void readTest() throws IOException {
//第一步:找到目标文件
File file = new File("F:\\a.txt");
//第二步:建立文件与程序的输入通道
FileInputStream fileInputStream = new FileInputStream(file);
//第三部:建立缓冲输入字节流
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
//读取文件数据
int content = 0;
while((content = bufferedInputStream.read())!=-1){
System.out.print((char)content);
}
//关闭资源
bufferedInputStream.close();
}
//不使用缓冲流读取的
public static void readTest2() throws IOException{
//第一步:找到目标文件
File file = new File("F:\\a.txt");
//第二步:建立文件与程序的输入通道
FileInputStream fileInputStream = new FileInputStream(file);
byte[] buf = new byte[8192];
int length = 0 ;
while((length = fileInputStream.read(buf))!=-1){
System.out.println(new String(buf,0,length));
}
fileInputStream.close();
}
}
疑问: 为什么创建BufferedInputStream对象需要传入一个InputStream的对象呢?
BufferedInputStream没有读取文件 数据的能力,但是又要读取文件的数据,这时候只能依赖一个具备读取文件数据能力的对象。
BuffereInputStream注意的事项:
1. BuffereInputStream 的close方法实际上关闭的就是你传递进去的FileInputStream对象。
缓冲输出字节流作用: 为了提高写文件的效率
———| OutputStream 抽象类, 所有输出字节流的基类。
————-| FileOutputStream 向文件写出数据的输出字节流对象。
————-| BufferedOutputStream 缓冲输出字节流,为了提高写文件数据的效率。
public class Demo2 {
public static void main(String[] args) throws IOException {
//找到目标文件对象
File file = new File("f:\\a.txt");
//建立数据的输出通道
FileOutputStream fileOutputStream = new FileOutputStream(file);
//建立缓冲输出字节流
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
//写数据
String data = "hello world";
bufferedOutputStream.write(data.getBytes());
// bufferedOutputStream.flush(); //把缓冲字节数组的数据写到硬盘上去。
bufferedOutputStream.close();
}
}
BufferedOutputStream 需要注意的事项:
1. 使用BufferedOutputStream的write方法时候,数据其实是写入了BufferedOutputStream内部维护的字节数组中,只有你调用BufferedOutputStream的close方法或者是flush方法数据才会真正的写到硬盘上去或者内部维护的字节数组已经存储满数据了,这时候数据也会写到硬盘上去。
2. BufferedOutputStream 的close方法实际上关闭的就是你传入的OutputStream对象的close方法。