什么是流?
流是个抽象的概念,是对输入输出设备的抽象,输入流可以看作一个输入通道,输出流可以看作一个输出通道。
输入流是相对程序而言的,外部传入数据给程序需要借助输入流。
输出流是相对程序而言的,程序把数据传输到外部需要借助输出流。
什么是字节流?
字节流–传输过程中,传输数据的最基本单位是字节的流。
什么是字符流?
字符流–传输过程中,传输数据的最基本单位是字符的流
字节流
字节流的类通常以stream结尾
常用的字节输入流主要有:
InputStream
FileInputStream
BufferedInputStream
使用:
将一个TXT中的文本信息打印出来:
public class FileInputStreamDemo {
public static void main(String[] args) {
InputStream is =null;
try {
is = new FileInputStream(new File("E:/java文本/a.txt")); //内存中得有这个文件夹
byte[] chars = new byte[1024]; //在 InputStreamDemo中用字节
int lenth = 0;
while((lenth = is.read(chars))!=-1){
//把a.txt读到chars里
String str = new String(chars,0,lenth); //循环把字节数组变成字符串
System.out.println(str);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
is.close(); //关闭流
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
运行结果:
常用的字节输出流主要有:
OutputStream
FileOutputStream
BufferedOutputStream
使用:
将字符串打印到TXT中:
public class Demo {
//往一个文本文件中写一句话“hello world。”
public static void main(String[] args){
OutputStream os = null;
try {
//1.创建流对象(字节流输出)
File file = new File("E:/java文本/a.txt"); //如果没有这个文件,会自动创建
os = new FileOutputStream(file,true); //OutputStream是抽象类,FileOutputStream是子类,参数为File型
String str = "hello world.";
//2.调用流对象的方法进行写入操作
byte[] bytes = str.getBytes(); //将字符串改为字节数组
os.write(bytes); //把bytes写到a.txt里参数为字节数组
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
//3.释放
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
常见的字符输入流有:
Reader
InputStreamReader
FileReader
BufferedReader
使用:
public class FileReaderDemo {
public static void main(String[] args) {
Reader r1 = null;
try {
r1 = new FileReader(new File("E:/java文本/a.txt"));
char[] chars = new char[1024]; //定义字符数组,字符通常都是1024的倍数
int length = 0;
//因为文件内容不知道多大,用一个循环,每读到1024个输出,每读到1024个输出,
while((length = r1.read(chars))!=-1){
// Length = r1.read(chars):把r1的内容读到chars字节数组中,返回值为int,当中参数为char型,内容不等于-1说明还没有空
String str = new String(chars,0,length); //把字符数组中的内容转成字符串
System.out.println(length+"--------"+str);
}
} catch (FileNotFoundException e) {
//读文件的前提是,文件必须存在,否则会抛异常
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
r1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
运行结果:
常见的字符输出流有:
Writer
OutputStreamWriter
FileWriter
BufferedWriter
使用:
往一个文件这个追加字符串
public class FileWriteDemo {
public static void main(String[] args) {
Writer fw = null;
try {
//true表面文档里之前的东西不会被覆盖,而是写在后面
fw = new FileWriter(new File("E:/java文本/a.txt"),true);
fw.write("zhangsan lisi");
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
字符缓存流
FileReader和FileWriter在读取的时候是读一次或者写一次就请求磁盘,这样使用的时间非常的长,效率比较低,因此引入BufferedReader和BufferedWriter作为读取和写入的缓存区.
1、 BufferedReader一次读取8K的字符流到内存中,当程序读取字符时会先到BufferedReader中读取,若没有的话BufferedReader再从磁盘中读取,一次又是8k
2、BufferedWriter作为写入缓存区,要写入文件的字符流写入BufferedWriter(缓存中),当刷新或关闭BufferedWriter时,才写入磁盘,减少磁盘的写入次数,提高效率
字符缓存输入流:
将TXT中的数据加到程序中:
public class BufferedReaderDemo {
public static void main(String[] args) {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(new File("E:/java文本/a.txt")));
String str = null;
while((str = br.readLine()) != null){
//readLine()为每次读取一行
System.out.println(str);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
字符缓存输出流:
将字符串输出到TXT中:
public static void main(String[] args) {
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new FileWriter(new File("E:/java文本/a.txt"),true)); //其实是对流对象进行包装
bw.newLine(); //写入一行空行
bw.write("你好,我好,大家好");
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
bw.flush(); //将缓存数据刷到硬盘上
bw.close(); //关闭
} catch (IOException e) {
e.printStackTrace();
}
}
}
实例:将a.txt中的数据拷贝到d.txt中
代码:
public class BufferedInputStreamAndBufferedOutputSream {
public static void main(String[] args) {
//a.txt拷贝到d.txt
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(new FileInputStream(new File("E:/java文本/a.txt"))); //外内
bos = new BufferedOutputStream(new FileOutputStream(new File("D:\\d.txt"))); //内外
byte[] bytes = new byte[1024];
int length = 0;
while((length=bis.read(bytes))!=-1){
bos.write(bytes, 0, length);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
bos.flush();
bos.close();
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
对于现在相同的功能发现有两组操作类可以使用,那么在开发中到底该怎么使用哪种会更好呢?
关于字节流和字符流的选择没有明确的定义要求,但是有如下的选择参考:
(1)java最早提供的实际上自由字节流,而在JDK1.1之后才增加了字符流;
(2)字符数据可以方便地进行中文的处理,但是字节数据处理起来会比较麻烦;
(3)在网络传输或者是进行数据保存的时候,数据操作单位都是字节,而不是字符;
(4)字节流和字符流在操作形式上都是类似的,只要一种流会使用了,其他的留都可以采用同样的方式完成。
(5)字节流操作时没有使用到缓冲区,字符流操作时需要缓冲区处理数据,字符流会在关闭的时候默认清空缓冲区,如皋现在操作时没有关闭,则用户可以使用flush()方法手工清空缓冲区。
所以对于字节流和字符流的选择,我们建议:在开发中尽量都去使用字节流进行操作,因为字节流可以处理图片、音乐、文字,也可以方便进行传输或者文字的编码转换;如果在处理中文的使用考虑字符流。