多谢 jametang25 和 孜燃 两位兄弟的博客:
https://blog.csdn.net/u014529755/article/details/50984310
https://blog.csdn.net/qq_15059163/article/details/80723556
一 概述:
1 概述
文件在程序中是以流的形式来操作的,流:是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两个存储位置之间的传输称为流。流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作,按照流向,划分为 输入流 和 输出流,这两个方向的流是以内存为参照,数据从内存流向文件则为输出流,数据从文件流向内存则维输入流。而且,按照传输单位划分为字节流和字符流,字节流可以用于读写二进制文件及任何类型文件,字符流可以用于读写文本文件。可以将流理解为内存和文件之间的管道。
2 字节流和字符流
2.1 字节流和字符流概述
Java IO中用于读写文件的四个抽象类:Reader,Writer,InputStream,OutputStream
根据流所处理的数据类型分为两类:
(1)字节流:用于处理字节数据。(InputStream,OutputStream)
(2)字符流:用于处理字符数据,Unicode字符数据。(Reader,Writer)
在Java中IO操作也是有相应步骤的,以文件操作为例,主要的操作流程如下:
使用File类打开一个文件
通过字节流或字符流的子类,指定输出的位置
进行读/写操作
关闭输入/输出
IO操作属于资源操作,一定要记得关闭
2.2 字符流和字节流的区别
区别1 :读写单位不同,字节流以字节(1 tyte = 8bit)为单位,字符流以字符为单位
区别2 :处理对象不同,字节流可以处理所有类型的数据(如图片等等),而字符流只能处理字符类数据
区别3 :缓存。字节流在操作的时候本身是不会用到缓冲区的,是文件本身的直接操作的;而字符流在操作的时候下后是会用到缓冲区的,是通过缓冲区来操作文件。
注意:优先选用字节流。因为硬盘上的所有文件都是以字节的形式进行传输或者保存的,包括图片等内容。字符只是在内存中才会形成的,所以在开发中,字节流使用广泛。
二 字节流
InputStream : 是所有字节输入流的父类,一般使用它的子类FileInputStream等,它能输入字节流;
OutputStream : 是所有字节输出流的父类,一般使用它的子类FileOutputStream等,它能输出字节流
1 InputStream
FileInputStream:文件输入流,用于从文件读取数据。它的对象可以用关键字 new 来创建,它有多种构造方法可用来创建
创建方法1
InputStream f = new FileInputStream("/data/data/包名/file/hello.text");
创建方法2
File f = new File("/data/data/包名/file/hello.text");
InputStream out = new FileInputStream(f);
三个重要方法:都是将内容以字节(byte)的形式读取到输入流中
int read()
int read(byte[] b)
int read(byte[] b , int off ,int len)
2 OutputStream
文件输出流,用于向文件写入数据,如果该流在打开文件进行输出前,目标文件不存在,该流不会创建该文件,并抛出FileNotFindException,有两个构造方法可以用来创建 FileOutputStream 对象。
创建方法1:
OutputStream f = new FileOutputStream("/data/data/包名/file/hello.text")
创建方法2:
File f = new File("/data/data/包名/file/hello.text");
OutputStream f = new FileOutputStream(f);
三个重要方法:从输出流写出数据到文件中
void write(byte[]/char[] b)
void write(byte[]/char[] b, int off, int len)
void write(int b)
三 字符流
1 Reader
Reader : 所有字符输入流的父类,它以字符流的形式输入
三个重要方法:将内容以字符(char)的形式读取到输入流中
int read()
int read(char[] b)
int read(char[] b , int off ,int len)
2 Writer
Writer : 所有字符输出流的父类,它以字符流的形式输出
三个重要方法:从输出流写出数据到文件中
void write(byte[]/char[] b)
void write(byte[]/char[] b, int off, int len)
void write(int b)
四 内存与外部资源进行数据流交互的类型分类
如果与内存交互的是文件,则使用文件流;如果与内存进行交互的是数组,则使用数组流,其他类似,如下表。
图片来自 :https://blog.csdn.net/u014529755/article/details/50984310
而这些类型的流的一些常用的处理方式。如下表:
图片来自 :https://blog.csdn.net/u014529755/article/details/50984310
五 流交互之文件操作流
字节流: FileInputStream ,FileOutputStream
字符流: FileReader, FileWriter(用法与字节流基本相同)
1 FileInputStream
File file =new File("文件路径"); //1.指定要读 的文件目录及名称
FileInputStream fis =new FileInputStream(file); //2.创建文件读入流对象
fis.close(); //3.关闭流
2 FileOutputStream
File file =new File("文件路径");//1.指定要写到的文件目录及名称
FileOutputStream fos =new FileOutputStream(file); //2.创建文件读入流对象
fos.write(要写出的字节或者字节数组);//3.定义结束标志
fos.flush();//4.刷新流
fos.close(); //5.关闭流
六 流处理之转换流
InputStreamReader 和OutputStreamWriter,这两个类是将字节流转换为字符流的类,InputStreamReader 可以将一个InputStream转换为Reader,OutputStreamWriter可以将一个OutputStream转换为Writer。
1 InputStreamReader
构造方法1 : // 用默认字符集创建一个InputStreamReader对象
InputStreamReader(InputStream in)
构造方法2 : // 接受已指定字符集名的字符串,并用该字符集创建对象
InputStreamReader(InputStream in,String CharsetName)
2 OutputStreamWriter
构造方法1 : // 用默认字符集创建一个OutputStreamWriter对象
OutputStreamWriter(OutputStream in)
构造方法2 : // 接受已指定字符集名的字符串,并用该字符集创建OutputStreamWriter对象
OutputStreamWriter(OutputStream in,String CharsetNarme)
七 流处理之字符打印流
PrintWriter 是字符类型的打印输出流,它继承于Writer,该类可用来创建一个文件并向文本文件写入数据。可以理解为java中的文件输出。
构造方法1
pw = new PrintWriter("f://aaa.txt");
pw.print("Hello World");
pw.close();
构造方法2
File file = new File("f://ccc.txt");
System.out.println(file.exists());//输出为false,因为本地没有ccc.txt
PrintWriter pw = null;
pw = new PrintWriter(file);//先创建ccc.txt(若存在,则不会创建)
pw.print("Hello World");
pw.close();
常用方法:
print(String str):向文件写入一个字符串。
print(char[] ch):向文件写入一个字符数组。
print(char c):向文件写入一个字符。
print(int i):向文件写入一个int型值。
print(long l):向文件写入一个long型值。
print(float f):向文件写入一个float型值。
print(double d):向文件写入一个double型值。
print(boolean b):向文件写入一个boolean型值。