字节流和字符流是流的一种划分
节点流和处理流是流的另外一种划分
先说下字节流和字符流
字节流:以字节为基础操作基础的情况下对流进行定义。
字符流:是以字符为操作基础,它使用的编码表是Unicode,所以可以国际化,并且在某些情况下,字符流比字节流更高效,
但是底层上,字符流也是基于字节流的; (就好像,Java用操作符可以完成数组排序,但实际上用一些工具类的方法
可以快速完成数组排序;)
字符流=字节流+编码表(Unicode)
字符流
package com.gx.iodemo;
import java.io.CharArrayReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.Writer;
import java.util.Arrays;
/**
* 字符流
*
* 字符流和字节流的区别
1.字节流:顾名思义,在以字节为基本操作基础的情况下对流进行定义;
2.字符流:是以字符为操作基础,它使用的编码表是Unicode,所以可以国际化,并且在某些情况下,字符流比字节流更高效,
但是底层上,字符流也是基于字节流的; (就好像,Java用操作符可以完成数组排序,但实际上用一些工具类的方
法可以快速完成数组排序;)
字符流=字节流+编码表(Uincode)
*
* 数据流在java.io包中,基本输入/输出流类可按其读写数据的类型之不同分为两种:字节流和字符流。
*
* @author en
*
*/
public class Demo03_ReaderAndWriter {
public static void main(String[] args) throws Exception {
//dooa();//读取文件内容长度
//doob();//123.txt内容写入到 1232.txt
dome3();//将输入的字符串写入1232.txt
}
//读取文件内容长度
public static void dooa() throws IOException{
//应是开启读取流 (主要文件123.txt是已经存在的)
Reader reader=new FileReader("E:\\e\\123.txt");//对文件进行读取操作
String str="";
//缓冲区越大 ,运行时所占内存越大,耗时短,相反 缓冲区越小 ,运行时所占内存越小,耗时长
char[] cbuf=new char[1024000];//创建字符型数组 (缓冲区)
int count=0;//记录字节大小,就可获取对应的有效字节(要不会带结尾后的空格符保存进去,还有就是cbuf)
//reder(或writer).read(cbuf,off,len)
//参数:cbuf:目的地缓冲区、off:开始存储字符的偏移量、len:要读取的最大字符数
//已读取的字符数,如果已到达流的结尾,则为-1。 如果发生I/O错误 抛出IOException
while(-1!=(count=reader.read(cbuf, 0, cbuf.length))){//-1 是个判断
//System.out.println(cbuf);
str=str+String.valueOf(cbuf,0,count);
}
//用完流,要记得关闭流
reader.close();
System.out.println("显示文件长度:"+str.length());//显示str里字符个数
}
//123.txt内容写入到 1232.txt
public static void doob() throws IOException{
//错误的写法
// String str="ab";
// Writer writer=new FileWriter("E:\\e\\1234.txt");//默认创建
// char[] cbuf1=str.toCharArray();//把字符串值转化为字符串数组类型
// char[] cbuf1=str.();//把字符串值转化为字符串数组类型
// writer.write(cbuf1, 0, cbuf1.length);
// writer.close();
Writer writer=new FileWriter("E:\\z\\1234.txt");
StringReader stringReader=new StringReader(str);
//----------------------------------------------------
//正确的处理方式
Reader reader2=new FileReader("E:\\e\\123.txt");//对文件进行读取操作
Writer writer2=new FileWriter("E:\\e\\1232.txt");//对文件进行写入操作
String str2="";
char[] cbuf2=new char[102400];//缓冲区
int count2=0;
子类必须实现的唯一方法是read(char[],int,int)和close()
while(-1!=(count2=reader2.read(cbuf2, 0, cbuf2.length))){
writer2.write(cbuf2, 0, count2);//把cbuf2所存的字符写入writer2里(1232.txt)
}
reader2.close();
writer2.close();
}
//将输入的字符串写入1232.txt (原理:先将 字符串 转为 字符数组,再讲 字符数组转为字符流)
public static void dome3() throws Exception{
String strstr="zeng guoxiabcdefghig0123456789C";
char[] cs=strstr.toCharArray();//将此字符串转换为新的字符数组
//将字符数组转为字符流(此类实现了一个字符缓冲区,可以用作字符输入流)
CharArrayReader reader=new CharArrayReader(cs);
Writer writ=new FileWriter("E:\\e\\1232.txt");
char[] cbuf2=new char[10];//(设定)缓冲区 (缓冲区越大 ,运行时所占内存越大,耗时短)
int count2=0;//记录字节大小,就可获取对应的有效字节(要不会带结尾后的空格符保存进去
while(-1 !=(count2=reader.read(cbuf2, 0, cbuf2.length))){
writ.write(cbuf2, 0, count2);
}
reader.close();
writ.close();
}
}
字节流
package com.gx.iodemo;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* 字节流
*
* 数据流在java.io包中,基本输入/输出流类可按其读写数据的类型之不同分为两种:字节流和字符流。
*
* @author en
*
*/
public class Demo04_InputStreamAndOutputStream {
public static void main(String[] args) throws IOException {
demo_1();//将文件写入到其他文件(这里是实现复制操作)
}
public static void demo_1() throws IOException {
File file=new File("E:\\e\\downloadfile(5).mp4");//
InputStream is=new FileInputStream(file);//InputStream字节输入流
//MKV是Matroska的一种媒体文件, Matroska是一种新的多媒体封装格式
//Matroska最大的特点就是能容纳多种不同类型编码的视频、音频及字幕流,即使是非常封闭
//的RealMedia及QuickTime也被它包括进去了,并将它们的音视频进行了 重新组织 来达到更好的效果。
//可以说是对传统媒体格式的一次大颠覆!它现在几乎变成了一个万能的媒体容器。
OutputStream os=new FileOutputStream("E:\\e\\666.mkv");//好像有个转换格式的效果 OutputStream 输出流
//FileOutputStream是(输出)字节流 如果字符串包含中文,就会出现乱码
//解决方法是使用OutputStreamWriter将字节流转换为字符流写入,同时指定utf-8编码。代码如下:
//OutputStreamWriter oStreamWriter = new OutputStreamWriter(new FileOutputStream(file), "utf-8");
//oStreamWriter.append(str);
//oStreamWriter.close();
//缓冲区:类似储存空间 它会把某文件传入的流滞留在这 等待别人获取(移走)
//缓存区:就是把某个“东西”保留下在这储存中(基本都有存活时间),别人可以在他存活期间调用或获取他。
byte[] buf=new byte[10240];//缓冲区
int count=0;
while(-1!=(count=is.read(buf, 0, buf.length))){//count就是得出的字节流了。
os.write(buf,0,count);
}
// //InputStream和OutputStream 一般辩证的来看,一个读,一个写,两者差不多的用法。
// FileOutputStream fos = new FileOutputStream(f);
is.close(); //is.flush();//清空缓存区 旧版的 现在os.close()已经包含了它
os.close();
}
}
节点流和处理流
功能划分:节点流可以从或者向一个特定的节点读写数据
处理流:是对一个数据已存在的流的连接和封装,通过所疯转的流的功能调用实现数据读写,如BufferedReader.
处理流的构造方法总是要带一个其他的流对象做参数,一个流对象经过其他的流的多次包装称为流的链接。
package com.gx.iodemo;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
/**
* 处理流 可以隐藏底层设备上节点流的差异,并对外提供更加方便的输入/ 输出方法,让程序员只需关心高级流的操作。
* 使用处理流时的典型思路是,使用处理流来包装节点流,程序通过处理流来执行输入/输出功能, 让节点流与底层的I/O设备
* 、文件交互。
* 处理流和节点流的区别,只要流的构造器存在参数不是一个物理节点,而是己经存在的流,那么这种流就一定是处理流;
* 而所有节点流都是直接以物理IO节点作为构造器参数的。
*
* @author en
*
*/
public class Demo05_PrintStream {
public static void main(String[] args) throws IOException {
demo2();
}
public static void demo2() throws IOException{
// Writer writer=new FileWriter("E:\\z\\asdg123.txt");
// PrintWriter printWriter=new PrintWriter(writer);
//如果没有asdg123.txt就默认创建
PrintWriter printWriter=new PrintWriter("E:\\e\\asdg123888.txt");
String str="sdfghjk0sdd";
String str2="sdfghjk0sdd";
String str3="sdfghjk0sdd";
printWriter.println(str);
printWriter.println(str2);
printWriter.println(str3);
/**
* 在使用处理流包装了底层节点流之后,关闭输入/输出流资源时,只要关闭最上层的处理流即可。
* 关闭最上层的处理流时,系统会自动关闭被该处理流包装的节点流。
*/
printWriter.close();
}
//
public static void demo1() throws IOException{
Writer writer=new FileWriter("E:\\e\\asdg.txt");//创建一个写入字符流 在给定文件名的情况下构造FileWriter对象。
String str="sdfghjk0sdd\n";
String str2="sdfghjk0sdd";
String str3="sdfghjk0sdd";
writer.write(str);
writer.write(str2);
writer.write(str3);
writer.close();
}
}