java学习笔记: 基础知识: day13,day14 异常、File类、IO流

====

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());
}

====

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值