/** * IO(Input Output)流 * 作用: * 1)IO流用来处理设备之间的数据传递 * 2)Java对数据的操作是通过流的方式 * 3)Java用于操作流的兑现个都在IO包中 * 4)流按操作的数据分为两种:字节流 (通用) 和 字符流(基于字节流) * 5)流按流向来分:输出流 和 输入流 * * IO流常用的基类 * 字节流的抽象基类 * InputStream,OutputStream. * 字符流的抽象基类 * Reader,Writer. * 注:由这四个类派生出来的子类名称都是一其父类名称作为子类的后缀 * 如:InputStream的子类,FileInputStream * Reader的子类,FileReader * * 既然IO流是用户操作数据的 * 那么数据的最长体现形式是:文件 * * 那么先以操作文件为主来演示: * 需求:在硬盘上,创建一个文件并写入一些文字数据. * * 找到一个专门用于操作文件的Writer子类对象,FileWriter ,后缀名是父类名,前缀名是该流对象的功能. */ import java.io.FileWriter; import java.io.IOException; public class IODemo { public static void main(String[] args) throws IOException { //字符编码 //ASCII--中国(gbk)--国际组织(uncode(无论什么字符都用两个字节表示))-->UTF-8(优化uncode) //创建一个FileWriter对象,该对象一被初始化必须要明确被操作的文件. //而且该文件会被创建到指定的目录下,如果该目录下已有同名文件,则被覆盖. //其实该步骤就是在明确数据要存放的目的地. FileWriter fw=new FileWriter("demo.txt"); //调用write方法,将字符串写入到流中 fw.write("我想写入到文件中."); //刷行流对象中的缓冲的数据 //将数据刷到目的地中. //发现写的时候不是换行写,是接着在后面写 fw.flush(); //不刷新 ,上面流中的数据是不保存到文件中. fw.write("没关闭我就继续写,哈哈哈1."); fw.flush(); //关闭资源,但是在关闭之前会刷行一次内存中缓冲的数据. //然后将数据刷到目的地中. //和flush的区别:flush刷新后,流还可继续使用,close刷新后,会将流关闭,流不能用了. fw.write("没关闭我就继续写,哈哈哈2."); fw.close(); //fw.write("没关闭我就继续写,哈哈哈3."); //发现挂了,说java.io.IOException: Stream closed //demo.txt最后的结果 //我想写入到文件中.没关闭我就继续写,哈哈哈1.没关闭我就继续写,哈哈哈2. } }
IO异常的处理方式
对已有文件的续写
window下的换行
/** * IO异常的处理方式 * * 对已有文件的续写 */ import java.io.FileWriter; import java.io.IOException; public class FileWriterDemo2 { public static void main(String[] args) throws IOException { method_1(); } //对已有的文件的数据的续写 (没有处理异常,注意) public static void method_1() throws IOException{ //传递一个true 擦恕,代表不覆盖已有的文件,并在已有文具店 末尾处进行续写. FileWriter fw=new FileWriter("demo.txt",true); fw.write("nihao\r\n哈哈");//换行: window: \r\n linux:\n fw.close(); } //IO异常的标准处理方式 public static void method(){ FileWriter fw=null; try{ fw=new FileWriter("k:\\demo.txt");//系统找不到指定的路径 fw.write("开课写数据到流缓冲中!"); //fw.close(); //异常后也需要处理 所以要放到 finally 里面 }catch(IOException e){ e.printStackTrace(); }finally{ //fw.close(); //直接放到这里还不行,因为这句还会出异常. try { if(fw!=null)//系统找不到指定的路径 fw.close(); } catch (Exception e) { e.printStackTrace(); } } } }
FileReader
当个字符读取
字符数组读取
import java.io.FileReader; import java.io.IOException; public class FileReaderDemo { public static void main(String[] args) throws IOException { method_2(); //method_1(); } //第二种方式的变形 public static void method_2() throws IOException{ FileReader fr=new FileReader("demo.txt"); char[] buf=new char[1024]; //1024*2=2k int num=0; while((num=fr.read(buf))!=-1){ System.out.print(new String(buf,0,num)); } } //第二种方式:通过字符数组进行读取 (没有做异常处理) public static void method_1() throws IOException{ //demo.txt里面文本是: 我爱中华人民共和国我爱人民 FileReader fr=new FileReader("demo.txt"); char[] chs=new char[3]; int num=fr.read(chs); System.out.println("num="+num+"...."+new String(chs));//num=3....我爱中 int num1=fr.read(chs); System.out.println("num="+num1+"...."+new String(chs));//num=3....华人民 int num2=fr.read(chs); System.out.println("num="+num2+"...."+new String(chs));//num=3....共和国 int num3=fr.read(chs); System.out.println("num="+num3+"...."+new String(chs)); //num=3....我爱人 //为什么会出现 "民爱人" //是将上一次的chs['我','爱','人']-->中的 "我"-->替换成 读取到的"民" int num4=fr.read(chs); System.out.println("num="+num4+"...."+new String(chs,0,1)); //num=1....民爱人 System.out.println("num="+num4+"...."+new String(chs)); //num=1....民爱人 //打印的还是上一次 保存的在数组中的数据 int num5=fr.read(chs); System.out.println("num="+num5+"...."+new String(chs)); //num=-1....民爱人 fr.close(); } //第一种方式: 使用 read()每次读取一个 字符 public static void method() throws IOException{ //创建一个文件读取流对象,和指定名称的文件相关联. //要保证该文件是已经存在的,如果不粗壮奶,会发生异常. FileNotFoundException FileReader fr=new FileReader("demo.txt"); //调用读取流对象的read方法 //read():一次读一个字符,而且会自动往下读,如果没有读取完了就返回 -1 /*int ch=fr.read(); System.out.println("ch="+(char)ch); int ch2=fr.read(); System.out.println("ch2="+(char)ch2);*/ //方式一 /*while(true){ int ch=fr.read(); if(ch==-1) break; System.out.println("ch="+(char)ch); }*/ //方式二 高效点 int ch=0; while((ch=fr.read())!=-1){ System.out.print((char)ch); } //关闭资源 fr.close(); } }
练习:读取一个java文件,并打印在控制台上.
import java.io.FileReader; import java.io.IOException; /** * 练习:读取一个java文件,并打印在控制台上. */ public class FileReaderTest { public static void main(String[] args) throws IOException { FileReader fr=new FileReader("E:\\workspace4\\exam\\src\\com\\itheima\\day18\\p1\\FileReaderDemo.java"); char [] buf=new char[1024]; int num=0; while((num=fr.read(buf))!=-1){ System.out.println(new String(buf,0,num)); } } }
复制
import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; /** * 需求:将CC盘的一个文本复制到D盘 * 复制原理: * 其实就是将C盘下的文件数据存储到D盘的一个文件中. * * 步骤: * 1) 在D盘中创建一个文件,用户存储C盘文件中的数据 * 2)定义读取流和C盘文件关联. * 3)通过不断的读写完成数据的存储. * 4)关闭资源 */ public class CopyText { public static void main(String[] args) throws IOException { copy_2(); //copy_1(); } //使用 字符数组进行copy 提高效率 public static void copy_2(){ FileWriter fw=null; FileReader fr=null; try { fw=new FileWriter("SystemDemo_copy.txt"); fr=new FileReader("E:\\workspace4\\exam\\src\\com\\itheima\\day18\\SystemDemo.java"); char[] cbuf=new char[1024]; int len=0; while((len=fr.read(cbuf))!=-1){ fw.write(cbuf, 0, len); fw.flush(); } } catch (Exception e) { e.printStackTrace();//读写失败 }finally{ if(fw!=null) try{ fw.close(); }catch(IOException e){ e.printStackTrace(); } if(fr!=null) try{ fr.close(); }catch(IOException e){ e.printStackTrace(); } } } //从C盘读取一个字符 ,就往D盘写一个字符 public static void copy_1() throws IOException{ //创建 目的地. FileWriter fw=new FileWriter("FileReaderDemo_copy.txt"); //与已有文件关联 FileReader fr=new FileReader("E:\\workspace4\\exam\\src\\com\\itheima\\day18\\p1\\FileReaderDemo.java"); int ch=0; while((ch=fr.read())!=-1){ fw.write(ch); //fw.flush(); } fw.close(); fr.close(); //数据不多可以直接关闭 } }