字节流:
一次读取一个字节数组的方式要比一次读取一个字节方式高效.
一次读取一个字节数组,相当于构造一个缓冲区,
基本的字节流
文件字节输入流/文件字节输出流
高效的字节流(缓冲流)
private static void FileInputStream2() throws Exception { FileInputStream fis=new FileInputStream("01_文件名称过滤器.exe"); FileOutputStream fos=new FileOutputStream("copy2.exe"); int len=0; while((len=fis.read())!=-1) { fos.write(len); fos.flush(); } fis.close(); fos.close(); }
使用字节流一次读取一个字节的方式,会造成中文乱码--->Java提供了一个字符流(专门用来解决中文乱码问题)
文本文件:优先采用字符流
字节缓冲输入流
public BufferedInputStream (InputStream in):默认缓冲区大小构造缓冲输入流对象
public BufferedInputStream (InputStream in,int size):指定缓冲区大小构造缓冲输入流对象
public int read()
public int read(byte[] b,int off,int len)
在使用输入流的时候,
两种方式读取(一次读取一个字节/一次读取一个字节数在),只能用一种方式,否则,会出现错误!
字节缓冲输出流:
构造方式:
(第一种开发中) public BufferedOutputStream(OutputStream out):采用的默认的缓冲区大小(足够大了) ,来构造 一个字节缓冲输出流对象
public BufferedOutputStream(OutputStream out,int size):指定size缓冲区大小构造缓冲输出流对象
IllegalArgumentException - 如果 size <= 0
BufferedInputStream bis=new BufferedInputStream(new FileInputStream("01_文件名称过滤器.exe")); BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("copy.exe")); byte[] by=new byte[1024]; int len=0; while((len=bis.read(by))!=-1) { bos.write(by, 0, len); bos.flush(); } bis.close(); bos.close(); }
操作一个视频文件,来测试速度问题
基本的字节流一次读取一个字节 ://耗时:85772毫秒
基本的字节流一次读取一个字节数组 :共耗时:216毫秒
高效的字节流一次读取一个字节 :共耗时:682毫秒
高效的字节流一次读取一个字节数组:共耗时:49毫秒
编码和解码:前后的编码格式要一致!
编码:
简单理解:将能看懂的东西--->看不懂的东西
将字符串变成一个字节数组
public byte[] getBytes() :平台默认编码集(默认的是Gbk)
public byte[] getBytes(Charset charset) ;"指定编码格式
解码:
看不懂的东西---能看懂的东西
将字节数组--->字符串
public String(byte[] bytes) :使用平台默认编码集(gbk)
public String(byte[] bytes,Charset charset):用指定的编码格式来解码
字符转换输入流:InputStreamReader
InputStreamReader(InputStream in) :构造一个字符转换输入流,默认编码
public InputStreamReader(InputStream in,Charset cs) 构造一个字符转换输入流,指定编码
字符转换输入流=字节流+编码格式
字符流:
字符输入流:Reader
字符输出流:Writer
字符输出流/字符输入流:都是抽象类
使用一个子类:转换流
字符输出流的构造方法
public OutputStreamWriter(OutputStream out):使用默认的编码格式构造一个字符转换输出流对象
public OutputStreamWriter(OutputStream out, Charset cs):使用指定编码格式构造一个字符转换输出流对象
转换流的构成=字节流+编码格式(平台默认/指定)
转换流的对象的创建,格式比较长,非常麻烦,Java--->转换流的便捷类
Reader:抽象类:字符输入流
inputStreamReader(字符转换输入流 :inputStream+编码格式)
便捷类:FileReader,这个类可以直接对文件进行操作
Writer:抽象类:字符输出流
outputStreamWriter(字符转换输出流:outputStream+编码格式)
便捷类:FileWriter,这个类可以直接对文件进行操作
字符输入流读数据的方法:
int read(char[] chs):读取一个字符数组
int read():读取单个字符
字符输出流写数据的功能:
public void write(int c):写单个字符
public void write(char[] cbuf):写字符数组
public abstract void write(char[] cbuf, int off, int len):写字符数组的一部分
public void write(String str):写字符串
public void write(String str,int off, int len):写字符串的某一部分
private static void FileReader1() throws Exception { FileReader fr=new FileReader("01_文件名称过滤器.exe"); FileWriter fw=new FileWriter("copy3.exe"); int len=0; while((len=fr.read())!=-1) { fw.write(len); fw.flush(); } fr.close(); fw.close(); }
flush和close方法的区别?
close:关闭该流,关闭该流对象以及它关联 的资源文件,关闭之后,不能再对流对象进行操作了,否则会有异常
flush:刷新该流,为了防止一些文件(图片文件/音频文件),缺失,或者没有加载到流对象中,刷新了该流,还是可以流对象进行操作
字符缓冲输入流/字符缓冲输出流
在字符流中提供了一个更高效的流-->字符缓冲流
字符缓冲输入流
字符缓冲输出流
BufferedReader:字符缓冲输入流
构造方法
public BufferedReader(Reader in)创建一个使用默认大小输入缓冲区的缓冲字符输入流。
public BufferedReader(Reader in, int sz)创建一个使用指定大小输入缓冲区的缓冲字符输入流。
BufferedWrier:字符缓冲输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入
构造方法
BufferedWriter(Writer out) :默认缓冲区大小构造字符缓冲输出流对象
BufferedWriter(Writer out,int size):指定缓冲区大小
写数据的方式:
一次写一个字节
write(int by)
一次写一个字节数组的一部分
write(byte[] b, int off, int len)
方法:
void flush() ;刷新缓冲区的流
private static void BufferedReader1() throws Exception { BufferedReader br=new BufferedReader(new FileReader("01_文件名称过滤器.exe")); BufferedWriter bw=new BufferedWriter(new FileWriter("copy5.exe")); char[] ch=new char[1024]; int len=0; while((len=br.read(ch))!=-1) { bw.write(new String(ch,0,len)); bw.flush(); } br.close(); bw.close(); }
其他流
标准的输入输出流
InputStream in = System.in
PrintStream out = Syste.out ;
jdk5以后,Java--->Scanner(InputStream in)
键盘录入
1)Scanner
2)BufferedReader里面包装字符转换输入流,包装System.in
先使用字符缓冲输出流写数据,在使用字符缓冲输入读数据,显示控制台上
BufferedReader br = new BufferedReader( new InputStreamReader( System.in)) ; System.out.println("请输入一个字符串:"); String line = br.readLine() ; System.out.println("您输入的字符串是:"+line); System.out.println("请输入一个整数:"); String str = br.readLine() ; int num = Integer.parseInt(str) ; System.out.println("输入的整数是:"+num);
内存操作流:适用于临时存储文件.
内存操作输入流:byteArrayInputStream
ByteArrayInputStream(byte[] buf)
内存操作输出流: byteArrayOutputStream
构造方法:ByteArrayOutputStream()
内存操作流:一个程序结束后,那么这些程序的变量,就会从内存消失(马上消失的这些数据进行读取写入)
ByteArrayOutputStream baos=new ByteArrayOutputStream(); for(int i=0;i<10;i++) { baos.write(("hello"+i).getBytes()); } byte[] by=baos.toByteArray(); ByteArrayInputStream bais=new ByteArrayInputStream(by); int len=0; while((len=bais.read())!=-1) { System.out.print((char)len); }
打印流
字符打印流(针对文本进行操作:PrintWriter)
字节打印流(printStream 和标准输出流有关系 System.out;)
PrintWriter:属于输出流
1)只能写数据(只能针对目的地文件进行操作),不能读数据(不能针对源文件进行操作)
2)可以针对文件直接进行操作
如果一个类中的构造方法里面有File对象或者String类型数据,这个类可以对文本文件直接操作
FileInputStream
FileOutputStream
FileWriter
FileReader..
PrintWriter
3)自动刷新功能::PrintWriter(OutputStream out/Writer out,boolean autoflush);第二个参数如果是true 表示启动自动刷新功能
4)打印的方法:print(XXX x)/println(XXX xx)
输出一个文本文件,启动自动刷新功能
FileReader fr=new FileReader("bbb.txt"); PrintWriter pw=new PrintWriter(new FileWriter("copy.txt"), true); int len=0; while((len=fr.read())!=-1) { pw.write(len); } fr.close(); pw.close();
数据流:针对Java基本类型的数据进行读写操作
数据输入流:DataInputStream
数据输出流:DataOutputStream
DataInputStream dis = new DataInputStream(new FileInputStream("dos.txt")) ; //读 int i = dis.readInt() ; short s = dis.readShort() ; byte b = dis.readByte() ; double d = dis.readDouble() ; float f = dis.readFloat(); boolean flag = dis.readBoolean() ; char ch = dis.readChar() ; dis.close(); System.out.println(i); System.out.println(s); System.out.println(b); System.out.println(d); System.out.println(f); System.out.println(flag); System.out.println(ch);合并流
SequenceInputStream 表示其他输入流的逻辑串联(合并流)
构造方法
public SequenceInputStream(InputStream s1, InputStream s2)
现在的需求:
a.txt+b.txt--->c.txt
StringDemo.java+SystemInDemo.java---->Copy.java
InputStream is1=new FileInputStream("aaa.txt") ; InputStream is2=new FileInputStream("bbb.txt") ; SequenceInputStream ss=new SequenceInputStream(is1, is2); FileOutputStream fos=new FileOutputStream("ccc.txt"); byte [] by=new byte[1024]; int len=0; while((len=ss.read(by))!=-1) { fos.write(by, 0, len); } ss.close(); fos.close(); }