--------------------ASP.Net+Android+IOS开发、.Net培训、期待与您交流!
--------------------
1.字节流
字符流:Writer,Reader 主要是用来操作的是文本文件
字节流:InputStream,OutputStream主要是用来操作的是媒体文件,例如:图片,音乐,电影…等。但是也可以操作文件。
如果用字符流操作媒体文件的话,复制文件的话:也能复制,只是复制后的图片不能看,因为查看的编码是不一样的,
不管是读还是写,都不需要刷新缓冲,除非用到了缓冲对象。
2. FileOutStream
操作文件,向文本文件中写入数据,其没有写入字符串耳朵方法,有字节数组的写入,所以我们要把字符串转换成数组。然后写入。
- importjava.io.FileNotFoundException;
- importjava.io.FileOutputStream;
- importjava.io.IOException;
- importjava.io.OutputStream;
- public classOutStreamDemo {
- public static void main(String[]args) {
- OutputStream out=null;
- try {
- out=new FileOutputStream("F:\\demo.txt");
- out.write("helloworld".getBytes());//写入数据,把字符串转换为字节数组
- } catch (IOException e) {
- e.printStackTrace();
- }finally{
- if(out!=null){
- try {
- out.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
- }
3. FileInputStream
读取文件,有三种方法,
第一种:一个一个字符的读取,
第二种:字节数组的读取。
第三种:使用available()方法,读取到文件的总大小,然后定义相同大小的字节数组,读取一次即可,但是加入文件过大,大于了虚拟的内存的大小,那么就会加载不进去,所以最好的办法是定义恰当合适的数组,然后循环读取。
1. 单个字节读取
使用的read()方法,进行循环读取。
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.io.InputStream;
- public class InputStreamDemo {
- public static void main(String[] args) {
- InputStream in = null;
- try {
- in = new FileInputStream("F:\\demo.txt");
- /* 这个为一个一个的读取,使用read()方法,然后读取到的字符的ASCII码,到结尾就返回-1*/
- int r = -1;
- while ((r = in.read()) != -1) {//开始读取
- System.out.print((char) r);
- }
- } catch (IOException e) {
- e.printStackTrace();
- }finally{
- if(in!=null){
- try {
- in.close();//关闭流
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
- }
2. 字节数组读取
定义恰当的数组,然后循环读取 使用的read(byte [] b)
然后转换成字符串,返回。
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.io.InputStream;
- public class InputStreamDemo {
- public static void main(String[] args) {
- InputStream in= null;
- try {
- in= new FileInputStream("F:\\demo.txt");
- /* 使用字节数组读取,然后转成字符串。到结尾就返回-1*/
- byte [] b=new byte[1024];
- int len=-1;
- while ((len = in.read(b)) != -1) {//开始读取
- System.out.print(new String(b,0,len));
- }
- } catch (IOException e) {
- e.printStackTrace();
- }finally{
- if(in!=null){
- try {
- in.close();//关闭流
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
- }
3. 固定数组大小
使用的available()方法,读取到文件的大小,然后定义相应的大小的字节数组,如果文件小的话,可以这样使用,但是文件很大,超过了虚拟机的申请的内存,那么就会导致加载不进入,所以最好的方法是是哟第二种方法,定义合适的字节数组的大小。
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.io.InputStream;
- public class InputStreamDemo {
- public static void main(String[] args) {
- InputStream in = null;
- try {
- in = new FileInputStream("F:\\demo.txt");
- /* 使用字节数组读取,数组的大小用:available()方法定,然后转成字符串。到结尾就返回-1 */
- byte[] b = new byte[in.available()];
- int len = in.read(b);
- System.out.print(new String(b, 0,len));
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- if (in != null) {
- try {
- in.close();// 关闭流
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
- }
4. 复制图片
使用的InputStream和OutputStream
步骤:
1.使用读取流InputStream,与要读取的图片关联。
2.定义写入流,定义好复制到的位置和图片的名称。
3.然后一边读取一边写入,循环读取和循环写入。使用的是数组读取和写入。
4.最后关闭流。
扩展:复制后的文件名称可以改变也可以不变,格式也可以改变,jpg或者bmp.或者其他的格式都可以
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- public class OutAndInputStreamDemo {
- public static void main(String[] args) {
- InputStream in = null;// 读取流字节流
- OutputStream out = null;// 写入流字节流
- try {
- in = new FileInputStream("F:\\A\\1.jpg");// 与复制的图片关联起来
- out = new FileOutputStream("F:\\B\\1.bmp");// 与复制到的目的关联起来,这里的图片的名称可以与原来的相同,也可以不一样
- byte[] b = new byte[1024];// 定义字节数组,并指定长度
- int l = -1;
- while ((l = in.read(b)) != -1) {// 读取
- out.write(b, 0, l);// 写入,读多少写入多少,所以用 write(b,0,len)
- }
- System.out.println("复制成功");
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- if (in != null) {
- try {
- in.close();// 关闭读取流
- } catch (IOException e) {
- System.out.println("读取流关闭失败");
- }
- if (out != null) {
- try {
- out.close();// 关闭写入流
- } catch (IOException e) {
- System.out.println("写入流关闭失败");
- }
- }
- }
- }
- }
- }
- 结果:
- 复制成功
5. 字节流的缓冲
字符流:Writer,Reader
BufferedWriter和BufferedReader
字节流:InputStream,OutputStream体文
BufferedInputStream和BufferedOutputStream
字节流的缓冲和字符流的花冲使用方法是类似的,用的对象是BufferedInputStream和BufferedOutputStream,他们增强了字节流的读取和写入效率。
1. 利用缓冲对象复制MP3文件
- package www.fuxi.IO;
- import java.io.BufferedInputStream;
- import java.io.BufferedOutputStream;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
- public class BufferedStreamDemo {
- public static void main(String[] args) {
- BufferedInputStream bis = null;// 读取缓冲流
- BufferedOutputStream bos = null;// 写入缓冲流
- try {
- bis = new BufferedInputStream(new FileInputStream("F:\\A\\1.mp3"));// 要复制的MP3文件
- bos = new BufferedOutputStream(new FileOutputStream("F:\\B\\1.mp3"));// 复制到的目的地
- byte[] b = new byte[1024];
- int len = 0;
- while ((len = bis.read(b)) != -1) {// 读取
- bos.write(b, 0, len);// 写入
- }
- System.out.println("复制成功");
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (bis != null) {
- try {
- bis.close();// 关闭读取缓冲对象流
- } catch (IOException e) {
- e.printStackTrace();
- }
- if (bos != null) {
- try {
- bos.close();// 关闭写入缓冲对象流
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
- }
- }
- 结果:
- 复制成功
2. 模拟读取缓冲区
- import java.io.IOException;
- import java.io.InputStream;
- public class MyBufferedInputStream {
- privateInputStream in = null;
- private intcount = 0;// 计数器
- private intpos = 0;// 指针
- private byte[]bu = new byte[1024];// 封装的字节数组
- publicMyBufferedInputStream(InputStream in) {
- this.in =in;
- }
- public intMyRead() throws IOException {
- if (count== 0) {// 说明此时缓冲区中没有数据,可能是缓冲区中还没有开始读取,或者是缓冲区中数据读取完毕
- count= in.read(bu);// 向缓冲区中读取数据
- if(count < 0) {
- return-1;// 这里返回的是int类型的-1
- }
- pos=0;//每次把指针都初始化
- byteb = bu[pos];
- count--;//计数器减一
- pos++;//指针加一
- returnb & 0xff;// 这里b是byte类型,自动提升为整形,但是前面补充的是全是1,为了防止当读取道德byte数据为11111111时,&上0xff,那么使前面的是0,那么这样额可以是原数据不变,又能避免字节数据是-1的情况
- } elseif(count>0){
- byteb = bu[pos];
- count--;//计数器减一
- pos++;//指针加一
- returnb & 0xff;// 这里b是byte类型,自动提升为整形,但是前面补充的是全是1,为了防止当读取道德byte数据为11111111时,&上0xff,那么使前面的是0,那么这样额可以是原数据不变,又能避免字节数据是-1的情况
- }
- return-1;
- }
- public voidmyClose() throws IOException {
- in.close();
- }
- }
- import java.io.BufferedInputStream;
- import java.io.BufferedOutputStream;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
- /*
- *测试类,也是复制MP3*/
- public class BufferedStreamDemo {
- public static void main(String[] args) {
- MyBufferedInputStream bis = null;// 读取缓冲流
- BufferedOutputStream bos = null;// 写入缓冲流
- try {
- bis = new MyBufferedInputStream(new FileInputStream("F:\\A\\1.mp3"));// 要复制的MP3文件
- bos = new BufferedOutputStream(new FileOutputStream("F:\\B\\1.mp3"));// 复制到的目的地
- // byte[] b = new byte[1024];
- int r = 0;
- while ((r = bis.MyRead()) != -1) {// 读取
- bos.write(r);// 写入
- }
- System.out.println("复制成功");
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (bis != null) {
- try {
- bis.myClose();// 关闭读取缓冲对象流
- } catch (IOException e) {
- e.printStackTrace();
- }
- if (bos != null) {
- try {
- bos.close();// 关闭写入缓冲对象流
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
- }
- }
- 结果:复制成功
注意点:在MyRead()方法中return 返回的必须写b&0xff,因为这样byte类型的提升为整形后,可以保证原数据保持不变,把原来的数据前面相当于添加的0.
例如:
byte : 11111111 这是-1
自动提升为整形后的数据是
1111111111111111 11111111 11111111 此时这是-1
那么当byte类型的数据是八个1的时候,那么直接返回b,那么提升为整形后是四个八个1,那么还是-1,所以程序直接结束,读取完毕,解决方法是,要是在前面补充的是全是0的话,那么原数据不变没这样也避免的读取-1的情况。
1111111111111111 11111111 11111111
& 00000000 00000000 00000000 11111111 这是255,
-----------------------------------------------------------------
0000000000000000 00000000 11111111
所以这样结果就是我们想要的数据,既避免了读取byte是11111111的缺点,同时还保证了原数据不变。
Read方法是byte类型的提升,从1个字节提升为整形为四个字节。Write方法是把4个字节变成了1个字节,值去最后的一个字节。所以复制后的文件的大小和原来的大小一下,而不是其4倍的大小。
6. 键盘读取
- import java.io.IOException;
- import java.io.InputStream;
- public class ClassDemo {
- public static void main(String[] args) throws IOException {
- /*
- * InputStream in“标准”输入流:读取的设备是键盘 PrintStream out“标准”输出流。输出到控制台
- */
- /*
- * 我们可以循环输入,当输入为over时候,结束输入
- */
- InputStream in = System.in;
- StringBuilder bu= new StringBuilder();
- while (true) {
- int ch = in.read();
- if (ch == '\r')
- continue;
- if (ch == '\n') {
- String s = bu.toString();
- if ("over".equals(s))// 如果输入的是over,那么结束输入
- break;
- System.out.println("输入的内容是:" + s);
- bu.delete(0,bu.length());
- } else
- bu.append((char) ch);
- }
- }
- }
- 结果:
- aa
- 输入的内容是:aa
- bb
- 输入的内容是:bb
- cc
- 输入的内容是:cc
- over
--------------------ASP.Net+Android+IOS开发、.Net培训、期待与您交流!
--------------------
1.字节流转换成字符流(InputStreamReader)
字节流:InputStream -------读取
字符流:Reader ------读取
在字节流读取的时候用的是一个一个字节的读取方式或者是字节数组的读取方式,
在字符流中读取的时候,除了有一个一个字符的读取方式和数组 的读取 方式外 ,在缓冲技术里面有一行一行的读取,这个方法在读取的时候很好用也很方面,那么我们就可以把字节流的转换成字符流,然后利用缓冲对象来使用读取一行的方法。
字符流要向获得从键盘录入的信息,那么必须使用字节流,然后把字节流准换成字符流
步骤:
1.准备好一个字节流(InputStream in)
2.利用InputStreamReader(isr)把字节流对象作为其构造函数的参数,new InputStreamReader(in)
3.然后使用缓冲技术(BufferedReader对象封装转换流)newBufferedReader(isr),然后就可以使用读取行的方法了。
4.最后要关闭流
举例:读取键盘的录入的数据
InputStream in = System.in;
InputStreamReader isr = new InputStreamReader(in);
BufferedReader br = newBufferedReader(isr);
然后我们就可以使用br对象纪念性读取键盘录入的数据了。
我们也可以把这三句转换成一句。
BufferedWriter bw = new BufferedWriter(newOutputStreamWriter(System.out));
2. 字节输入流转换成字符输入流(OutputStreamWriter)
字符流:Writer -----写入流
字节流:OutputStream ---写入流
OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset
将要写入流中的字符编码成字节。
步骤:
1.准备一个字符流
2.利用OutputStreamWriter(OutputStream out)把其转换成字节流,
3.可以利用其缓冲对象对其进行封装。然后做相应的操作。
4.最后关闭流
举例:
OutputStream out = System.out;
OutputStreamWriter osw = new OutputStreamWriter(out);
BufferedWriter bw = new BufferedWriter(osw);
也可以将这三句合成一句话
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
3. 流操作(转换流练习)
1. 源:键盘录入 (输出)目的:控制台
- import java.io.BufferedReader;
- import java.io.BufferedWriter;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.io.OutputStream;
- import java.io.OutputStreamWriter;
- public class ZhuanhuanDemo {
- public static void main(String[] args) throws IOException {
- /*InputStream in = System.in;//原始键盘
- InputStreamReader isr = new InputStreamReader(in);
- BufferedReader br = new BufferedReader(isr);//封装类字符流*/
- BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
- /*OutputStream out = System.out;//输出的目的是控制台
- OutputStreamWriter osw = new OutputStreamWriter(out);//将字符流转换成字节流
- BufferedWriter bw = new BufferedWriter(osw);*/
- BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
- String line = null;
- while ((line = br.readLine()) != null) {
- if ("over".equals(line))
- break;
- bw.write("输入的内容是:" + line);
- bw.newLine();
- bw.flush();
- }
- }
- }结果:
- 张三
- 输入的内容是:张三
- 李四
- 输入的内容是:李四
- abc
- 输入的内容是:abc
- over
2. 源:键盘 输出目的:文件
就是将键盘录入的数据写到了文件中
- import java.io.BufferedReader;
- import java.io.BufferedWriter;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.OutputStreamWriter;
- public class ZhuanhuanDemo {
- public static void main(String[] args) throws IOException {
- BufferedReader br = new BufferedReader(new InputStreamReader(System.in));// 源:键盘
- BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
- new FileOutputStream("F:\\demo.txt")));// 目的:文件
- String line = null;
- while ((line = br.readLine()) != null) {
- if ("over".equals(line))
- break;
- bw.write(line);//写入
- bw.newLine();
- bw.flush();
- }
- bw.close();// 关闭流
- br.close();// 关闭流
- }
- }
3. 源:文件 目的:控制台
将文件的内容打印在控制台上
- import java.io.BufferedReader;
- import java.io.BufferedWriter;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.OutputStreamWriter;
- public class ZhuanhuanDemo {
- public static void main(String[] args) throws IOException {
- BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("F:\\demo.txt")));// 源:文本
- BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));// 目的:控制台
- String line = null;
- while ((line = br.readLine()) != null) {
- bw.write(line);//输出
- bw.newLine();
- bw.flush();
- }
- bw.close();// 关闭流
- br.close();// 关闭流
- }
- }
- 结果:
- 张三
- 李四
- 王五
4. 流操作规律
1.明确源和目的
源:输入流:InputStream Reader
目的:输出流:OutputStream Writer
2.操作的数据是否是纯文本
是:字符流
不是:字节流
3.当体系明确后,在明确要使用那个具体的对象。
通过设备来进行区分:
源设备:内存,硬盘,键盘
目的内存:内存,硬盘,控制台
需求:
1.将一个文件数据存储到另一个文件中,复制文件
源:文件 使用读取流: InputStream Reader
是否是文本文件: 是:用Reader
明确对象:明确设备:硬盘中的文件FileReader对象
提高效率。利用缓冲区。BufferedReader。
FileReader fr=new FileReader(“a.txt”);
BufferedReader br=new BufferedReader(fr);
目的 :文件:OutputStream Writer
是否是纯文本:Writer
设备:硬盘中的文件
提高效率。利用缓冲区。BufferedWriter。
对象:FileWriter
FileWriter fw=new FileWriter();
BufferedWriter bw=new BufferedWriter(fw);
2.需求
将键盘录入的数据保存到另一个文件中。
源:InputStream Reader
纯文本:Reader
设备:键盘 对象 System.in
InputStreamReader idr=new InputStreamReader(System.in);
提高效率用BufferedReader
BufferedReader bufr=new BufferedReader(idr);
目的:OurStream ,Writer
纯文本:Writer
设备:硬件的文件
FileWrite fw=new FileWriter(“文件”);
BufferefWriter bufW=new BufferefWriter(fw);
要指定编码方式,必须使用转换流,OutputStreamWriter扩展:指定编码方式
OutputStreamWriter(OutputStream out,String charsetName)
OutputStreamWriter osw=new OutputStreamWriter(newFileOutputStream(“F:\\demo.txt”,”utf-8”))这制订了编码方式;
在转换流构造方法中指定。
当需要指定编码方式的时候,那么就需要此转换流OutputStreamWriter。
当需要指定编码方式的时候那么就需要转换流来操作。
当需要读取别的编码方式的文件的时候,也得需要使用转换流
字节流不用刷新缓冲区,字符流要刷新缓冲区
- public class ZhuanhuanDemo {
- public static void main(String[] args) throws IOException {
- BufferedReader br = new BufferedReader(new InputStreamReader(System.in));// 源:键盘
- /*默认的编码是jbk。*/
- BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
- new FileOutputStream("F:\\demo1.txt"),"utf-8"));// 目的:控制台
- String line = null;
- while ((line = br.readLine()) != null) {
- if ("over".equals(line))
- break;
- bw.write(line);// 输出
- bw.newLine();
- bw.flush();
- }
- bw.close();// 关闭流
- br.close();// 关闭流
- }
当你输入两个汉字就结束的话,那么文件大小是8个字节,要是默认的话就是6个字节,指定GBK的话,那也是6个字节,所以可以确认默认的是GBK编码。
- import java.io.BufferedReader;
- import java.io.BufferedWriter;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.OutputStreamWriter;
- public class ZhuanhuanDemo {
- public static void main(String[] args) throws IOException {
- BufferedReader br = new BufferedReader(new InputStreamReader(System.in));// 源:键盘
- /*默认的编码是jbk。*/
- BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
- new FileOutputStream("F:\\demo1.txt"),"utf-8"));// 目的:控制台
- String line = null;
- while ((line = br.readLine()) != null) {
- if ("over".equals(line))
- break;
- bw.write(line);// 输出
- bw.newLine();
- bw.flush();
- }
- bw.close();// 关闭流
- br.close();// 关闭流
- }
- }
5. 改变标准输入输出设备
- public static void main(String[] args) throws IOException {
- /*
- * static void setIn(InputStream in)改变输入设备
- * static void setOut(PrintStream out)改变输出的设备目的
- * */
- System.setIn(new FileInputStream("F:\\demo.txt"));//把输入设备定义到了一个文件流上,就是源:文件
- System.setOut(new PrintStream("F:\\demo1.txt"));//把输入设备定义到一个文件上,就是把内容输入到一个文件中
- BufferedReader br = new BufferedReader(new InputStreamReader(System.in));// 源:键盘
- /*默认的编码是jbk。*/
- BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
- new FileOutputStream("F:\\demo1.txt"),"utf-8"));// 目的:控制台
- String line = null;
- while ((line = br.readLine()) != null) {
- if ("over".equals(line))
- break;
- bw.write(line);// 输出
- bw.newLine();
- bw.flush();
- }
- bw.close();// 关闭流
- br.close();// 关闭流
- }
6. 异常日志文件
我们可以将程序中出现的异常保存到一个文件中,那么我就可以方便我们查看,在开发中也是把异常打印到文件中,不可能让用户看到异常。我们也可以下载logf4工具,这是专门处理异常的工具。
下面我们写一个字节的异常日志文件。
void |
printStackTrace(PrintStream s) 将此 throwable 及其追踪输出到指定的输出流。 |
- public class ExceptionDemo {
- public static void main(String[] args) {
- try {
- int a = 4 / 0;
- } catch (Exception e) {
- try {
- PrintStream ps = new PrintStream("F:\\exception.log");
- SimpleDateFormat sdf = new SimpleDateFormat(
- "yyyy-MM-DDHH:mm:ss");
- String s = sdf.format(new Date());
- ps.println(s);//将日期传进入
- e.printStackTrace(ps);// 将流传入,指定目的
- } catch (FileNotFoundException e1) {
- System.out.println("日志文件创建失败");
- }
- }
- }
- }
- 结果:
7.系统属性信息
系统日志
将系统的实现存到文件中
- import java.io.FileNotFoundException;
- import java.io.PrintStream;
- import java.util.Properties;
- public class PropertiesDemo {
- public static void main(String[] args) {
- /*list(PrintStream out)将属性列表输出到指定的输出流。*/
- Properties p=new Properties();
- p=System.getProperties();
- try {
- p.list(new PrintStream("F:\\SystemInfo.txt"));
- } catch (FileNotFoundException e) {
- System.out.println("创建文件失败");
- }
- }
- }