====
day13,day14
day13java学习笔记: 基础知识: day13,day14 异常、File类、IO流
一、异常 异常就是程序出现了不正常的情况。 代码在编译或运行的时候出现的不正常的情况。 1.概念 (1)Throwable类是java语言中所有错误(Error)或异常(Exception)的超类。 (2)Error是Throwable的子类,用于指示合理的应用程序不应该试图捕获的严重问题,如内存不足,即我们的程序不处理。 (3)Exception类及其子类是Throwable的一种形式,它指出了合理的应用程序想要捕获的条件。也就是说针对程序发生了Exception的情况是我们需要处理的问题。在Exception类里有所有异常情况。 (4)RuntimeException:是那些可能发生在java虚拟机正常运行期间抛出的异常的超类。 (5)Exception分为运行期异常和编译期异常。 A.运行期的异常:在编译期是不处理的,在程序运行时出现了问题,需要我们回来修改代码。 B.编译期的异常:在编译期就必须处理,否则程序不能通过编译,就更不能正常地执行了。
2.异常的体系 Throwable:是根类,不是接口。 |--Error:我们处理不了的,如硬件、内存不足等。严重问题,不需要程序处理。 |--Exception:我们可以处理的异常。 |--运行时异常:代码在编译期不会报错,我们可以在出现问题后,修改代码,也可以像编译期异常一样,try...catch或throws。 |--编译时异常:代码在编译期会报错,如果不对异常进行处理,程序没有办法执行,即必须先处理再运行。
3.JVM对异常的默认处理方式 java.lang.ArithmeticException:异常的类名,包括包名 by zero:异常的原因 at ... method(....java 17):异常的位置 如果程序出现了问题,我们没有做任何处理,最终JVM会做出默认的处理。处理方案: A.把异常的类名名称、异常的原因、异常出现的位置等信息在控制台输出。 B.让程序停止执行。
4.异常处理方案try...catch (1)方案1:try...catch 格式: try{ 可能出现异常的代码; }catch(异常类名 对象名){ 异常的处理代码; }
执行流程:程序从try开始执行,执行到哪里出现了问题,就会跳转到catch里面执行。执行完毕后,程序还能继续往下执行。 public void printStackTrace():把异常的错误信息输出到控制台。 在实际开发中,遇见异常会给出一个页面进行提示,我们暂时用printStackTrace来处理。
比较常用的格式: try{ 可能出现异常的代码; }catch(异常类名 对象名){ 异常的处理代码; } ... }catch(Exception e){//这一段catch代码要加载最后,用来接我们还未发现的异常 System.out.println("各种异常"); e.printStackTrace(); }
(2)方案2:throws 我们通过try...catch可以对异常进行处理了,但是并不是所有的时候,我们都有权限进行异常处理。也就是说,有些时候我们处理不了,但是这个时候异常是存在的,不处理也行,怎么办呢? 这个时候,java就提供了throws的处理方案。 格式: throws 异常类名 注意这个格式必须跟在方法的括号的后面,在方法定义的后面 ...method(...) throws Exception{...} 注意:编译时异常是必须要处理的,两种方案:try...catch或者throws。如果采用了throws这种方案,将来谁调用,还得进行处理。运行时异常可以不用处理,出现问题后,我们需要回来修改代码。
5.什么时候用try...catch,什么时候用throws? 正常情况下,出现异常要给用户一些提示,什么地方出现了问题。但是,不是每个方法里都可以和用户沟通。一般和用户沟通会有一个页面,但不是每个类都能弹出这个页面。 工具类的用throws,main或页面上的用try...catch。因为:工具类它只负责处理一些经常用的功能,它没有页面,不能和用户沟通,它的方法里如果出现异常,只能抛出throws。页面上、main这些可以和用户沟通的页面,可以对异常进行捕获try...catch,然后给用户一个友好的提示。
二、File类 所在包:java.io.File File类是文件和目录路径名的抽象表示形式。也就是说,文件和目录是可以通过File封装成对象的。目录其实就是文件夹。 1.File构造方法 File(String pathname);//通过将给定 路径名 字符串 转换为 抽象路径名,来创建一个新File实例。 File(String parent, String child);//根据parent路径名 字符串和child路径名 字符串 创建一个新File实例。String parent必须是路径名 File(File parent, String child);//根据parent抽象路径名和child路径名 字符串创建一个File实例。 代码举例:把d:\\a\\b.txt转换为File对象 File f1 = new File("d:\\a\\b.txt"); File f2 = new File("d:\\a", "b.txt"); File f3 = new File("d:\\a"); File f4 = new File(f3, "b.txt");
2.File类的创建功能 public boolean createNewFile();//创建文件。如果文件不存在,创建文件并返回true;如果文件存在,创建文件失败,并返回false。 public boolean mkdir();//创建目录。如果目录不存在,创建目录并返回true;如果目录存在,创建目录失败,并返回false。 public boolean mkdirs();//创建多级目录 代码: //在d盘目录下创建一个文件ee\f.txt File f1 = new File("d:\\ee"); File f2 = new File("d:\\ee\\f.txt"); f1.mkdir(); f2.createNewFile();//throws IOException
3.File类的删除功能 public boolean delete();//删除文件和目录 File f1 = new File("a.txt"); f1.createNewFile(); 注意:如果一个目录中有内容(目录或文件),就不能直接删除,要先删除目录或文件,再删除。即只能删除空目录。 绝对路径:是以盘符开始的路径。 相对路径:不以盘符开始,相对于当前的项目而言,在项目的目录下。
4.File类的判断和获取功能 判断功能: public boolean isDirectory();//判断是否是目录 public boolean isFile();//判断是否是文件 public boolean exists();//判断是否存在 获取功能: public String getAbsolutePath();//获取绝对路径 public String getPath();//获取相对路径 public String getName();//获取名称,文件全名+扩展名
5.代码示例: File file = new File("aa/bb/cc/a.txt"); file.getParent();//返回文件的父路径,以字符串的形式返回 File parentFile = file.getParentFile();//返回文件的父路径,以文件的形式返回 parentFile.mkdirs(); file.createNewFile(); File dir = new File("aa/bb/cc"); File[] listFiles = dir.listFiles();//获取目录下所有的文件,以文件的形式返回 for(File file : listFiles){ System.out.println(file.getName()); } String[] list = dir.list();//获取目录下所有的文件,以字符串的形式返回 for(String s : list){ System.out.println(s); }
三、IO流 (一)基本概念 IO流是用来处理设备间的数据传输问题。 数据流向:站在java程序的角度来看数据流向。从硬盘、文件读数据到java程序里,是输入流;从java程序里写数据到硬盘、文件,是输出流。 数据类型:分为字节流、字符流(字符流数据是通过记事本notepad.txt打开后可以读懂的数据) IO流常见的应用:文件复制、文件上传、文件下载 IO流分类: A.按照数据流向分:输入流、输出流 B.按照操作类型分:字节流、字符流
(二)字节流写数据 1.都是抽象基类 字节流: InputStream 字节输入流 OutputStream 字节输出流(此抽象类是表示输出字节流的所有类的超类) 字符流: Reader 字符输入流 Writer 字符输出流 字节流写数据outputStream,它的子类FileOutputStream文件输出流是用于将数据写入File
2.构造方法 FileOutputStream(String name);//创建一个向具有指定名称的文件中写入数据的输出文件流 //创建字节输出流对象,throws FileNotFoundException FileOutputStream fos = new FileOutputStream("a.txt");//如果文件不存在,它会帮我们创建一个文件。如果文件存在,它会把文件内容清空。 创建字节输出流对象做了这样的三件事情: A.调用系统功能创建了a.txt文件 B.调用写数据的方法 C.释放资源 fos.write(65);//wite(int b) 写到文件里的是65,是文本阅读器把65转成了A fos.write(66); fos.close();//关闭此文件输出流,并释放与此流有关的所有系统资源
3.字节流写数据的步骤: A.创建字节输出流对象 B.调用写数据的方法 C.释放资源
4.构造方法 FileOutputStream(String name); throws FileNotFoundException FileOutputStream(File file); 代码示例: FileOutputStream fos = new FileOutputStream("b.txt"); FileOutputStream fos = new FileOutputStream(new File("b.txt")); fos.write(65);
5.写字节 throws IOException public void write(int b);//一次写一个字节 public void write(byte[] b, int off, int len);//一次写一个字节数组的一部分,off表示指定位置开始,len表示写几个字节 public void write(byte[] b);//一次写一个字节数组 代码示例: byte[] bys = {65,66,67,68,69}; fos.write(bys);//ABCDE //String类中的方法 String::public byte[] getBytes();把一个字符串转换为字符数组 fos.write("ABCDE".getBytes()); fos.write("ABCDE".getBytes(), 0, 3);//ABC
6.字节流写数据的常见问题 A.如何实现数据的换行? 不同的操作系统针对换行的符号识别是不一样的。 Windows: \r\n Linux: \n Mac: \r 加入换行符的代码示例: FileOutputStream fos = new FileOutputStream("c.txt"); for(int i = 0; i < 10; i++){ fos.write("hello".getBytes()); //加入换行符号 fos.write("\r\n".getBytes()); } fos.close();
B.如何实现数据的追加写入? 用构造方法带第二个参数是true的情况即可 FileOutputStream(String name, boolean append); 如果第二个参数为true,则将字节写入文件末尾处,而不是写入文件开始处。
7.字节流写数据加入异常处理 方法一:分开做异常处理(太繁琐) 方法二:放在一起做异常处理。这种方式代码虽然简洁了,但是释放资源的动作可能未执行到 方法三:try-catch-finally 代码: FileOutputStream fos = null; try{ fos = new FileOutputStream("d:\\d.txt");//如果操作系统没有d:这个盘符,就不会成功创建对象,fos就为null。 fos.write("hello".getBytes()); }catch(IOException e){ e.printStackTrace(); }finally{ if(fos != null){ try{ //释放资源 fos.close();//null调用方法,就会出异常 }catch(IOException e){ e.printStackTrace(); } } }
(三)字节流读数据InputStream FileInputStream 从文件系统中的某个文件中获得输入字节 1.构造方法 FileInputStream(String name); 代码示例: FileInputStream fis = new FileInputStream("a.txt"); int by; while((by = fis.read()) != -1){//读到文件的结尾,会返回-1 System.out.println((char)by);//一次读取一个字节 } fis.close();//释放资源
2.字节流读数据的步骤: A.创建字节输入流对象 B.调用读数据的方法 C.释放资源
3.字节流读数据 方式一:public int read();//一次读取一个字节,如果已经到达文件末尾,则返回-1 方式二:public int read(byte[] b);//一次读取一个字节数组。从此输入流中将最多b.length个字节的数据读入一个byte数组中,返回值是读入缓冲区的字节总数,也就是实际的读取个数,如果已经到达文件末尾,则返回-1。 代码示例: //String::public String(byte[] bytes); //String::public String(byte[] bytes, int offset, int length); byte[] bys = new byte[1024];//1024或1024的整数倍。因为1024byte=1M int len; while((len = fis.read(bys)) != -1){ System.out.print(new String(bys, 0, len));//不用println(),因为文件里有换行符 } fis.close();
4.IO字节流的练习题 练习题1: 题目描述:文件复制,其实就是从一个文件中读数据(数据源),然后把数据写到另一个文件中(目的地)。 数据源:d:\\窗里窗外.txt -->读数据-->InputStream-->FileInputStream 目的地:林青霞.txt -->写数据-->OutputStream-->FileOutputStream 代码: //封装数据源 FileInputStream fis = new FileInputStream("d:\\窗里窗外.txt"); //封装目的地 FileOutputStream fos = new FileOutputStream("林青霞.txt"); //读写数据 //方式1:一次读取一个字节 int by; while((by = fis.read()) != -1){ fos.write(by); } //方式2:一次读取一个字节数组 byte[] bys = new byte[1024]; int len; while((len = fis.read(bys)) != -1){ fos.write(bys, 0, len); } //释放资源 fos.close(); fis.close();
练习题2: 题目描述:复制图片文件 数据源:d:\\mn.jpg -->读数据-->FileInputStream 目的地:mn.jpg -->写数据-->FileOutputStream 代码: //封装数据源 FileInputStream fis = new FileInputStream("d:\\mn.jpg"); //封装目的地 FileOutputStream fos = new FileOutputStream("mn.jpg"); //读写数据 byte[] bys = new byte[1024]; int len; while((len = fis.read(bys)) != -1){ fos.write(bys, o, len); } //释放资源 fos.close(); fis.close();
(四)字节缓冲区流 字节流一次读写一个数组的速度比一次读写一个字节的速度快很多,这是加了数组这样的缓冲区效果。所以java提供了字节缓冲区流。 1. BufferedOutputStream: 字节缓冲输出流 BufferedInputStream: 字节缓冲输入流
2.构造方法 BufferedOutputStream(OutputStream out); 使用这种构造方法,它提供了一个默认的缓冲区大小,所以一般我们使用默认的缓冲区就可以了。 为什么构造方法传递的是一个OutputStream,而不是具体的文件或路径呢?因为字节缓冲区流仅仅提供缓冲区,而真正的底层的读写数据还得需要基本的流对象进行操作。 代码示例: FileOutputStream fos = new FileOutputStream("a.txt"); BufferedOutputStream bos = new BufferedOutputStream(fos); 上述两行代码等价于:BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("a.txt")); bos.close();//释放资源
3.写数据 bos.write(65);//写一个字节 bos.write("abcdefg".getBytes());//写一个字节数组 bos.write("abcdefg".getBytes(), 0, 4);//写一个字节数组的一部分
4.构造方法 BufferedInputStream(InputStream in); 代码示例: BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt")); 读取方式1:一次读取一个字节 int by; while((by = bis.read()) != -1){ System.out.print((char)by); } 读取方式2:一次读取一个字节数组 int len; byte[] bys = new byte[1024]; while((len = bis.read(bys)) != -1){ System.out.print(new String(bys, 0, len)); } //释放资源 bis.close();
5.字节流复制文件的效率 System类的public static long currentTimeMillis();//返回以毫秒为单位的当前时间 long start = System.currentTimeMillis();//记录开始时间 ...//待测试效率的代码,如:methodA() long end = System.currentTimeMillis();//记录结束时间 共耗时 = end - start;//毫秒 设计四个方案: 方案A:基本字节流,一次读写一个字节 方案B:基本字节流,一次读写一个字节数组 方案C:缓冲字节流,一次读写一个字节(要求记住) 方案D:缓冲字节流,一次读写一个字节数组(要求记住) 代码: //方案A:基本字节流,一次读写一个字节 private static void methodA() throws IOException{ //封装数据源 FileInputStream fis = new FileInputStream("d:\\复制图片.avi"); //封装目的地 FileOutputStream fos = new FileOutputStream("copy.avi"); int by; while((by = fis.read()) != -1){ fos.write((char)by); } fos.close(); fis.close(); }
//方案B:基本字节流,一次读写一个字节数组 private static void methodB() throws IOException{ //封装数据源 FileInputStream fis = new FileInputStream("d:\\复制图片.avi"); //封装目的地 FileOutputStream fos = new FileOutputStream("copy.avi"); byte[] bys = new byte[1024]; int len; while((len = fis.read(bys)) != -1){ fos.write(bys, 0, len); } fos.close(); fis.close(); }
//方案C:缓冲字节流,一次读写一个字节(要求记住) private static void methodC() throws IOException{ //封装数据源 BufferedInputStream bis = new BufferedInputStream(new FileInputStream("d:\\复制图片.avi")); //封装目的地 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.avi")); int by; while((by = bis.read()) != -1){ bos.write((char)by); } bos.close(); bis.close(); }
//方案D:缓冲字节流,一次读写一个字节数组(要求记住) private static void methodD() throws IOException{ //封装数据源 BufferedInputStream bis = new BufferedInputStream(new FileInputStream("d:\\复制图片.avi")); //封装目的地 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.avi")); byte[] bys = new byte[1024]; int len; while((len = bis.read(bys)) != -1){ bos.write(bys, 0, len); } bos.close(); bis.close(); }
// (五)转换流 转换流=字节流+编码表 1.转换流出现的原因:因为字节流操作字符文件的时候,可能会出现乱码问题。 2.字节流读数据可能出现的问题:字节流一次读取一个字节的方式读取带有汉字的文件是有问题的。因为你读取到一个字节后,就转为字符在控制台输出了,而汉字是由2个字节组成的,所以这里会出问题。 3.文件复制的时候,字节流读取一个字节,写入一个字节,这个没有出现问题,是因为最终底层会根据字节做拼接,得到汉字。 4.汉字存储的规则:左边的字节数据肯定是负数,右边的字节数据可能是负数,也可能是正数,大部分情况下是负数。 代码示例: String s1 = "hello"; String s2 = "你好"; byte[] bys1 = s1.getBytes();//[104,101,108,111] byte[] bys2 = s2.getBytes();//[-60,-29,-70,-61] System.out.println(Arrays.toString(bys1)); System.out.println(Arrays.toString(bys2)); 创建一个输出流后,如果文件不存在,它会创建一个文件。如果文件存在,它会把文件清空。因为BufferedInputStream和BufferedOutputStream不能共用同一个文件。
(六)编码表概述和常见的码表 1.编码表:由字符和对应的数据组成的一张表。 2.常见的编码表 ASCII:一个字节的7位表示数据,美国标准码表 ISO-8859-1:欧洲码表,一个字节的8位表示数据,兼容ASCII GB2312:中文码表,兼容ASCII GBK:中文码表的升级版,更多中文字符,兼容ASCII UTF-8:可变长度的字符编码,用1-3个字节表示数据,又叫万国码表,兼容ASCII。用在网页上可以统一页面中的中文简体、繁体和其他语言的显示。
3.乱码问题:针对同一个数据,采用的编码和解码的编码不一致造成的。 为了不出现乱码的问题,要保证编码和解码采用统一的编码表。
(七)字符串中的编码、解码问题 1.编码: public byte[] getBytes(String charsetName) throws UnSupportedEncodingException;//使用指定的字符集将此String编码为byte序列,并将结果存储到一个新的byte数组中。默认编码为GBK。 String::public byte[] getBytes();//使用平台默认的编码表来编码 2.解码 String::public String(byte[] bytes, String charsetName);//通过使用指定的charset解码指定的byte数组,构造一个新的String String::public String(byte[] bytes);//使用平台默认的编码表来解码 3.代码示例: String s = "苍老师"; byte[] bys = s.getBytes("UTF-8");//编码 System.out.println(Arrays.toString(bys)); String s2 = new String(bys, "UTF-8");//解码 System.out.println(s2);
(八)转换流的编码、解码 1.转换流其实就是一个字符流 转换流=字节流+编码表
2.字符输出流OutputStreamWriter: public OutputStreamWriter(OutputStream out);//根据默认编码把字节流转换为字符流 public OutputStreamWriter(OutputStream out, String charsetName);//根据指定编码,把字节流数据转换为字符流 代码示例: OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt")); OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt"), "UTF-8"); osw.write("你好");//调用写数据的方法 osw.close();//释放资源
3.OutputStreamWriter写数据的方法 public void write(int c);//写一个字符 public void write(char[] cbuf);//写一个字符数组 public void write(char[] cbuf, int offSet, int len);//写一个字符数组的一部分 public void write(String str);//写一个字符串 public void write(String str, int offSet, int len);//写一个字符串的一部分 写完数据后,没有发现数据,为什么呢?因为需要手动刷缓冲。 字符流写数据需要手动刷新缓冲。void flush()刷新该流的缓冲。close()方法在关闭流之前,先做了刷新缓冲的动作。 1字符=2字节 文件中的数据存储的基本单位是字节。 代码示例: OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("a.txt"), "UTF-8"); osw.write("我爱苍老师".toCharArray());//把字符串转成字符数组 String::char[] toCharArray() 将此字符串转换为一个新的字符数组 osw.write("我爱苍老师".toCharArray(), 0, 2); osw.write("我爱苍老师"); osw.write("我爱苍老师", 0, 2);
4.字符输入流InputStreamReader public InputStreamReader(InputStream in);//用默认的编码读数据 public InputStreamReader(InputStream in, String charsetName);//用指定的编码读数据 代码示例: InputStreamReader isr = new InputStreamReader(new FileInputStream("osw.txt"), "UTF-8"); //读数据,一次读取一个字符数据 int ch; while((ch = isr.read()) != -1){ System.out.print((char)ch); } isr.close();//释放资源
5.InputStreamReader读数据的方法 public int read();//一次读取一个字符 public int read(char[] cbuf);//一次读取一个字符数组 代码示例: InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"), "UTF-8"); //方式1:一次读取一个字符 int by; while((by = isr.read()) != -1){ System.out.print((char)by); } //方式2:一次读取一个字符数组 char[] chs = new char[1024]; int len; while((len = isr.read(chs)) != -1){ System.out.print(new String(chs, 0, len));//String::public String(byte[] bytes, int offset, int length); } //释放资源 isr.close();
6.练习题:把当前项目目录下的StringDemo.java内容复制到当前项目目录下的copy.java中。 数据源:StringDemo.java -->读数据-->字符流-->InputStreamReader 目的地:copy.java -->写数据-->字符流-->OutputStreamWriter //封装数据源 InputStreamReader isr = new InputStreamReader(new FileInputStream("StringDemo.java")); //封装目的地 OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("copy.java")); //读写数据 //方式1:一次读写一个字符 int ch; while((ch = isr.read()) != -1){ osw.write(ch); } //方式2:一次读写一个字符数组 char[] chs = new char[1024]; int len; while((len = isr.read(chs)) != -1){ osw.write(chs, 0, len); } //释放资源 osw.close(); isr.close();
(九)转换流的子类FileWriter, FileReader 转换流的名字比较长,而我们常见的操作都是按照本地默认编码实现的,所以为了简化书写,转换流提供了对应的子类。 1.FileWriter, FileReader FileWriter extends OutputStreamWriter 用来写入字符文件的便捷类 FileReader extends InputStreamReader 用来读取字符文件的便捷类 OutputStreamWriter = FileOutputStream + 编码表 FileWriter = FileOutputStream + 编码表 InputStreamReader = FileInputStream + 编码表 FileReader = FileInputStream + 编码表
2.构造方法 FileWriter(String fileName); FileReader(String fileName); 代码示例: //封装数据源 FileReader fr = new FileReader("StringDemo.java"); //封装目的地 FileWriter fw = new FileWriter("copy.java"); //读写数据 //方法1 int ch; while((ch = fr.read()) != -1){ fw.write(ch); } //方法2 char[] chs = new char[1024]; int len; while((len = fr.read(chs)) != -1){ fw.write(chs, 0, len); } //释放资源 fw.close(); fr.close();
(十)字符缓冲区流BufferedWriter,BufferedReader 1.BufferedWriter: 将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。 可以指定缓冲区的大小,或者接受默认的大小。在大多数情况下,默认值就足够大了。 构造方法: BufferedWriter(Writer out);//Creates a buffered character-output stream that uses a default-sized output buffer. BufferedWriter(Writer out, int sz);//Creates a new buffered character-output stream that uses an output buffer of the given size. 写数据的方法: void newLine();//Writes a line separator. void write(char[] cbuf, int off, int len);//Writes a portion of an array of characters. void write(int c);//Writes a single character. void write(String s, int off, int len);//Writes a portion of a String.
2.BufferedReader: 从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。 可以指定缓冲区的大小,或者接受默认的大小。在大多数情况下,默认值就足够大了。 构造方法: BufferedReader(Reader in);//Creates a buffering character-input stream that uses a default-sized input buffer. BufferedReader(Reader in, int sz);//Creates a buffering character-input stream that uses an input buffer of the specified size. 读数据的方法: int read();//Reads a single character. int read(char[] cbuf, int off, int len);//Reads characters into a portion of an array. String readLine();//Reads a line of text.
3.代码示例: //创建字符缓冲输出流对象 BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt")); //调用写数据的方法 bw.write("Hello"); //释放资源 bw.close();
//创建字符缓冲输入流对象 BufferedReader br = new BufferedReader(new FileReader("1.java")); //方式1:一次读取一个字符 int ch; while((ch = br.read()) != -1){ System.out.print((char)ch); } //方式2:一次读取一个字符数组 char[] chs = new char[1024]; int len; while((len = br.read(chs)) != -1){ System.out.print(new String(chs, 0, len)); } //释放资源 br.close();
4.练习题 题目描述:字符缓冲区流复制文件,把a.txt内容复制到b.txt中。 数据源:a.txt -->读数据-->字符流-->InputStreamReader-->FileReader-->BufferedReader 目的地:b.txt -->写数据-->字符流-->OutputStreamWriter-->FileWriter-->BufferedWriter 代码: //封装数据源 BufferedReader br = new BufferedReader(new FileReader("a.txt")); //封装目的地 BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt")); //读写数据 //一次读写一个字符数组 char[] chs = new char[1024]; int len; while((len = br.read(chs)) != -1){ bw.write(chs, 0, len); } //释放资源 bw.close(); br.close();
5.特殊功能--换行功能 BufferedWriter::void newLine();//写入一个行分隔符,分隔符由系统属性决定。 BufferedReader::String readLine();//包含该行内容的字符串,不包含任何终止符。如果已到达流末尾,则返回null。即不读换行符。所以要自己换行System.out.println(); 代码示例: //创建字符缓冲输出流对象 BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt")); //写数据 for(int i = 0; i < 3; i++){ bw.write("Hello"); //bw.write("\r\n"); bw.newLine(); bw.flush(); } //释放资源 bw.close();
//创建字符缓冲输入流对象 BufferedReader br = new BufferedReader(new FileReader("bw.txt")); String line; while((line = br.readLine()) != null){ System.out.println(line); } //释放资源 br.close();
6.练习题 题目描述:用字符缓冲区流的换行功能复制文件 数据源:a.java -->BufferedReader 目的地:b.java -->BufferedWriter 代码: //封装数据源 BufferedReader br = new BufferedReader(new FileReader("a.txt")); //封装目的地 BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt")); String line; while((line = br.readLine()) != null){ bw.write(line); bw.newLine(); bw.flush(); } //释放资源 bw.close(); br.close();
(十一)IO流总结(重点) 1.字节流 FileInputStream fis = new FileInputStream("a.txt"); FileOutputStream fos = new FileOutputStream("b.txt");
2.字节缓冲流 BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt")); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("b.txt"));
3.转换流 InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"), "UTF-8"); OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("b.txt"), "UTF-8");
4.字符流 FileReader fr = new FileReader("1.java"); FileWriter fw = new FileWriter("2.java");
5.字符缓冲流 BufferedReader br = new BufferedReader(new FileReader("1.java")); BufferedWriter bw = new BufferedWriter(new FileWriter("2.java"));
(十二)IO流的一些练习题 练习题1:字符流复制文本文件 一共有5种方式: A.基本字符流一次读写一个字符串 B.基本字符流一次读写一个字符数组 C.缓冲字符流一次读写一个字符 D.缓冲字符流一次读写一个字符数组 E.缓冲字符串一次读写一个字符串 代码: //A.基本字符流一次读写一个字符串 private static void methodA() throws IOException{ FileReader fr = new FileReader("d:\\林青霞.txt"); FileWriter fw = new FileWriter("窗里窗外.txt"); int ch; while((ch = fr.read()) != -1){ fw.write((char)ch); } fw.close(); fr.close(); }
//B.基本字符流一次读写一个字符数组 private static void methodB() throws IOException{ FileReader fr = new FileReader("d:\\林青霞.txt"); FileWriter fw = new FileWriter("窗里窗外.txt"); char[] chs = new char[1024]; int len; while((len = fr.read(chs)) != -1){ fw.write(chs, 0, len); } fw.close(); fr.close(); }
//C.缓冲字符流一次读写一个字符 private static void methodC() throws IOException{ BufferedReader br = new BufferedReader(new FileReader("d:\\林青霞.txt")); BufferedWriter bw = new BufferedWriter(new FileWriter("窗里窗外.txt")); int ch; while((ch = br.read()) != -1){ bw.write((char)ch); } bw.close(); br.close(); }
//D.缓冲字符流一次读写一个字符数组 private static void methodD() throws IOException{ BufferedReader br = new BufferedReader(new FileReader("d:\\林青霞.txt")); BufferedWriter bw = new BufferedWriter(new FileWriter("窗里窗外.txt")); char[] chs = new char[1024]; int len; while((len = br.read(chs)) != -1){ bw.write(chs, 0, len); } bw.close(); br.close(); }
//E.缓冲字符串一次读写一个字符串 private static void methodE() throws IOException{ BufferedReader br = new BufferedReader(new FileReader("d:\\林青霞.txt")); BufferedWriter bw = new BufferedWriter(new FileWriter("窗里窗外.txt")); String line; while((line = br.readLine()) != null){ bw.write(line); bw.writeLine(); bw.flush(); } bw.close(); br.close(); }
练习题2:把ArrayList集合中的字符串数据存储到文本文件,每一个字符串元素作为文件中的一行数据 分析: A.创建集合对象 B.往集合中添加字符串对象 C.创建字符缓冲输出流对象 D.遍历集合,得到每一个字符串元素,把字符串元素作为数据写到文本文件 E.释放资源 代码: //创建集合对象 ArrayList<String> array = new ArrayList<String>(); //往集合中添加字符串元素 array.add("hello"); array.add("world"); array.add("Java"); //创建字符缓冲输出流对象 BufferedWriter bw = new BufferedWriter(new FileWriter("array.txt")); //遍历集合,得到每一个字符串元素,把字符串元素作为数据写入到文本文件 for(String s : array){ bw.write(s); bw.newLine(); bw.flush(); } //释放资源 bw.close();
练习题3:从文本文件中读取数据到ArrayList集合中,并遍历集合,每一行数据作为一个字符串元素。 分析: A.创建字符缓冲输入流对象 B.创建集合对象 C.读取数据,每一次读取一行,并把该数据作为元素存储到集合中 D.释放资源 E.遍历集合 代码: //创建字符缓冲输入流对象 BufferedReader br = new BufferedReader(new FileReader("array.txt")); //创建集合对象 ArrayList<String> array = new ArrayList<String>(); //读取数据,每一次读取一行,并把该数据作为元素存储到集合中 String line; while((line = br.readLine()) != null){ array.add(line); } //释放资源 br.close(); //遍历集合 for(String s : array){ System.out.println(s); }
练习题4:把ArrayList集合中的学生数据存储到文本文件,每一个学生数据作为文件中的一行数据 分析: A.创建集合对象 B.创建学生对象 C.把学生对象添加到集合中 D.创建字符缓冲输出流对象 E.遍历集合,得到每一个学生对象,然后把该对象的数据拼接成一个指定格式的字符串,写到文本文件 F.释放资源 代码: //创建集合对象 ArrayList<Student> array = new ArrayList<Student>(); //创建学生对象 Student s1 = new Student("it001", "林青霞", 30, "北京"); Student s2 = new Student("it002", "张曼玉", 35, "东京"); Student s3 = new Student("it003", "王祖贤", 33, "纽约"); //把学生对象添加到集合中 array.add(s1); array.add(s2); array.add(s3); //创建字符缓冲输出流对象 BufferedWriter bw = new BufferedWriter(new FileWriter("students.txt")); //遍历集合,得到每一个学生对象 for(Student s : array){ StringBuilder sb = new StringBuilder(); sb.append(s.getSid()).append(", ").append(s.getName()).append(", ").append(s.getAge()).append(", ").append(s.getCity());//it001, 林青霞, 30, 北京 bw.write(sb.toString()); bw.newLine(); bw.flush(); } //释放资源 bw.close();
练习题5:从文本文件中读取学生数据到ArrayList集合中,并遍历集合,每一行数据作为一个学生元素。这里要使用String类中的方法split()。 分析: A.创建字符缓冲输入流对象 B.创建集合对象 C.读取数据,每一次读取一行数据,把该行数据想办法封装成学生对象,并把学生对象存储到集合中 D.释放资源 E.遍历集合 代码: //创建字符缓冲输入流对象 BufferedReader br = new BufferedReader(new FileReader("students.txt")); ArrayList<Student> array = new ArrayList<Student>(); //读取数据,每一次读取一行数据 String line; while((line = br.readLine()) != null){it001, 林青霞, 30, 北京 String[] strArray = line.split(", "); Student s = new Student(); s.setSid(strArray[0]); s.setName(strArray[1]); s.setAge(Integer.parseInt(strArray[2])); s.setCity(strArray[3]); array.add(s); } //释放资源 br.close(); //遍历集合 for(Student s : array){ System.out.println(s.getSid() + ", " + s.getName() + ", " + s.getAge() + ", " + s.getCity()); }
====