------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
黑马程序员 java 基础 毕向东 面向对象 IO流操作
1 Java io流操作概述:字节流 字符流 及其基类(后缀名是父类 前缀名是功能)
package day19IO; import java.io.FileWriter; import java.io.IOException; public class FileWriterDemo { /* * IO体系 * * 字符流 字节流 * * 字节流的两个基类: * InputStream OutputStream * * 字符流的两基类 * Reader Writer * 字符流的特点: * 既然io流是用于操作数据的 * 那么数据的常见体现形式是:文件 * * 需求:在硬盘上创建文件,并写入 * 找到一个专门用于操作文件的writer子类对象 * FileWriter * 后缀名是父类 * 前缀名是功能 * */ public static void main(String[] args) throws IOException { //创建一个fileWriter对象,该对象一被创建就必须明确操作的文件 //该文件会被创建到指定目录, //如果由同名文件,被覆盖 //就是在明确数据的存放地址 FileWriter fw=new FileWriter("demo.txt"); char ch[]={'A','你','1'}; String s="专注技术,精益求精"; //调用write方法,将数据写入内存缓冲中 fw.write(ch); fw.write(3); fw.flush(); fw.write("cui崔国强"); fw.write(ch, 1, 1); fw.write(s,2,1); /*刷新该流的缓冲。如果该流已保存缓冲区中各种 write() 方法的所有字符, * 则立即将它们写入预期目标。然后,如果该目标是另一个字符或字节流, * 则将其刷新。 * 因此,一次 flush() 调用将 * 刷新 Writer 和 OutputStream 链中的所有缓冲区。 */ fw.flush(); fw.close();//关闭流资源,关闭之前刷新缓冲到目的地;关闭此流,但要先刷新它。 // fw.write("cui崔国强"); } }
2 Java io操作异常处理方式
package day19IO; import java.io.FileWriter; import java.io.IOException; import static java.lang.System.*; public class FileWriterDemo2 { /* * IO异常的处理方式*/ public static void main(String[] args) { FileWriter fw = null; try { // fw = new FileWriter("o:\\demo.txt"); fw = new FileWriter("demo.txt"); fw.write("abcdefg") ; fw.flush(); } catch (IOException e) { e.printStackTrace(); out.println(e); }finally{ try { if(fw!=null) fw.close(); } catch (IOException e) { e.printStackTrace(); out.println("close exception"); } } } }
3 Java 文件的续写 FileWriter(String fileName, boolean append)
package day19IO; import static java.lang.System.out; import java.io.FileWriter; import java.io.IOException; public class FileWriterDemo3 { /*文件的续写 * 对已有文件的续写 * windows 下的换行 * windows:回车 \r\n * linux;回车 \n * * */ private static boolean WRITE_IN_END=true; public static void main(String[] args) { FileWriter fw = null; try { /*public FileWriter(String fileName, boolean append) throws IOException * 根据给定的文件名以及指示是否附加写入数据的 * boolean 值来构造 FileWriter 对象。 * 参数: * fileName - 一个字符串,表示与系统有关的文件名。 * append - 一个 boolean 值,如果为 true, * 则将数据写入文件末尾处,而不是写入文件开始处。 */ fw = new FileWriter("demo.txt",WRITE_IN_END); fw.write("好abcdefg\r\n崔") ; fw.write("\r\nabcdefg") ; fw.flush(); } catch (IOException e) { e.printStackTrace(); out.println(e); }finally{ try { if(fw!=null) fw.close(); } catch (IOException e) { e.printStackTrace(); out.println("close exception"); } } } }
4 FileReader 读取文件
package day19IO; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import static java.lang.System.out; /* * 创建一个文件读取流对象 ,和指定名称 的文件相关联 * 要保证该文件已经存在,如果不存在,发送异常 FileNotFoundException*/ public class FileReaderDemo { /** * @param args */ public static void main(String[] args) { FileReader fr = null; try { fr=new FileReader("demo.txt"); int ch; while((ch=fr.read())!=-1){ out.println("ch:"+(char)(ch)); } /* while(true){ ch=fr.read(); if(ch==-1) break; out.println("ch:"+(char)(ch)); } */ // ch = fr.read();//读取单个字符。在字符可用 /*返回: * 作为整数读取的字符,范围在 0 到 65535 之间 (0x00-0xffff), * 如果已到达流的末尾,则返回 -1*/ } catch (FileNotFoundException e) { e.printStackTrace(); }catch (IOException e) { e.printStackTrace(); } } }
5 通过字符数组读取数据 read(char [])
package day19IO; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import static java.lang.System.out; /*通过字符数组进行读取 * */ public class FileReaderDemo2 { /** * @param args */ public static void main(String[] args) { FileReader fr = null; char[] dstCh = new char[1024]; try { fr=new FileReader("demo.txt"); int length; while((length=fr.read(dstCh))!=-1){ out.println("desCh:"+new String(dstCh,0,length)); } // length=fr.read(dstCh); /* 读取的字符数,如果已到达流的末尾,则返回 -1 */ } catch (FileNotFoundException e) { e.printStackTrace(); }catch (IOException e) { e.printStackTrace(); } // out.println("desCh:"+new String(dstCh)); } }
6 读取文件打印在控制台上
package day19IO; import java.io.*; import static java.lang.System.*; public class FileReaderTest { /*读取一个java文件并打印在控制台上 * */ public static void main(String[] args) { FileReader fr = null; char dstCh[]=new char[1024]; int rl; try { fr=new FileReader("FileReaderDemo2.java"); while((rl=fr.read(dstCh))!=-1){ out.println("长度:"+rl+":"+new String(dstCh,0,rl)); } } catch (FileNotFoundException e) { e.printStackTrace(); }catch (IOException e) { e.printStackTrace(); }finally{ if(fr!=null){ try { fr.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
7 拷贝文件 FileReader ->FileWriter
package day19IO; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import static java.lang.System.*; /* * 将c盘一个文件复制的d盘 * 其实就是讲c盘下的文件数据存储到d盘的一个文件中 * 步骤: * 1:在d盘创建文件,用于存储c盘文件中的数据 * 2:定义读取流和c盘的文件关联 * 3:通过不断的读写完成数据存储 * 4:关闭资源*/ public class CopyText { public static void main(String[] args) { FileReader fr = null;//创建源文件 FileWriter fw = null;//创建目的地 String srcPathName="FileReaderDemo2.java"; String dstPathName="Copy_FileReaderDemo2.java"; char [] tempCh=new char[1024]; int rl; int ch; try { fr=new FileReader(srcPathName); fw=new FileWriter(dstPathName); /* while((ch=fr.read())!=-1){ fw.write(ch); } */ while((rl=fr.read(tempCh))!=-1){ out.println("rl:"+rl+"mes:"+new String(tempCh,0,rl)); fw.write(tempCh); fw.flush(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally{ try { if(fw!=null) fw.close(); } catch (IOException e1) { e1.printStackTrace(); } try { if(fr!=null) fr.close(); } catch (IOException e1) { e1.printStackTrace(); } } } }
8 BufferedReader 一次读取一行 BufferedReader br=new BufferedReader(new FileReader(String path));br.readLine()
package day19IO; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; /* * BufferReader 缓冲流提供了一次读取一行的方法readLine() * 读到末尾 返回null*/ public class BufferReaderDemo { /*从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取*/ public static void main(String[] args) { FileReader fr = null;//创建一个读取流对象和文件相关联。 BufferedReader br = null;//为了提高效率。加入缓冲技术。 //将字符读取流对象作为参数传递给缓冲对象的构造函数 String scrPath="FileReaderDemo2.java"; String lineStr; try { fr=new FileReader(scrPath); br=new BufferedReader(fr); /*String readLine() * 返回: * 包含该行内容的字符串,不包含任何行终止符, * 如果已到达流末尾,则返回 null */ while((lineStr=br.readLine())!=null){ System.out.println("line:"+lineStr); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally{ if(br!=null){ try { br.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
9BufferedWriter 提高写入效率 与平台无关的换行BufferedWriter bw=new BufferedWriter (new FileWriter(String)) flush(); 才可以写入
package day19IO; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; public class BufferWriterDemo { /*缓冲区的出现时为了提高流 的操作效率而出现的 * 所以在出现缓冲流之前,必须存储 流对象 * 该缓冲流方法提供了跨平台的换行方法 * * * 将文本写入字符输出流,缓冲各个字符, * 从而提供单个字符、数组和字符串的高效写入。*/ public static void main(String[] args) { FileWriter fw = null;//创建字符写入流对象 BufferedWriter bw = null;//为了提高字符写入流的效率。加入了缓冲技术 String dstPath="buffer.txt"; try { fw=new FileWriter(dstPath); // //只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可。 bw=new BufferedWriter(fw); bw.write("abcde"); bw.newLine();//换行 bw.write("abcde"); //只要用缓冲区,就flush bw.flush(); } catch (IOException e) { e.printStackTrace(); }finally{ if(bw!=null){ try { bw.close();//其实关闭缓冲区,就是在关闭缓冲区中的流对象 } catch (IOException e) { e.printStackTrace(); } } //以下可以不写 // if(fw!=null){ // try { // fw.close();// 关闭此流,但要先刷新它。 // } catch (IOException e) { // e.printStackTrace(); // } // } } } }
10 通过缓冲实现 文本复制
package day19IO; import static java.lang.System.out; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; /* *通过缓冲流实现复制文件 **/ public class CopyTextByBuffer { public static void main(String[] args) { FileReader fr = null;//创建源文件 FileWriter fw = null;//创建目的地 BufferedReader br = null; BufferedWriter bw = null; String srcPathName="FileReaderDemo2.java"; String dstPathName="Copy_FileReaderDemo2_by_buffer.java"; String lintStr; try { fr=new FileReader(srcPathName); fw=new FileWriter(dstPathName); br=new BufferedReader(fr); bw=new BufferedWriter(fw); while((lintStr=br.readLine())!=null){ /*String readLine() * 返回: * 包含该行内容的字符串,不包含任何行终止符, * 如果已到达流末尾,则返回 null */ bw.write(lintStr); bw.newLine(); out.println("lint:"+lintStr); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally{ try { if(bw!=null) bw.close(); } catch (IOException e1) { e1.printStackTrace(); }try { if(br!=null) br.close(); } catch (IOException e1) { e1.printStackTrace(); } } } }
11 装饰类设计模式,使原有类功能增强,且不会使体系结构臃肿
package day19IO; public class 装饰设计模式 { /*装饰设计模式 * 当对已有对象进行功能增强时 * 可以定义类,将已有对象传入,基于 * 已有功能,并加强功能 * 那么自定义的类就称为 * 装饰类 * * 装饰类通常通过构造方法接受被装饰的对象 * 并基于被装饰的功能增强功能 * */ public static void main(String[] args) { SuperPerson sp=new SuperPerson(new Person()); sp.chifan(); } } class Person{ public void chifan() { System.out.println("吃饭"); } } class SuperPerson{ private Person p; public SuperPerson(Person p) { this.p=p; } public void chifan() { System.out.println("开胃酒"); p.chifan(); } }
12 装饰 与 继承 特点 和区别
package day19IO; public class 装饰与继承 { /*设计类的前世今生 * 继承: * MyReader 专门用于读取数据的类 * 继承体系:--------------------------------------------- * |--MyTextReader * |--MyBufferedTextReader * |--MyMediaReader * |--MyBufferedMediaReader * |--MyDateReader * |--MyBufferedDateReader * 这样的类结构体系庞大,臃肿 * class MyBufferReader{ * public MyBufferReader(MyTextReader m){ * } * public MyBufferReader(MyMediaReader m){ * } * public MyBufferReader(MyDateReader m){ * } * } * * 上面的类扩展型差 * 通过多态特性 * 装饰体系:--------------------------------------------- * MyReader 专门用于读取数据的类 * |--MyTextReader * |--MyMediaReader * |--MyDateReader * |--MyBufferReader <--------------------- * class MyBufferReader extend MyReader{ * private MyReader m; * public MyBufferReader(MyReader m){ * } * * } * * 装饰模式比继承要灵活。避免了继承体系臃肿。 * 而且降低了类于类之间的关系。 * * 装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能。 * 所以装饰类和被装饰类通常是都属于一个体系中的。 * 以前是通过继承将每一个子类都具备缓冲功能。 那么继承体系会复杂,并不利于扩展 现在优化思想。单独描述一下缓冲内容。 将需要被缓冲的对象。传递进来。也就是,谁需要被缓冲,谁就作为参数传递给缓冲区。 这样继承体系就变得很简单。优化了体系结构。 java.lang.Object |-- java.io.Writer |-- java.io.BufferedWriter |-- java.io.OutputStreamWriter |-- java.io.FileWriter java.io.Reader |-- java.io.BufferedReader |-- java.io.InputStreamReader |-- java.io.FileReader * */ public static void main(String[] args) { } }
13 自定义实现MyBufferedReader
package day19IO; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.Reader; /* * 明白了BufferedReader类中特有方法readLine的原理后, 可以自定义一个类中包含一个功能和readLine一致的方法。 来模拟一下BufferedReader*/ public class MyBufferReaderDemo { public static void main(String[] args) { FileReader fr = null;//创建一个读取流对象和文件相关联。 MyBufferReader mbf = null; try { fr=new FileReader("demo.txt"); mbf=new MyBufferReader(fr); String lineStr; while((lineStr=mbf.readLine())!=null){ System.out.println("-"+lineStr); } } catch (FileNotFoundException e) { e.printStackTrace(); }finally{ try { if(mbf!=null) mbf.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } class MyBufferReader extends Reader{ // private FileReader fr; private Reader fr; // public MyBufferReader(FileReader fr) { // this.fr=fr; // } public MyBufferReader(Reader fr) { this.fr=fr; } public String readLine() { StringBuilder sb; sb=new StringBuilder(); int ch; try { while((ch=fr.read())!=-1){ if(ch=='\r') continue; if(ch=='\n') return sb.toString(); sb.append((char)ch); } } catch (IOException e) { e.printStackTrace(); } return sb.length()==0?null:sb.toString(); } //覆盖Reader类中的抽象方法 public void close() throws IOException { if(fr!=null) fr.close(); } public int read(char[] cbuf, int off, int len) throws IOException { return fr.read(cbuf, off, len); } }
14 LineNumberReader Demo 示例
package day19IO; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.LineNumberReader; public class LineNumberReaderDemo { /**/ public static void main(String[] args) { FileReader fr; LineNumberReader lnr = null; try { fr=new FileReader("FileReaderDemo2.java"); lnr=new LineNumberReader(fr); String lineStr; int lineNum; lnr.setLineNumber(31); while((lineStr=lnr.readLine())!=null){ lineNum=lnr.getLineNumber(); System.out.println(lineNum+":line:"+lineStr); } lineStr=lnr.readLine(); System.out.println("set 3line:"+lineStr); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally{ if(lnr!=null){ try { lnr.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
15自定义MyLineNumberReader
package day19IO; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.Reader; public class MyLineNumberReaderDemo { /* * 模拟带行号的缓冲对象 * */ public static void main(String[] args) { MyLineNumberReader mlnr = null; FileReader fr; try { fr=new FileReader("FileReaderDemo2.java"); mlnr=new MyLineNumberReader(fr); String lineStr; int lineNum; mlnr.setLineNumber(100000); while((lineStr=mlnr.readLine())!=null){ lineNum=mlnr.getLineNumber(); System.out.println(lineNum+":line:"+lineStr); } } catch (FileNotFoundException e) { e.printStackTrace(); }finally{ try { mlnr.close(); } catch (IOException e) { e.printStackTrace(); } } } } class MyLineNumberReader extends MyBufferReader{ private int lineNumber; public MyLineNumberReader(Reader r) { super(r); } public String readLine(){ lineNumber++; return super.readLine(); } public void setLineNumber(int lineNumber) { this.lineNumber=lineNumber; } public int getLineNumber() { return this.lineNumber; } } //class MyLineNumberReader{ // private Reader r; // private int lineNumber; // public MyLineNumberReader(Reader r) { // this.r=r; // } // public String readLine(){ // StringBuilder sb=new StringBuilder(); // lineNumber++; // int ch; // try { // while((ch=r.read())!=-1){ // if(ch=='\r') // continue; // if(ch=='\n') // return sb.toString(); // sb.append((char)ch); // } // } catch (IOException e) { // e.printStackTrace(); // } // return sb.length()==0?null:sb.toString(); // } // public void setLineNumber(int lineNumber) { // this.lineNumber=lineNumber; // } // public int getLineNumber() { // return this.lineNumber; // } // public void close(){ // try { // r.close(); // } catch (IOException e) { // e.printStackTrace(); // } // } //}
16 Java io 字节流 InputStream 演示
package day19IO; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class FileStreamDemo{ /* * 字符流 * FileReader * FileWriter * * BufferReader * BufferWriter * * 字节流: * InputStream * OutputStream * 需求: * 想操作图片数据 * 用字节流 * */ public static void main(String[] args) { // writeFile(); // readFile(); // readFile_2(); readFile_available(); } public static void readFile_available() { /* 返回: 可以不受阻塞地从此输入流中读取(或跳过)的估计剩余字节数。*/ FileInputStream fis = null; byte [] buf; int length; int leftNum; try { fis=new FileInputStream("fos.txt"); leftNum=fis.available(); /*返回: * 可以不受阻塞地从此输入流中读取(或跳过) * 的估计剩余字节数。*/ buf=new byte[leftNum];//定义刚刚好的缓冲区,无需循环 fis.read(buf); System.out.println("leftNum:"+leftNum); System.out.println("data:"+new String(buf)); } catch (IOException e) { e.printStackTrace(); }finally{ try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } public static void readFile_2() { FileInputStream fis = null; byte [] buf=new byte[1024];//这个缓冲大小是最合适的 int length; try { fis=new FileInputStream("fos.txt"); while((length=fis.read(buf))!=-1){ System.out.println("data:"+new String(buf,0,length)); } } catch (IOException e) { e.printStackTrace(); }finally{ try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } public static void readFile() { FileInputStream fis = null; int data; try { fis=new FileInputStream("fos.txt"); while((data=fis.read())!=-1){ System.out.println("data:"+(char)data); } } catch (IOException e) { e.printStackTrace(); }finally{ try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } public static void writeFile() { FileOutputStream fos = null; try { fos=new FileOutputStream("fos.txt"); fos.write("abac12A你好".getBytes()); /*字符流依赖字节流,暂时存储起来,查表 * 此时不需要刷新 * 是对字节的最小单位操作 * */ } catch (IOException e) { e.printStackTrace(); }finally{ try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } }
17 操作非文本文件 使用字节流: 演示 拷贝图片
package day19IO; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class CopyPic { /* * 复制图 * 思路: * 1:用字节流读取 * 2:用字节写入流创建一个图片。用于存取到的图片数据 * 3:通过循环读写,完成存储 * 4:关闭资源 * */ public static void main(String[] args) { FileOutputStream fos=null; FileInputStream fis=null; try { fis=new FileInputStream("F:\\fis.jpg"); fos=new FileOutputStream("F:\\out.jpg"); byte[] data=new byte[1024]; int len; int i=0; while((len=fis.read(data))!=-1){ fos.write(data,0,data.length); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally{ if(fos!=null) try { fos.close(); } catch (IOException e) { e.printStackTrace(); } if(fis!=null) try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } }
18 操作非文本文件 使用字节流: 演示 拷贝mp3 (自定义BufferedInputStream 就该问题 效率更高)
---------------------------自定义BufferedInputStream---------------------------------
package day19IO; import java.io.IOException; import java.io.InputStream; public class MyBufferInputStreamDemo { /**/ public static void main(String[] args) { } } class MyBufferInputStream{ private InputStream is; private byte[] buffer=new byte[1024]; private int pos=0,count=0; public MyBufferInputStream(InputStream is) { this.is=is; } /* * 1111-1111 * 提升为int类型 * 还是-1; * 是-1的原因是在8个1前面补1导致的 * 那怎么补0呢? * 即可以保持原字节数据不变,又可以避免-1的出现 * 怎么补0呢? * 1111-1111 1111-1111 1111-1111 1111-1111 =255 或者 &0xff * 0000-0000 0000-0000 0000-0000 1111-1111 * ------------------------------------------ * 0000-0000 0000-0000 0000-0000 1111-1111 * */ public int read() throws IOException{ if(count==0){ count=is.read(buffer); if(count<0){ return -1; } pos=0; count--; return buffer[pos]&255; }else{ if(count>0){ byte b=buffer[++pos]; count--; pos++; return b&0xff; } } return -1; } public void myClose() throws IOException { is.close(); } }
拷贝mp3 文件
package day19IO; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class CopyMp3 { /*演示mp3 的复制 * 通过缓冲区 * BufferOutputStream * BufferInputStream * */ public static void main(String[] args) { long start=System.currentTimeMillis(); // copy1(); copy_by_MyBufferInputStream(); long end=System.currentTimeMillis(); System.out.println("start:"+(end-start)+":end:"); } public static void copy1() { try { BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("F:\\2.mp3")); BufferedInputStream bis=new BufferedInputStream(new FileInputStream("F:\\1.mp3")); int data; while((data=bis.read())!=-1){ bos.write(data); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public static void copy_by_MyBufferInputStream() { //一开始,惊呆了,被这读写速度 虽然后来发现有错误,但最终的效率还是提高了些许,感觉很爽 try { BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("F:\\2.mp3")); BufferedInputStream bis=new BufferedInputStream(new FileInputStream("F:\\1.mp3")); // MyBufferInputStream bis=new MyBufferInputStream(new FileInputStream("F:\\1.mp3")); int data; while((data=bis.read())!=-1){ /* * 将指定的字节写入此输出流。 * write 的常规协定是: * 向输出流写入一个字节。 * 要写入的字节是参数 b 的八个低位。 * b 的 24 个高位将被忽略。 * */ //为什么read方法返回的是int类型,而不是byte类型呢? //避免了 原有数据中恰好是 -1 的情形 //提升后byte类型的数据 1111-1111 (-1) //被提升为int型 //本来返回的是0000-0000 0000-0000 0000-0000 1111-1111 //是原有数据的5倍,可实际结果并没有变大 //那是因为write 内含强转操作 去除了前面的 0 bos.write(data);// // System.out.println(data); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
19从键盘录入
package day19IO; import java.io.IOException; import java.io.InputStream; public class ReadFromKeyboard { /* * 从键盘录入 * System.out 标准输出 * System.in 标准输入 键盘 * * 通过键盘录入 * 录入一行,打印一行 * 录入的为over时停止*/ public static void main(String[] args) { InputStream in =System.in; String stopFlag="over"; int data = 0; StringBuilder sb=new StringBuilder(); try { while((data=in.read())!=-1){ if(data=='\r') continue; if(data=='\n'){ if(stopFlag.equals(sb.toString())) break; System.out.println(sb.toString()); sb.delete(0, sb.length()); }else sb.append((char)data); } } catch (IOException e) { e.printStackTrace(); } // System.out.println("data"+data); } }
20 字节流向字符流转换 InputStreamReader -----字符流向字节流转换 OutputStreamWriter
package day19IO; 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 TransStreamDemo { /* * 字符流 * FileReader * FileWriter * * BufferReader * BufferWriter * * 字节流: * InputStream * OutputStream * * BufferedInputStream * BufferedOutputStream * 通过刚才的键盘录入一行并打印 * 发现其实读取一行 的实现原理 * * 那么能否使用readLine 来完成录入一一行呢? * * readLine 方法是字符流 BufferedReader类的方法 * 而键盘录入的Read方法是字节流InputStream的方法 * * 能否将自己流转成字符流呢? * 在使用readLine方法 * public class InputStreamReaderextends ReaderInputStreamReader * 是字节流通向字符流的桥梁: * 它使用指定的 charset 读取字节并将其解码为字符。 * 它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。 * 每次调用 InputStreamReader 中的一个 read() * 方法都会导致从底层输入流读取一个或多个字节。 * 要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节, * 使其超过满足当前读取操作所需的字节。 * */ public static void main(String[] args) { // //获取键盘录入对象 // InputStream in=System.in; // OutputStream out =System.out; // // //将字节流转成字符流.InputStreamReader // InputStreamReader isr=new InputStreamReader(in); // OutputStreamWriter osw=new OutputStreamWriter(out); // // //为了提高效率,将字符串进行缓冲区技术高效操作,使用BufferReader // BufferedReader br=new BufferedReader(isr); // BufferedWriter bw=new BufferedWriter(osw); BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out)); String lineStr; try { while((lineStr=br.readLine())!=null){ // System.out.println(lineStr); // osw.write(lineStr+"\r\n"); // osw.flush(); bw.write(lineStr); bw.newLine(); bw.flush(); if("over".equals(lineStr)){ break; } } } catch (IOException e) { // TODO Auto-generated catch block }finally{ if(br!=null) try { br.close(); } catch (IOException e) { e.printStackTrace(); } if(bw!=null) try { bw.close(); } catch (IOException e) { e.printStackTrace(); } } } }
21 确定使用Java io体系中的哪些类的规律
package day19IO; 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 TransStreamDemo2 { /*1: 源:键盘 * 目的:控制台 * * 2需求: * 把键盘录入的存储到文件中 * * 源:键盘 * 目的:文件 * * 3:将文件是数据打印字控制台上 * * 流操作的基本规律 * * 最痛苦的事情是流对象有太多。不知道用那一个 * * 同 3 个明确来完成选择: * * 1:明确 源和目的 * 源:输入流 InputStream Reader * 目的:输出流 OutputStream Writer * 2:明确操作的数据是否是纯文本 * 是纯文本:字符流 * 不是: 字节流 * 3:当体系明确后,在明确使用哪个具体的对象 * 通过设备来进行区分 * 源设备:包括 内存、硬盘、键盘 * 目的设备:包括 内存、硬盘、控制台 * ------------------------------------------------------------------------ * 需求1: * 将一个文件中的数据存储到另一个文件中,复制文件 * 源:文件 InputStream Reader 因为是源所以读取流 * 是不是文本:是 选择 Reader * 这样体系明确了 * 接下来明确要使用该体系中对象 * 明确设备:硬盘山的文件 * Reader体系中 可以操作文件的对象是FileReader * 是否需要提高效率: * 加入Reader体系的缓冲技术BufferedReader * 目的:文件 OutputStream Writer * 是不是文本:是 选择 Writer * 明确设备:硬盘山的文件 * Reader体系中 可以操作文件的对象是FileWriter * 是否需要提高效率: * 加入Reader体系的缓冲技术BufferedWriter * 练习:将图片文件数据存储到另一个文件中 * 复制文件 * 按照以上步骤 * 源: InputStream Reader * 文本? 不是 InputStream * 是否提高效率:BufferedInputStream * 目的:OutputStream Writer * 文本?不是 OutputStream * 提高效率:BufferedOutputStream * ---------------------------------------------------------- * 需求:将键盘录入的数据保存到一个文件中 * 这个需求中有源和目的都存在。 * 源: InputStream Reader * 文本? 是:Reader * 设备:键盘:对于的对象时System,in * 为了操作键盘的文本数据方便。转成字符流按照字符串操作是最方便的。 * 所以既然明确了Reader,那么就将System.in转换成Reader。 * 用了Reader体系中转换流,InputStreamReader * * InputStreamReader isr=new InputStreamReader(system.in) * 提高效率:? * BufferedReader bufr = new BufferedReader(isr); * 目的:OutPutStream Writer * 文本? Writer * 设备:硬盘: * 对象:FileWriter * FileWriter fw = new FileWriter("c.txt"); * 提高效率 * BufferedWriter bufw = new BufferedWriter(fw); * ----------------------------------------------------------- * 扩展:将录入 的数据按照指定的编码表(utf-8),存储 * 目的:OutPutStream Writer * 文本? Writer * 设备:硬盘: * 对象:FileWriter * 但是存储时 使用指定编码表 * 所以使用OutStreamWriter * 而该转回流对象要接受字节输出流,还可以操作文件的字节输出流FileOutpurStream * OutputStreamWriter osw=new OutputStreamWriter(new FileOutpurStream,”utf-8“) * 提高效率 * BufferedWriter bufw = new BufferedWriter(osw); * 所以 记住: * 转换流什么时候使用呢? * 字符和字节之间的桥梁 * 通常涉及字符编码转回式需要用到转换流 * * 练习: * 将文本数据打印在控制台上 * * 源:InputStream Reader * 文本:是 Reader * 设备硬盘:FielReader * 提高效率:BufferedReader * 目的:OutputStream Writer * 文本:不是 Writer * 设备:控制台 System.out转换成Writer。 * 用了Writer体系中转换流,OutputStreamWriter * 提高效率 * BufferedWriter bufw = new BufferedWriter(osw); * */ public static void main(String[] args) { // BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); // BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out)); BufferedReader br = null; BufferedWriter bw = null; String lineStr; try { // bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("out.txt"))); bw=new BufferedWriter(new OutputStreamWriter(System.out)); // bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("out_gbk.txt"),"GBK")); // bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("out_utf_8.txt"),"UTF-8")); br=new BufferedReader(new InputStreamReader(new FileInputStream("FileReaderDemo2.java"))); // br=new BufferedReader(new InputStreamReader(System.in)); while((lineStr=br.readLine())!=null){ if("over".equals(lineStr)){ break; } bw.write(lineStr); bw.newLine(); bw.flush(); } } catch (IOException e) { }finally{ if(br!=null) try { br.close(); } catch (IOException e) { e.printStackTrace(); } if(bw!=null) try { bw.close(); } catch (IOException e) { e.printStackTrace(); } } } }
22 Java 标准输入输出 改变
package day19IO; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintStream; public class TransStreamTurnStandDemo { /* * */ public static void main(String[] args) { BufferedReader br = null ; BufferedWriter bw = null ; String lineStr; try { System.setIn(new FileInputStream("fos.txt")); System.setOut(new PrintStream("zzz.txt")); br=new BufferedReader(new InputStreamReader(System.in)); bw=new BufferedWriter(new OutputStreamWriter(System.out)); while((lineStr=br.readLine())!=null){ bw.write(lineStr); bw.newLine(); bw.flush(); if("over".equals(lineStr)){ break; } } } catch (IOException e) { e.printStackTrace(); }finally{ if(br!=null) try { br.close(); } catch (IOException e) { e.printStackTrace(); } if(bw!=null) try { bw.close(); } catch (IOException e) { e.printStackTrace(); } } } }
23 Java io 异常处理 方式: 保存日志 log4j
package day19IO; import java.io.FileNotFoundException; import java.io.PrintStream; import java.text.SimpleDateFormat; import java.util.Date; public class ExceptionInfo { static SimpleDateFormat sdf; public static void main(String[] args) { sdf=new SimpleDateFormat("y年m月d-h时:m:分:s秒"); try { int arr[]=new int[2]; System.out.println(arr[2]); } catch (Exception e) { try { Date d=new Date(); PrintStream ps=new PrintStream("s.txt"); ps.println(sdf.format(d)); e.printStackTrace(ps); } catch (FileNotFoundException e1) { throw new RuntimeException("日志文件创建失败"); } } } } //log4j 专门保存日志的第三方包
24 系统信息重定向 保存
package day19IO; import java.io.FileNotFoundException; import java.io.PrintStream; import java.util.Properties; public class SystemInfo { /** * @param args */ public static void main(String[] args) { PrintStream ps = null; try { ps = new PrintStream("systeminfoprop.txt"); Properties prop=System.getProperties(); // System.out.println(prop); // prop.list(System.out); prop.list(ps); } catch (FileNotFoundException e) { e.printStackTrace(); } } }<span style="font-size:32px;"> </span>
《黑马程序员 java 基础 毕向东 面向对象 IO流操作》
讲解了Java IO流体系中操作类和方法,介绍了部分类的实现原理,相信在日后的应用中会跟得心应手。
以下是自己总结的java io体系中部分类的特点和继承、依赖关系