------- android培训、java培训、期待与您交流! ----------
IO流,英文I/O Stream,代表输入输出流。流表示一连串的数据。
当前程序用输入流(InputStream)从数据源(比如硬盘上的文件,键盘,条码扫描枪,其他程序等)读取数据,如下图所示:
当前程序用输出流(OutputStream)向目的地(比如硬盘上的文件,键盘,条码扫描枪,其他程序等)写入数据,如下图所示:
java中关于IO流的类主要都在java.io包中,四个主要基类如下表:
FIleWriter类继承Writer类,它有一个构造方法FileWriter(String FileName),用来创建FileWriter实例,FileWriter实例一但被初始化, 就必须要明确被操作的文件。如果FileName指定目录存在,但文件不存在,则创建新文件,如果文件已存在,则覆盖成空文件。如果FileName参数直接传文件名,不写路径,则创建在项目目录下。
FileWriter类还有继承来的write(String str)方法,用于将字符串写入到流中。
flush():将流对象缓冲中的数据刷到目的地中。
close():该方法用于关闭流资源,关闭之前会将流对象缓冲中的数据刷到目的地中。
上面的方法用法的例子:
import java.io.FileWriter; import java.io.IOException; public class FileWriterDemo { public static void main(String[] args) throws IOException { String fileName="F:\\Mytreasure\\study\\java\\IO\\a.txt"; FileWriter fileWriter=new FileWriter(fileName); fileWriter.write("nihao"); fileWriter.flush(); fileWriter.write("haha"); fileWriter.close(); //在close()后调用write会报异常 //fileWriter.write("after close invoke me"); } }
import java.io.FileWriter; import java.io.IOException; public class IOExceptionDemo { public static void main(String[] args) { FileWriter fw=null; try { fw=new FileWriter("test.txt"); fw.write("你好"); } catch (IOException e) { System.err.println(e.toString()); }finally { try { if(fw!=null) fw.close(); } catch (IOException e) { System.err.println(e.toString()); } } System.out.println("文件写入成功"); } }上面的方法虽然繁琐,但是可以保证程序最低的报错几率。注意上面的System.err.println()它的功能和System.out.println()一样,只不过,在MyEclipse中输出时显示红色字体,以突出是错误提示。
import java.io.FileWriter; import java.io.IOException; public class ContinueWrite { public static void main(String[] args) { FileWriter fw=null; try { fw=new FileWriter("test.txt",true); fw.write("\r\n前面是windows换行"); fw.write("\n前面是Linux换行");//用记事本打开时,此换行不好使 } catch (IOException e) { System.err.println(e.toString()); }finally{ try { if(fw!=null){ fw.close(); } } catch (Exception e) { System.err.println(e.toString()); } } } }
import java.io.FileReader; import java.io.IOException; public class FileReaderDemo { public static void main(String[] args) { // 创建一个文件读取流对象,和指定名称的文件相关联 // 要保证该文件已经存在,如不存在,会发生异常FileNotFoundException FileReader fileReader = null; try { fileReader = new FileReader("test.txt"); int ch=0; while ((ch=fileReader.read())!=-1) { System.out.println((char) ch); } } catch (IOException e) { System.err.println(e.toString()); } finally { try { if (fileReader != null) { fileReader.close(); } } catch (IOException e) { System.err.println(e.toString()); } } } }上述代码中的read()方法,一次读一个字符,且会自动往后读,如果读到文件末尾,则会返回-1;
import java.io.FileReader; import java.io.IOException; public class ReadFileByCharArray { public static void main(String[] args) { char[] buffer=new char[1024]; FileReader fr=null; try { fr = new FileReader("test.txt"); int num=0; while ((num=fr.read(buffer))!=-1){ System.out.println(new String(buffer,0,num)); } } catch (IOException e) { System.err.println(e.toString()); } finally { try { if (fr != null) fr.close(); } catch (IOException e) { System.err.println(e.toString()); } } } }其中当调用FileReader的read(char[] buffer)方法时,返回的是此轮读到的字符个数,如果一个字符都没读到,则返回-1。上面代码中利用String类的带三个参数的构造函数new String(char[],int,int),其中第一个参数表示构成字符串的字符数组,第二个参数表示导入字符串的第一个字符在字符数组中的索引,第三个参数表示导入字符串的最后一个字符在字符数组中的索引。这种方法要比上面的一种读取方法要好的多,因为是从文件一批一批的读数据,性能会高很多。另外,字符数组buffer一般都声明成1024个元素,这被证明是最合适的大小。
import java.io.FileReader; import java.io.IOException; public class FileReaderExercise { //从硬盘读取一个.java文件,并打印出来 public static void main(String[] args) { FileReader fr=null; char[] buffer=new char[1024]; int num=0; try { fr=new FileReader("Demo.java"); while((num=fr.read(buffer))!=-1){ System.out.print(new String(buffer,0,num)); } } catch (IOException e) { System.err.println(e.toString()); } finally { try { if (fr != null) fr.close(); } catch (IOException e) { System.err.println(e.toString()); } } } }
import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class CopyFileDemo { public static void main(String[] args) { copy("c:\\test.txt", "d:\\test.txt"); } public static void copy(String source,String destination){ FileWriter fw=null; FileReader fr=null; char[] buffer=new char[1024]; int len=0; try { fw=new FileWriter(destination); fr=new FileReader(source); while ((len=fr.read(buffer))!=-1) { fw.write(buffer,0,len); } } catch (IOException e) { throw new RuntimeException(e); }finally{ try { if(fw!=null)fw.close(); if(fr!=null)fr.close(); } catch (IOException e2) { throw new RuntimeException(e2); } } } }
import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; public class BufferedWriterDemo { public static void main(String[] args) { FileWriter fw=null; BufferedWriter bw=null; try { fw = new FileWriter("test.txt",true); bw=new BufferedWriter(fw); for (int i = 0; i < 5; i++) { bw.write("测试文本"); bw.newLine();//跨平台的换行 } bw.flush(); //关闭缓冲区就是关闭流,所以此处不用再写fw.close() bw.close(); } catch (IOException e) { throw new RuntimeException(e); } finally { try { if (fw != null) fw.close(); if (bw != null) bw.close(); } catch (IOException e) { throw new RuntimeException(e); } } } }
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; public class BufferedReaderDemo { public static void main(String[] args) { FileReader fr=null; BufferedReader br=null; String line=""; try { fr=new FileReader("test.txt"); br=new BufferedReader(fr); while((line=br.readLine())!=null){ System.out.println(line); } } catch (IOException e) { throw new RuntimeException(e); } finally { try { if (br != null) br.close(); } catch (IOException e) { throw new RuntimeException(e); } } } }注意上面的readLine()方法并不返回换行符,所以需要自己加换行。readLine方法的原理:其实从硬盘到内存还是一个字符一个字符读入,但是从内存到当前程序时,是先读取完一行(以遇到\r或\n为标志),然后传给当前程序使用。
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class BufferedCopyDemo { public static void main(String[] args) { BufferedReader br=null; BufferedWriter bw=null; try { br=new BufferedReader(new FileReader("test.txt")); bw=new BufferedWriter(new FileWriter("test_copy.txt")); String line=""; while ((line=br.readLine())!=null) { bw.write(line); bw.newLine(); } } catch (IOException e) { throw new RuntimeException(e); } finally { try { if (br != null) br.close(); if (bw != null) bw.close(); } catch (IOException e) { throw new RuntimeException(e); } } } }
import java.io.FileReader; import java.io.IOException; class MyBufferedReader{ FileReader r; public MyBufferedReader(FileReader r) { this.r=r; } public String readLine() throws IOException{ //原生的BufferedReader方法封装的是字符数组,我们为了演示方便,这里用StringBuilder StringBuilder sb=new StringBuilder(); int ch=0; while((ch=r.read())!=-1){ if (ch=='\r') { continue; } if (ch=='\n') { return sb.toString(); } sb.append((char)ch); } //这里是防止读到最后一行时,无行终止符,导致最后一行文本没读进来的问题 if (sb.length()>0) { return sb.toString(); } return null; } public void close() throws IOException{ r.close(); } } public class MyBufferReaderDemo { public static void main(String[] args) { MyBufferedReader mybr=null; try { mybr=new MyBufferedReader(new FileReader("test.txt")); String line=""; while ((line=mybr.readLine())!=null) { System.out.println(line); } } catch (IOException e) { throw new RuntimeException(e); } finally { try { if (mybr != null) mybr.close(); } catch (IOException e) { throw new RuntimeException(e); } } } }
//被装饰的类 class Person{ public void eat(){ System.out.println("吃饭"); } } //装饰类 class DecoratorPerson{ private Person p; public DecoratorPerson(Person p) { this.p=p; } public void enjoyEat(){ System.out.println("开胃菜"); p.eat(); System.out.println("水果"); } } public class DecoratorPattern { public static void main(String[] args) { Person person=new Person();//定义被装饰的对象 DecoratorPerson dp=new DecoratorPerson(person); dp.enjoyEat(); } }当想要对已有的对象进行功能增强时,可以先定义一个类,然后将已有对象传入,通过定义新方法调用已有对象的方法并进行增强,该自定义类称为装饰类。
import java.io.FileReader; import java.io.IOException; import java.io.Reader; class MyBufferedReader extends Reader{//这里继承Reader以使MyBufferedReader与Reader在一个体系中 Reader r;//这里把FileReader改为Reader,从而使本类不只可以装饰FileReader,还可以装饰其他Reader public MyBufferedReader(Reader r) { this.r=r; } public String readLine() throws IOException{ //原生的BufferedReader方法封装的是字符数组,我们为了演示方便,这里用StringBuilder StringBuilder sb=new StringBuilder(); int ch=0; while((ch=r.read())!=-1){ if (ch=='\r') { continue; } if (ch=='\n') { return sb.toString(); } sb.append((char)ch); } //这里是防止读到最后一行时,无行终止符,导致最后一行文本没读进来的问题 if (sb.length()>0) { return sb.toString(); } return null; } public void close() throws IOException{ r.close(); } @Override public int read(char[] cbuf, int off, int len) throws IOException { return r.read(cbuf, off, len); } }
import java.io.FileReader; import java.io.IOException; import java.io.LineNumberReader; public class LineNumberReaderDemo { public static void main(String[] args) { FileReader fr=null; LineNumberReader lnr=null; try { fr=new FileReader("AutoBoxing.java"); lnr=new LineNumberReader(fr); lnr.setLineNumber(100); String buf=null; while((buf=lnr.readLine())!=null){ System.out.println(lnr.getLineNumber()+":"+buf); } } catch (IOException e) { throw new RuntimeException(e); } finally { try { if (lnr != null) lnr.close(); } catch (IOException e) { throw new RuntimeException(e); } } } }
import java.io.FileReader; import java.io.IOException; import java.io.Reader; class MyLineNumberReader extends MyBufferedReader{ int lineNumber; public MyLineNumberReader(Reader r){ super(r); } public String readLine() throws IOException{ lineNumber++; return super.readLine(); } public void setLineNumber(int number){ this.lineNumber=number; } public int getLineNumber(){ return this.lineNumber; } } public class MyLineNumberDemo{ public static void main(String[] args)throws IOException { FileReader fr=new FileReader("AutoBoxing.java"); MyLineNumberReader mnd=new MyLineNumberReader(fr); String line=""; mnd.setLineNumber(10); while((line=mnd.readLine())!=null){ System.out.println(mnd.getLineNumber()+":"+line); } mnd.close(); } }