I (in):输入指得就是从外界进入到程序的方向,通常我们是需要读取外界的数据,所以输入流就是用来读取数据的。
O(out):输出指的就是从程序发送到外界的方向,通常我们是需要写出数据到外界,所以输出流就是用来写出数据的。
编写程序除了自身定义一些数据信息时,经常也可能会用到外部的数据,或将自己写的数据发送给外部。
例如我们自己写的程序(APP)想要去读取一个文件,或者想往文件中写一些数据时,就需要用到输入和输出的功能。
Java将输入和输出的过程比喻为(流 Stream),想同一侧顺序移动的过程。
并且定义了两个超类
java.io.InputStream : 输入流
里面规定了所有字节输入流的读取方式,用来实际去读取不同设备的输入流都继承它,因此它里面定义了相关的读取操作.
java.io.OutputStream:输出流
里面规定了所有字节输出流的写出方式,用来实际去写出不同设备的输出流都继承它,因此它里面定义了相关的写出操作.
(可以进行读写文件数据。)
java.io.FileInputStream 和 FileOutputStream
分别继承 InputStream 和 OutputStream
需求,通过程序实现一个文件的拷贝工作.
通过程序获取被复制文件 -----从外输入到程序中获取则使用输入流
通过程序写出要拷贝文件 -----从程序中写出到磁盘上则使用输出流
package io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 文件拷贝演示:
*/
public class CopyDemo {
public static void main(String[] args) throws IOException {
//文件输入流
FileInputStream fis = new FileInputStream("paimeng.jpg");//从外界获取图片
//文件输出流
FileOutputStream fos = new FileOutputStream("paimeng2.jpg");//拷贝到外界
//如果读到的数据为 -1 读完了,如果读到的数据不为 -1 需要一直读
/**
* paimeng.jpg 文件内容:
* 11110000 11111000 00100111 ........
* */
int d;
while ( (d = fis.read()) != -1) { //如果读到的数据不为 -1
//进行拷贝
/**
* paimeng2.jpg 目标文件
* 11110000 11111000 00100111
* */
fos.write(d);
}
fis.close();
fos.close();
}
}
解决拷贝速度,提高每次读写的数据量,减少读写的次数,可以提高读写效率。
一组字节的读写是块读写的形式。
块读写的效率要好,随机读写要差。
package io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 拷贝demo02 -------:使用块读写的方式提高读写效率
*/
public class CopyDemo02 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("./神里.jpeg");//建立输入流管道链接源文件
FileOutputStream fos= new FileOutputStream("./神里4.jpeg");//建立输出流体管道 链接目标写出的文件
int length;
/**
* 1b ---- 8位
* b ---字节
* 1024b ---- 1kb
* 1024kb ---- 1Mb
* 1024MB ---- 1GB
* 1024GB ---- 1TB
* */
byte[] data = new byte[1024*10];//10kb
long start = System.currentTimeMillis();
while ((length =fis.read(data))!= -1){//读取后看下 如果不等于-1 那么就不是文件末尾
// fos.write(data);//将读取到的data数组中的字节 一次行写入到文件中。
/**
* write(int b) 代表传入字节 来写出
* write(byte[] byte) 代表传入一个字节数组 来写出
*/
fos.write(data); //使用含有三个参数的write方法来实现 copy 解决
}
long end = System.currentTimeMillis();
System.out.println("拷贝完毕,总共耗时:"+(end-start)+"ms");
fis.close();//释放输入流体
fos.close();//释放输出流体
}
}
向文件中写入文本数据
package io;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
/**
* 向文件中写入 文本数据的演示:
*/
public class WriteStringDemo {
public static void main(String[] args) throws IOException {
/**
* FileOutputStream(String path,boolean append) //第二个参数代表是否追加内容的意思
* 如果创建时,指定的第二个参数为true时,文件输出流将设置为追加模式
* 也就是指定的文件存在的数据保留,新写入的数据都会继续向文件中进行追加
* */
FileOutputStream fos = new FileOutputStream("fos.txt",true);//建立链接fos文件的管道
String line = "!!";
//将line中的文本数据转换为字节数组
byte[] data = line.getBytes(StandardCharsets.UTF_8);//"utf-8"
//将转换后的字节数组内容写入到文件中
fos.write(data);
// line = "哈哈";
// //将line中的文本数据转换为字节数组
// data = line.getBytes(StandardCharsets.UTF_8);//"utf-8"
// //将转换后的字节数组内容写入到文件中
// fos.write(data);
System.out.println("写出完毕");
fos.close();//释放
}
}
读取文本的演示:
package io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
/**
* 从文本文件中读取文本数据 的演示类:
*/
public class ReadStringDemo {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("fos.txt");
//流可以估算可以读到的字节量(不一定等同实际文件的长度,文件很大的话)
int len = fis.available();
byte[] data = new byte[len];
fis.read(data);//将读到文件的字节内容存放到data数组里面
String line = new String(data,"UTF-8");//将data数组内容转换为String
System.out.println(line);
fis.close();//释放
}
}
节点流和处理流
节点流:称之为低级流,是真实连接程序与另一端的管道,读写一定是建立在节点流的基础上进行的。文件流就是节点流。
处理流:称之为高级流,是不能够独立存在的,必须要建立在其他流上面,目的就是当前数据流经过它的时候,可以做一些加工的处理,简化我们的操作。
实际开发过程中,我们经常会用到高级流,串联一组高级流到低级流上。
缓冲流是一对高级流,作用就是加快读写效率。
package io;
import java.io.*;
/**
* 缓冲 输入流和输出流的使用演示:
* 加快读写效率
* */
public class BOSDemo {
public static void main(String[] args) throws IOException {
//文件输入流
FileInputStream fis = new FileInputStream("中国风PPT.pptx");//从项目路径下获取资源文件
BufferedInputStream bis = new BufferedInputStream(fis);
//文件输出流
FileOutputStream fos = new FileOutputStream("中国风PPT_copy.pptx");//拷贝到项目路径
BufferedOutputStream bos = new BufferedOutputStream(fos);
int d;
long start = System.currentTimeMillis();//获取系统时间 (毫秒单位) 拷贝开始
while ( (d = bis.read()) != -1) {
bos.write(d);
}
long end = System.currentTimeMillis();//拷贝结束的时间
System.out.println("拷贝完毕!耗时:"+(end - start)+"ms");
System.out.println("文件拷贝完成");
bis.close();//释放高级流 内部其实也会帮把对应的低级流进行释放
bos.close();//释放高级流 内部其实也会帮把对应的低级流进行释放
}
}
缓冲流是块读写,如果写的内容太少,并没有及时刷新的话,系统不会立即写出文件,导致有时候可能不及时存入数据的现象,那么需要手动调用flush刷新。
//文件输出流
FileOutputStream fos = new FileOutputStream("bos.txt");
//缓冲输出流
BufferedOutputStream bos = new BufferedOutputStream(fos);
String line = "圣诞节快乐!!!!!!";
byte[] data = line.getBytes("utf-8");
bos.write(data);
bos.flush(); //手动刷新,强制将缓冲区中的内容 一次性写出
System.out.println("写出完毕");
bos.close();//关闭缓冲流 里面会做一次 flush 刷新。
答:程序除了自身定义一些数据信息时,经常也可能会需要读取外部的数据,或将自己写的数据发送给外部。那么就需要用到输入流和输出流.
相对于程序来讲,外部文件读取到程序中使用输入流.
相对于程序来讲,外部文件写出到程序外使用输出流.
答:字节流是低级流,通过字节读写的方式处理文件,字节流的读写都是单字节读写,所以读写效率低.
字节流分为字节输入流FileInputStream 和 字节输出流FileOutputStream
答:缓冲流是高级流,可以加速对于文件资源的读写效率,需要建立在字节流基础上来使用.
缓冲流分为缓冲输入流BufferedInputStream 和 缓冲输出流 BufferedOutputStream