流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。它的特性是进行数据传输
例如从水源地长江把水导入自来水厂,然后又从自来水厂把水送到各家各户。从长江到自来水厂之间的管道我们可以称之为输入流,从自来水厂把水送到各家各户的管道我们称之为输出流,我们大概可以这么理解。
(1)按照流的流向分,可以分为输入流和输出流。
输入流: 只能从中读取数据,而不能向其写入数据。
输出流:只能向其写入数据,而不能向其读取数据。
(2)按照操作单元划分,可以划分为字节流和字符流。
字节流和字符流的用法几乎完成全一样,区别在于字节流和字符流所操作的数据单元不同,字节流操作的单元是数据单元是8位的字节,字符流操作的是数据单元为16位的字符。
字节流主要是由InputStream和outPutStream作为基类,而字符流则主要有Reader和Writer作为基类。
(3)按照流的角色划分为节点流和处理流。
可以从/向一个特定的IO设备(如磁盘,网络)读/写数据的流,称为节点流。节点流也被称为低级流。
处理流则用于对一个已存在的流进行连接和封装,通过封装后的流来实现数据的读/写功能。处理流也被称为高级流。
FileInputStream流被称为文件字节输入流,意思指对文件数据以字节的形式进行读取操作如读取图片视频等。
InputStream f = new FileInputStream("C:/java/hello");
File f = new File("C:/java/hello");
InputStream f = new FileInputStream(f);
public static void main(String[] args) throws IOException {
//创建对象
File file = new File("C:\\Users\\wawjy\\Desktop\\cc.txt");
InputStream is = new FileInputStream(file);
//读取数据
int bit = is.read();
//输出数据
System.out.println("读取到的数据是:"+(char)bit);
//关闭资源
is.close();
}
int read(byte[] b):从输入流中最多读取b.length个字节的数据,并将其存储在字节数组b中,返回实际读取的字节数
int read(byte[] b, int off, int len):从输入流中最多读取len个字节的数据,并将其存储在数组b中;放入数组b中时,并不是从数组起点开始,而是从off位置开始,返回实际读取的字节数FileInputStream继承InputStream,使用FileInputStream读取文件内容
public static void main(String[] args) throws IOException {
//声明对象
InputStream is = new FileInputStream("C:\\Users\\wawjy\\Desktop\\cc.txt");
//读取数据
//声明一个字节数组
byte[] buf = new byte[1024];
//读取一个字节数组长度的数据 返回读取到的字节数组的长度
int len = is.read(buf);//会将数据读取到buf中
//分析数据
String msg = new String(buf,0,len);
System.out.println(msg);
//关闭资源
is.close();
}
FileOutputStream流是指文件字节输出流,专用于输出原始字节流如图像数据等,其继承OutputStream类,拥有输出流的基本特性。
该类用来创建一个文件并向文件中写数据。
如果该流在打开文件进行输出前,目标文件不存在,那么该流会创建该文件。
有两个构造方法可以用来创建FileOutputStream 对象。
OutputStream f = new FileOutputStream("C:/java/hello")
File f = new File("C:/java/hello");
OutputStream f = new FileOutputStream(f);
write(byte[] b) :将 b.length 个字节从指定 byte 数组写入此文件输出流
write(byte[] b, int off, int len) :将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流
public static void main(String[] args) throws IOException {
//创建对象
OutputStream os = new FileOutputStream("aaa.a",true);
//声明写出的数据
String msg = "laoxuezhideniyongyou";
//写出数据
os.write(msg.getBytes(),0,10);
//关闭资源
os.close();
}
}
public static void main(String[] args) throws IOException {
// 创建输出流对象
OutputStream os = new FileOutputStream("abc.txt");
//声明写出数据
int num = 97;
//写出数据
os.write(num);
//关闭
os.close();
}
字节字符输入流。InputStreamReader类是从字节流到字符流的桥接器:它使用指定的字符集读取字节并将它们解码为字符。 它使用的字符集可以通过名称指定,也可以明确指定,或者可以接受平台的默认字符集。每次调用一个InputStreamReader的read()方法都可能导致从底层字节输入流中读取一个或多个字节。
*public int read():
读取单个字符。读取的字符,如果已到达流的末尾,则返回 -1
public static void main(String[] args) throws IOException {
//创建对象
Reader reader = new InputStreamReader(new FileInputStream("a.txt"));
//读取
int num = reader.read();
//分析结果
System.out.println(num);
//关闭
reader.close();
//System.out.println((char)(new FileInputStream("a.txt").read()));
}
*public int read(char[] ,int off, int len):
从数组的第off个位置起读取 len个字节,读取的字符数,如果已到达流的末尾,则返回 -1
public static void main(String[] args) throws IOException {
//创建对象
Reader reader = new InputStreamReader(new FileInputStream("C:\\Users\\wawjy\\Desktop\\c.txt"));
//声明字符数组
char[] chs = new char[1024];
//将读取到的信息存放在chs字符数组中 返回读取大文件的字符个数
int count = reader.read(chs);
System.out.println(new String(chs, 0, count));
//关闭
reader.close();
//System.out.println((char)(new FileInputStream("a.txt").read()));
}
字符流通向字节流的桥梁,可以使用指定的charset将要写入流的字符编码为字节。它使用的字符集可以由名称指定或显示给定,否则接受平台默认的字符集。
写入单个字符。c - 指定要写入字符的 int。
public static void main(String[] args)throws IOException {
//创建对象
Writer out=new OutputStreamWriter(new FileOutputStream("z.txt"));
//声明输出数据
int num=97;
//输出数据
out.write(num);
//刷新
out.flush();
//关闭资源
out.close();
}
写入字符串。 str - 要写入的字符串
public static void main(String[] args)throws IOException {
//创建对象
Writer out=new OutputStreamWriter(new FileOutputStream("z.txt"));
//声明输出数据
String str="hello java!";
//输出数据
out.write(str);
//刷新
out.flush();
//关闭资源
out.close();
}
刷新该流的缓冲。
关闭此流,但要先刷新它。
BuffereReader继承于Reader,是字符输入缓冲流。 BufferedReader类从字符输入流中读取文本并缓冲字符,以便有效地读取字符,数组和行可以通过构造函数指定缓冲区大小也可以使用默认大小。对于大多数用途,默认值足够大由Reader构成的每个读取请求都会导致相应的读取请求由基础字符或字节流构成,通过BufferedReader包装Reader的实例类可以提高效率如
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("a.txt")));
read():读取单个字符;
read(char[] cbuf,int off,int len):将字符读入数组的某一部分;
public static void main(String[] args)throws IOException {
//创建对象
BufferedReader reader=new BufferedReader(new InputStreamReader(new FileInputStream("abc.txt")));
//声明字符数组
char[] chs=new char[1024];
//将读取到的信息存放在chs字符数组中 返回读取大文件的字符个数
int count=reader.read(chs);
System.out.println(new String(chs,0,count));
//关闭资源
reader.close();
}
public static void main(String[] args)throws IOException {
//创建对象
BufferedReader reader=new BufferedReader(new InputStreamReader(new FileInputStream("abc.txt")));
//读取数据
String str;
while ((str=reader.readLine())!=null){
System.out.println(str);
}
//关闭资源
reader.close();
}
从read()方法理解,若使用InputStreamReader的read()方法,可以发现存在每2次就会调用一次解码器解码,但若是使用 BufferedReader包装 InputStreamReader后调用read()方法,可以发现只会调用一次解码器解码,其余时候都是直接从BufferedReader的缓冲区中取字符即可。
从read(char cbuf[], int offset, int length)方法理解,若使用InputStreamReader的方法则只会读取leng个字符,但是使用BufferedReader类则会读取读取8192个字符,会尽量提取比当前操作所需的更多字节。
因此可以看出BufferedReader类会尽量提取比当前操作所需的更多字节,以应该更多情况下的效率提升,因此在设计到文件字符输入流的时候,使用BufferedReader中包装InputStreamReader类更好。
BufferedWriter类将文本写入字符输出流,缓冲字符。因此,可以高效地写入单个数组,字符和字符串。需要指定缓冲区大小,如果不是,则需要默认值。Writer立即将输出设置为底层字符或字节流。
void write(char ch);//写入单个字符。
void write(char []cbuf,int off,int len)//写入字符数据的某一部分
public static void main(String[] args)throws IOException {
//创建对象
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("abc.txt")));
//写出数据
char[] chs={'h','e','l','l','0','!'};
bw.write(chs,0,2);
//刷新
bw.flush();
//关闭资源
bw.close();
}
public static void main(String[] args)throws IOException {
//创建对象
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("abc.txt")));
//写出数据
String str="hello java!";
bw.write(str,0,5);
//刷新
bw.flush();
//关闭资源
bw.close();
}
public static void main(String[] args)throws IOException {
//创建对象
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("abc.txt")));
//写出数据
bw.write("我自横刀向天笑");
bw.newLine();
bw.write("去留肝胆两昆仑");
//刷新
bw.flush();
//关闭资源
bw.close();
}
OutputStream:表示输出字节流所有类的超类。输出流接受输出字节并将它们发送到某个接收器。一般使用它的子类,如FileOutputStream等。
OutputStreamWriter:OutputStreamWriter是从字符流到字节流的桥接:写入它的字符使用指定的字节编码为字节字符集。它使用的字符集可以通过名称指定,也可以明确指定,或者可以接受平台的默认字符集。每次调用write()方法都会导致在给定字符上调用编码转换器。生成的字节在写入底层输出流之前在缓冲区中累积。可以指定此缓冲区的大小,但默认情况下,它足够大,可用于大多数用途。注意,传递给write()方法的字符不会被缓冲。为了获得最高效率,可以在BufferedWriter中包装OutputStreamWriter,以避免频繁的转换器调用。
BufferedWriter:将文本写入字符输入流,缓冲字符,以便地写入单个字符,数字和字符串。可以指定缓冲区大小,或者可以接受默认大小,对于大多数用途,默认值足够用提供了一个newLine()方法,它使用平台自的分行隔符概念。并非所有的平台都是用换行符 “\n” 来终止行,因此,调用此方法终止输出行比直接写换行符更为可取。通常,Writer会立即将其输出发送到基础字符或字节流,除非需要提示输出,否则将BufferedWriter包装在任何write() 操作可能代价高昂的Writer周围
,或者可以接受平台的默认字符集。每次调用write()方法都会导致在给定字符上调用编码转换器。生成的字节在写入底层输出流之前在缓冲区中累积。可以指定此缓冲区的大小,但默认情况下,它足够大,可用于大多数用途。注意,传递给write()方法的字符不会被缓冲。为了获得最高效率,可以在BufferedWriter中包装OutputStreamWriter,以避免频繁的转换器调用。