黑马程序员----JAVA基础----IO流_1
2015-07-21 10:21
246 查看
------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
一、IO流
IO流是用来处理设备之间的数据传输,Java对数据的操作是通过流的方式,而这些操作流的对象都在IO包中。
流按数据操作可分为字节流和字符流(处理文本数据);
a,字节流:读取文字字节的数据
b,字符流:在字节流的基础上,不直接操作而是先查找指定编码表,获取对应的文字。简单说:字符流就是字节流+编码表。
流按流向可分为输入流和输出流。
a,输入流:从外部设备读数据到内存中。
b,输出流:将内存中的数据写到外部设备上。
二、IO流体系
IO流有四个顶层基类:
字节流抽象基类:InputStream、OutputStream
字符流抽象基类:Reader、Writer
对于IO流体系内的类的名称来说:子类都以父类名作为后缀,子类名的前缀表示该类的功能
三、IO流使用
1,创建一个可以向文件中写入数据的字符输出流对象及一些细节问题
3,读取一个文件,将文件的内容打印到控制台上。
4,字符流的缓冲区。缓冲区提高了数据的读写效率,对应类:BufferedReader、BufferedWriter。
缓冲区要结合流才可以使用,在流的基础上对流的功能进行增强。
缓冲区常用方法:readlLine()、newLine()
注意:使用缓冲区一定要使用flusn()方法!!!
使用缓冲区与流结合高效读写数据,并加上异常处理:
5,装潢设计模式:对一组对象的功能进行增强时,就可以使用该模式进行问题的解决
装潢和继承都能进行功能的扩展增强,那么二者的区别是什么呢?用继承来进行功能的扩展,
会导致继承体系越来越臃肿,不够灵活。装饰比继承更为灵活
注意:装饰类和被装饰类必须所属同一个接口或者父类!!!
装饰类:BufferedReader、BufferedWriter、LineNumberReader等。
其中LineNumberReader的特有方法:setLineNumber(int index)、getLineNumber()(返回行号)
6,字节流两个常用子类FileInputStream、FileOutputStream,该类的read()方法一次读取一个字节,available()方法可以
返回与其关联文件的字节数
字符流只可以处理文本文件,而字节流既可以处理文本文件,又可以处理非文本文件。
注意在使用BufferedOutputStream时不用使用flush()方法,原因:
字符流底层使用的还是字节流,因为字符流融合了编码表,所以可以读写字符。
字符流写入文本数据时,需要先将文本数据写入字符流中,对照编码表转换成字节数据,然后flush进目的地。
字节流中是字节数据不需要转换,所以可以直接写入目的地。
7,读取键盘录入的数据并打印在控制台上
InputStreamReader 和 OutputStreamWriter是字节流与字符流之间的桥梁
InputStreamReader:字节到字符的桥梁,解码。
OutputStreamWriter:字符到字节的桥梁,编码。
8,流的操作规律
a,明确源和目的源:InputStream
Reader目的: OutputStream
Writer
b,明确数据是否是纯文本数据源:是纯文本用Reader,否InputStream
目的:是纯文本用Writer,否OutputStream
c,明确具体的设备源:硬盘(File)、键盘(System.in)、内存(数组)、网络(Socket流)
目的设备与源相同。
d,是否需要额外功能是否需要高效?是,加Buffer
四、File类
用来将文件或文件夹封装成对象,方便对文件和文件夹的属性进行操作,File对象可作为参数传递给流的构造函数。
一、IO流
IO流是用来处理设备之间的数据传输,Java对数据的操作是通过流的方式,而这些操作流的对象都在IO包中。
流按数据操作可分为字节流和字符流(处理文本数据);
a,字节流:读取文字字节的数据
b,字符流:在字节流的基础上,不直接操作而是先查找指定编码表,获取对应的文字。简单说:字符流就是字节流+编码表。
流按流向可分为输入流和输出流。
a,输入流:从外部设备读数据到内存中。
b,输出流:将内存中的数据写到外部设备上。
二、IO流体系
IO流有四个顶层基类:
字节流抽象基类:InputStream、OutputStream
字符流抽象基类:Reader、Writer
对于IO流体系内的类的名称来说:子类都以父类名作为后缀,子类名的前缀表示该类的功能
三、IO流使用
1,创建一个可以向文件中写入数据的字符输出流对象及一些细节问题
import java.io.FileWriter; import java.io.IOException; public class IODemo { private static final String LINE_SEPARATOR = System.getProperty("line.separator"); public static void main(String[] args) throws IOException{ /* * 在创建字符流对象时,必须明确与其关联的文件 * 会抛出一个IO异常,原因:可能无法关联 */ // 用字符输出流关联一个文本文件,文件存在,会覆盖其中的内容,如果该文件不存在,则创建一个文本文件 // 如果需要续写文件,则在构造函数中加入true FileWriter fw = new FileWriter("demo.txt"); // FileWriter fw = new FileWriter("demo.txt",true); //使用该流,就可以续写,而不会发生覆盖 // 调用FileWriter中的write()方法,写入数据,数据被写入临时数据缓冲区中 fw.write("abcdefg"); /* * 换行:在windos系统中换行符:\r\n,在Linux系统中:\n * 有两种方法,一是+\r\n;一种是用系统提供的方法System.getProperty("line.separator") * 第二种方法不用考虑系统问题 */ fw.write("hehe"+"\r\n"+"heihei"); fw.write("hehe"+LINE_SEPARATOR+"heihei"); // 运行flus()方法,将缓冲区的数据刷新到文本文件中 fw.flush(); // 关闭流,关闭资源,关闭前会调用flush刷新缓冲区的数据到文本文件中,因此flush可以省略 fw.close(); // 关闭流后再写入数据,就会引起IOException // fw.write("cde"); } }2,IO异常处理
import java.io.FileWriter; import java.io.IOException; public class IODemo2 { private static final String LINE_SEPARATOR = System.getProperty("line.separator"); public static void main(String[] args) throws IOException { // 先创建字符输出流对象 FileWriter fw = null; try{ // 关联文件操作失败会引发IOException,因此将其放到try block中 fw = new FileWriter("demo.txt"); fw.write("abc"+LINE_SEPARATOR+"def"); }catch(IOException e){ // 处理异常 }finally{ // 表示一定要关闭资源 // 加上判断条件,当fw不为null时才可以关闭,否则会引发NullPointerException if(fw!=null) try{ fw.close(); }catch(IOException e){ System.out.println(e.toString()); } } } }
3,读取一个文件,将文件的内容打印到控制台上。
<pre name="code" class="html">import java.io.FileReader; import java.io.IOException; public class IODemo3 { public static void main(String[] args) throws IOException { // 用读取流关联文件,文件不存在则会引发FileNotFoundException FileReader fr = new FileReader("demo.txt"); // 读一次 // show1(fr); // 循环读取方式 // show2(fr); // 使用字符数组,将数据读取到数组中 show3(fr); fr.close(); } private static void show3(FileReader fr) throws IOException { char[] buf = new char[1024]; //一般将数组的大小设为1024,如果数字是固定的,可以将其设置为常量 int len=0; while((len=fr.read(buf))!=-1){ // 使用String构造函数,将字符数组转换成字符串 System.out.println(new String(buf,0,len)); } } private static void show2(FileReader fr) throws IOException { int ch = 0; while((ch=fr.read())!=-1){ System.out.print((char)ch); //使用强制转换,将int转为char类型 } } private static void show1(FileReader fr) throws IOException { int ch = fr.read(); // 用读取流的read()方法读取数据,返回读取到的字符数,读到结尾返回-1 System.out.print((char)ch); //使用强制转换,将int转为char类型 } }
4,字符流的缓冲区。缓冲区提高了数据的读写效率,对应类:BufferedReader、BufferedWriter。
缓冲区要结合流才可以使用,在流的基础上对流的功能进行增强。
缓冲区常用方法:readlLine()、newLine()
注意:使用缓冲区一定要使用flusn()方法!!!
使用缓冲区与流结合高效读写数据,并加上异常处理:
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class BufferedDemo { public static void main(String[] args) { // TODO Auto-generated method stub // 创建缓冲区对象 BufferedReader bufr = null; BufferedWriter bufw = null; try{ // 与流相关联 bufr = new BufferedReader(new FileReader("demo.txt")); bufw = new BufferedWriter(new FileWriter("copydemo.txt")); String line = null; // readLine()是读取一行 while((line=bufr.readLine())!=null){ bufw.write(line); bufw.newLine(); // 换行 bufw.flush(); // 使用缓冲区一定要刷新 } }catch(IOException e){ System.out.println(e.toString()); }finally{ // 当bufr和bufw不为空时,才可以关闭流 if(bufr!=null) try{ bufr.close(); }catch(IOException e){ } if(bufw!=null) try{ bufw.close(); }catch(IOException e){ } } } }
5,装潢设计模式:对一组对象的功能进行增强时,就可以使用该模式进行问题的解决
装潢和继承都能进行功能的扩展增强,那么二者的区别是什么呢?用继承来进行功能的扩展,
会导致继承体系越来越臃肿,不够灵活。装饰比继承更为灵活
注意:装饰类和被装饰类必须所属同一个接口或者父类!!!
装饰类:BufferedReader、BufferedWriter、LineNumberReader等。
其中LineNumberReader的特有方法:setLineNumber(int index)、getLineNumber()(返回行号)
6,字节流两个常用子类FileInputStream、FileOutputStream,该类的read()方法一次读取一个字节,available()方法可以
返回与其关联文件的字节数
字符流只可以处理文本文件,而字节流既可以处理文本文件,又可以处理非文本文件。
注意在使用BufferedOutputStream时不用使用flush()方法,原因:
字符流底层使用的还是字节流,因为字符流融合了编码表,所以可以读写字符。
字符流写入文本数据时,需要先将文本数据写入字符流中,对照编码表转换成字节数据,然后flush进目的地。
字节流中是字节数据不需要转换,所以可以直接写入目的地。
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 CopyMediaDemo { public static void main(String[] args) throws IOException { // 方法1 // show1(); // 方法2 show2(); } private static void show2() throws FileNotFoundException, IOException { FileInputStream fis = new FileInputStream("Desert.jpg"); FileOutputStream fos = new FileOutputStream("Desert_copy.jpg"); byte[] buf = new byte[1024]; int len = 0; len=fis.read(buf); System.out.println(len); // 如果read()方法里不加数组buf,那么len就是读到的字节的值 // 加上buf后,len表示读进buf的字节数量 // while((len=fis.read())!=-1){ // fos.write(buf,0,len); // } while((len=fis.read(buf))!=-1){ fos.write(buf,0,len); } fos.close(); } /** * */ private static void show1() { BufferedInputStream bis = null; BufferedOutputStream bos = null; try { // 将缓冲区与流相关联 bis = new BufferedInputStream(new FileInputStream("Desert.jpg")); bos = new BufferedOutputStream(new FileOutputStream("Desert_copy.jpg") bc76 ); int ch=0; while((ch=bis.read())!=-1){ /* * 字符流底层使用的还是字节流,因为字符流融合了编码表,所以可以读写字符。 * 字符流写入文本数据时,需要先将文本数据写入字符流中,对照编码表转换成字节数据, * 然后flush进目的地。字节流中是字节数据不需要转换,所以可以直接写入目的地 */ bos.write(ch); } } catch (Exception e) { e.printStackTrace(); }finally{ // 关闭流,释放资源,记着判断流是否为空 if(bos!=null) try { bos.close(); } catch (Exception e) { e.printStackTrace(); } if(bis!=null) try { bis.close(); } catch (Exception e) { e.printStackTrace(); } } } }
7,读取键盘录入的数据并打印在控制台上
InputStreamReader 和 OutputStreamWriter是字节流与字符流之间的桥梁
InputStreamReader:字节到字符的桥梁,解码。
OutputStreamWriter:字符到字节的桥梁,编码。
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; public class KeyDemo { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub // 创建字节流接 InputStream in = System.in; // 读取一次 // show1(in); // 无限读取,直到遇到特定标记停止 // show2(in); // 通过字节字符桥梁来完成键盘录入及打印操作 show3(in); // 流关闭后再创建新流会产生异常IOException // InputStream in1 = System.in; // int ch1 = in.read(); // System.out.println(ch1); } private static void show3(InputStream in) throws IOException { // InputStreamReader和OutPutStreamWriter是字节流与字符流的桥梁 BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out)); String str = null; while((str=bufr.readLine())!=null){ if("over".equals(str)) break; bufw.write(str); bufw.newLine(); bufw.flush(); } } private static void show2(InputStream in) throws IOException { // 创建一个StringBuilder用于接收数据 StringBuilder sb = new StringBuilder(); int ch=0; while((ch=in.read())!=-1){ // 当回车时,输出键盘录入的内容 if(ch=='\r') continue; if(ch=='\n'){ String temp = sb.toString(); // 当输入内容为over时就结束 if("over".equals(temp)) break; // 将键盘录入数据转成大写输出 System.out.println(temp.toUpperCase()); // 输出数据后清空sb sb.delete(0, sb.length()); }else sb.append((char)ch); // 将ch转换成字符存入sb中 } } private static void show1(InputStream in) throws IOException { int ch = in.read(); // 阻塞式 System.out.println(ch); in.close(); } }
8,流的操作规律
a,明确源和目的源:InputStream
Reader目的: OutputStream
Writer
b,明确数据是否是纯文本数据源:是纯文本用Reader,否InputStream
目的:是纯文本用Writer,否OutputStream
c,明确具体的设备源:硬盘(File)、键盘(System.in)、内存(数组)、网络(Socket流)
目的设备与源相同。
d,是否需要额外功能是否需要高效?是,加Buffer
四、File类
用来将文件或文件夹封装成对象,方便对文件和文件夹的属性进行操作,File对象可作为参数传递给流的构造函数。
import java.io.File; import java.io.FileFilter; import java.io.FilenameFilter; import java.io.IOException; public class FileDemo { public static void main(String[] args) throws IOException { // 可以建一个存在的和不存在的文件或者目录封装成对象 // 构造函数的集中不同形式 File f1 = new File("demo.txt"); File f2 = new File("D:\\JAVA\\Blog\\","demo.txt"); File f3 = new File("D:\\JAVA\\Blog\\"); File f4 = new File(f3,"demo.txt"); // 字段 File.separator 对于不同的操作系统都可以应用 File f5 = new File("D:"+File.separator+"JAVA"+File.separator+"Blog"+File.separator+"demo.txt"); /* * File类常见方法 * 1,获取:文件名称、大小、路径、修改时间等 * 2,创建与删除 * 3,判断: */ // 获取 System.out.println("getName():"+f1.getName()); System.out.println("length():"+f1.length()); System.out.println("path:"+f1.getPath()); System.out.println("absolutePath:"+f1.getAbsolutePath()); //获取绝对路径 System.out.println("lastModified:"+f1.lastModified()); // 创建与删除 File file = new File("aaa.txt"); // 和输出流不一样,如果文件不存在则创建,如果存在就不创建。输出流是在与不在都会创建,在就覆盖 boolean b = file.createNewFile(); boolean b1 = file.delete(); // 删除文件 // 创建目录 File file1 = new File("abc"); boolean b2 = file1.mkdir(); boolean b3 = file1.delete();// 注意:如果要删除的文件内部有其他文件,则无法删除 // 创建多级目录 File file2 = new File("abc\\def\\mnk\\ss"); boolean b4 = file2.mkdirs(); boolean b5 = file2.delete();// 删除的ss文件夹,不会都删除 // 判断 File file3 = new File("demo.txt"); System.out.println(file3.exists()); //是否存在,当文件是未知时,应该先判断是否存在 System.out.println(file3.isDirectory());//是不是目录 System.out.println(file3.isFile());// 是不是文件 // renameTo() File file4 = new File("demo.txt"); File file5 = new File("DEMO.txt"); File file6 = new File("d:\\demo_copy.txt"); // file4.renameTo(file5); //同目录下重命名, // file4.renameTo(file6); //非同文件下,移动并重命名 // listRoots 获取根目录列表 File[] file7 = File.listRoots(); for(File files:file7){ System.out.println(files); } // File file8 = new File("d:\\"); System.out.println(file8.getFreeSpace()); // 盘符的可用空间 System.out.println(file8.getUsableSpace()); // 盘符的可用空间 System.out.println(file8.getTotalSpace()); // 盘符的大小 // list 获取当前目录下的文件及文件夹名称,包含隐藏文件 // 注意:调用list方法的File类对象中封装的必须是目录,否则会发生NullPointerException // 如果访问系统级目录也会发生NullPointerException // 如果目录存在但没有内容,会返回一个长度为0的数组 String[] names = file8.list(); for(String name:names){ System.out.println(name); } // FilenameFilter 获取指定类型的文件 File file9 = new File("E:\\数据\\BLS900"); String[] strs = file9.list(new FilterByMnd()); for(String str:strs){ System.out.println(str); } File[] files = file9.listFiles(new FilterByHidden()); for(File f:files){ System.out.println(f); } } } class FilterByMnd implements FilenameFilter{ //创建构造函数,可以方便过滤某后缀的文件 // private String suffix; // // public FilterByMnd(String suffix) { // super(); // this.suffix = suffix; // } // @Override // public boolean accept(File dir, String name) { // // TODO Auto-generated method stub // return name.endsWith(suffix); // } @Override public boolean accept(File dir, String name) { // TODO Auto-generated method stub return name.endsWith(".mnd"); } } class FilterByHidden implements FileFilter{ @Override public boolean accept(File pathname) { // TODO Auto-generated method stub return !pathname.isHidden(); } }
相关文章推荐
- 黑马程序员——java基础——接口
- Java面试-Hibernate总结
- 黑马程序员——Java交通灯管理系统&银行业务系统
- Web程序员开发5个诀窍
- 程序员开发编程经验知识总结
- 几道坑人的PHP面试题 试试看看你会不会也中招
- 面试时碰到的一道数据库题目
- 面试时碰到的一道数据库题目
- 面试时碰到的一道数据库题目
- 专题十 面试基本应对机制
- 【LeetCode-面试算法经典-Java实现】【017-Letter Combinations of a Phone Number (电话号码上的单词组合)】
- 【LeetCode-面试算法经典-Java实现】【016-3 Sum Closest(最接近的三个数的和)】
- 【LeetCode-面试算法经典-Java实现】【015-3 Sum(三个数的和)】
- OSChina 周二乱弹 —— 锄禾日当午,码农好辛苦
- 黑马程序员--面向对象之封装
- 黑马程序员————Java基础日常笔记---IO流二
- java面试---自动装箱
- 李陈铖求职安卓开发工程师简历20150720
- 面试题06_重建二叉树——剑指offer系列
- 上海麻辣马资深程序员叶劲峰:我的游戏人生