- IO
- 概述
IO流简单来说就是Input和Output流,IO流主要是用来处理设备之间的数据传输,Java对于数据的操作都是通过流实现,而java用于操作流的对象都在IO包中。
分类:
按操作数据分为:字符流(bit)和字节流(Byte)。 如:Reader和InpurStream
按流向分:输入流和输出流。如:InputStream和OutputStream
IO流常用的基类:
* InputStream ,OutputStream(字节流)
字符流的抽象基类:
* Reader ,Writer
由上面四个类派生的子类名称都是以其父类名作为子类的后缀:
如:FileReader和FileInputStream
- 字符流
- 简介
* 字符流中的对象融合了编码表,也就是系统默认的编码表。我们的系统一般都是GBK编码。
* 字符流只用来处理文本数据,字节流用来处理媒体数据。
* 数据最常见的表现方式是文件,字符流用于操作文件的子类一般是FileReader和FileWriter。
-
- 读写
注意事项:
* 写入文件后必须要用flush()刷新。
* 用完流后记得要关闭流
* 使用流对象要抛出IO异常
* 定义文件路径时,可以用“/”或者“\\”。
* 在创建一个文件时,如果目录下有同名文件将被覆盖。
* 在读取文件时,必须保证该文件已存在,否则出异常
IO流的类层次图:
- 例子:将F盘已有的一个文件复制到D盘,见实战
- 字符流的缓冲区:BufferedReader和BufferedWreiter
a. 简介
* 缓冲区的出现是为了提高流的操作效率而出现的.
* 需要被提高效率的流作为参数传递给缓冲区的构造函数
* 在缓冲区中封装了一个数组,存入数据后一次取出
b. BufferedWriter 示例:
读取流缓冲区提供了一个一次读一行的方法readline,方便对文本数据的获取。
readline()只返回回车符前面的字符,不返回回车符。如果是复制的话,必须加入newLine(),写入回车符,newLine()是java提供的多平台换行符写入方法。缓冲区也是要刷新和关闭的:
FileWriter fw = new FileWriter("buf.txt");
//为了提高字符写入效率,加入了缓冲技术。
//只要将需要被提高效率的流作为参数传递给缓冲区的构造函数即可
BufferedWriter bfw = new BufferedWriter(fw);
for(int x = 1; x < 5; x++) {
bfw.write("abc");
bfw.newLine(); //java提供了一个跨平台的换行符newLine();
bfw.flush();
}
bfw.flush(); //刷新缓冲区
bfw.close(); //关闭缓冲区,但是必须要先刷新
//注意,关闭缓冲区就是在关闭缓冲中的流对象
fw.close(); //关闭输入流对象
- 字节流
- 概述:
1、字节流和字符流的基本操作是相同的,但是要想操作媒体流就需要用到字节流。
2、字节流因为操作的是字节,所以可以用来操作媒体文件。(媒体文件也是以字节存储的)
3、读写字节流:InputStream 输入流(读)和OutputStream 输出流(写)
4、字节流操作可以不用刷新流操作。
5、InputStream特有方法:int available();//返回文件中的字节个数
注:可以利用此方法来指定读取方式中传入数组的长度,从而省去循环判断。但是如果文件较大,而虚拟机启动分配的默认内存一般为64M。当文件过大时,此数组长度所占内存空间就会溢出。所以,此方法慎用,当文件不大时,可以使用。
例子:复制一张图片F:\1.BMP到F:\ 2.bmp 见实战
字节流缓冲区(BufferedOutputStream BufferedInputStream )
简介
* 字节流缓冲区跟字符流缓冲区一样,也是为了提高效率。
注意事项:
1. read():会将字节byte()提升为int型值
2. write():会将int类型转换为byte()类型,保留最后的8位。
例子:复制MP3文件 1.MP3 --> 2.MP3,自己写一个MyBufferedInputStream缓冲类,提升复制速度 见实战
- 流
- 键盘读取,控制台打印
System.out: 对应的标准输出设备:控制台 //它是PrintStream对象,(PrintStream:打印流。OutputStream的子类)
System.in: 对应的标准输入设备:键盘 //它是InputStream对象
例子:
/*================从键盘录入流,打印到控制台上================*/
public static void InOutDemo(){
//键盘的最常见的写法
BufferedReader bufr = null;
BufferedWriter bufw = null;
try {
/*InputStream ips = System.in; //从键盘读入输入字节流
InputStreamReader fr = new InputStreamReader(ips); //将字节流转成字符流
bufr = new BufferedReader(fr); */ //将字符流加强,提升效率
bufr = new BufferedReader(new InputStreamReader(System.in)); //匿名类。InputSteamReader:读取字节并将其解码为字符
bufw = new BufferedWriter(new OutputStreamWriter(System.out)); //OutputStreamWriter:要写入流中的字符编码成字节
String line = null;
while((line = bufr.readLine())!=null){
if("over".equals(line)) break;
bufw.write(line.toUpperCase()); //打印
bufw.newLine(); //为了兼容,使用newLine()写入换行符
bufw.flush(); //必须要刷新。不然不会显示
}
if(bufw!=null) {
bufr.close();
bufw.close();
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
我们在键盘录入的是时候,read()方法是一个一个录入的,能不能整行的录入呢?这时候我们想到了BufferedReader中ReadLine()方法。
为了让字节流可以使用字符流中的方法,我们需要转换流。
- InputStreamReader:字节流转向字符流;
- 获取键盘录入对象。
InputStream in=System.in;
- 将字节流对象转成字符流对象,使用转换流。
InputStreamReader isr=new InputStreamReader(in);
- 为了提高效率,将字符串进行缓冲区技术高效操作。使用BufferedReader
BufferedReader br=new BufferedReader(isr);
//键盘录入最常见写法
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
-
- OutputStreamWriter:字符流通向字节流
示例:
/*================把键盘录入的数据存到一个文件中==============*/
public static void inToFile() {
//键盘的最常见的写法
BufferedReader bufr = null;
BufferedWriter bufw = null;
try {
/*InputStream ips = System.in; //从键盘读入输入字节流
InputStreamReader fr = new InputStreamReader(ips); //将字节流转成字符流
bufr = new BufferedReader(fr); */ //将字符流加强,提升效率
bufr = new BufferedReader(new InputStreamReader(System.in)); //匿名类。InputSteamReader:读取字节并将其解码为字符
bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("out.txt"))); //OutputStreamWriter:要写入流中的字符编码成字节
String line = null;
while((line = bufr.readLine())!=null){
if("over".equals(line)) break;
bufw.write(line.toUpperCase()); //打印
bufw.newLine(); //为了兼容,使用newLine()写入换行符
bufw.flush(); //必须要刷新。不然不会显示
}
if(bufw!=null) {
bufr.close();
bufw.close();
}
}
catch (IOException e) {
e.printStackTrace();
}
}
如何确定用哪个类:
示例1:将一个文本文件中的数据存储到另一个文件中: 复制文件
一、明确体系
源:文件-->读取流-->(InputStream和Reader)
是否是文本:是-->Reader
目的:文件-->写入流-->(OutputStream Writer)
是否纯文本:是-->Writer
二、 明确设备
源:Reader
设备:硬盘上一个文本文件 --> 子类对象为:FileReader
FileReader fr = new FileReader("Goods.txt");
是否提高效率:是-->加入Reader中的缓冲区:BufferedReader
BufferedReader bufr = new BufferedReader(fr);
目的:Writer
设备:键盘上一个文本文件 --> 子类对象:FileWriter
FileWriter fw = new FileWriter("goods1.txt");
是否提高效率:是-->加入Writer的缓冲区:BufferedWriter
BufferedWriter bufw = new BufferedWriter(fw);
示例2:将一个图片文件数据复制到另一个文件中:复制文件
一、明确体系
源:文件-->读取流-->(InputStream和Reader)
是否是文本:否-->InputStream
目的:文件-->写入流-->(OutputStream Writer)
是否纯文本:否-->OutputStream
二、 明确设备
源:InputStream
设备:硬盘上一个媒体文件 --> 子类对象为:FileInputStream
FileInputStream fis = new FileInputStream("Goods.txt");
是否提高效率:是-->加入InputStream中的缓冲区:BufferedInputStream
BufferedInputStream bufi = new BufferedInputStream(fis);
目的:OutputStream
设备:键盘上一个媒体文件 --> 子类对象:FileOutputStream
FileOutputStream fos = new FileOutputStream("goods1.txt");
是否提高效率:是-->加入OutputStream的缓冲区:BufferedOutputStream
BufferedOutputStream bufo = new BufferedOutputStream(fw);
示例3:将键盘录入的数据保存到一个文本文件中
一、明确体系
源:键盘-->读取流-->(InputStream和Reader)
是否是文本:是-->Reader
目的:文件-->写入流-->(OutputStream Writer)
是否纯文本:是-->Writer
二、 明确设备
源:InputStream
设备:键盘 --> 对用对象为:System.in --> InputStream
为了操作方便,转成字符流Reader --> 使用Reader中的转换流:InputStreamReader
InputStreamReader isr = new InputStreamReader(System.in);
是否提高效率:是-->加入Reader中的缓冲区:BufferedReader
BufferedReader bufr = new BufferedReader(isr);
目的:Writer
设备:键盘上一个文本文件 --> 子类对象:FileWriter
FileWriter fw = new FileWriter("goods1.txt");
是否提高效率:是-->加入Writer的缓冲区:BufferedWriter
BufferedWriter bufw = new BufferedWriter(fw);
- 指定编码表(转换流可以指定编码表)
OutputStream.write(int)是以二进制的方法写文件的,用UTF-8编码存储一个文本件:
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("goods1.txt"),"UTF-8"));
如果不用BufferedWriter缓冲区的话,这个关闭了OutputStreamWriter后还要关闭FileOutputStream
注:
- 从键盘读取虽然是字符确定了Reader,但是因为system.in是inputStream的子类,所以要用new InputStreamReader(System.in)获得对象。
- System.out是PrintStream的对象,PrintStream是OutputStream的子类,所以也可以用write方法,但更常用的是print()和println()方法。
- 使用BufferedReader 的read() 方法从控制台读取一个字符,或者用 readLine() 方法读取一个字符串。每次调用 read() 方法,它从输入流读取一个字符并把该字符作为整数值返回。 当流结束的时候返回 -1。该方法抛出 IOException。
- 文件
- 单独创建文件时:
mkdir( )方法创建一个文件夹,成功则返回true,失败则返回false。失败表明File对象指定的路径已经存在,或者由于整个路径还不存在,该文件夹不能被创建。
mkdirs()方法创建一个文件夹和它的所有父文件夹。
String dirname = "/tmp/user/java/bin"; File d = new File(dirname); // 现在创建目录 d.mkdirs();
- 读取目录
一个目录其实就是一个 File 对象,它包含其他文件和文件夹。
如果创建一个 File 对象并且它是一个目录,那么调用 isDirectory() 方法会返回 true。
可以通过调用该对象上的 list() 方法,来提取它包含的文件和文件夹的列表。
- 删除目录或文件
删除文件可以使用 java.io.File.delete() 方法。需要注意的是当删除某一目录时,必须保证该目录下没有其他文件才能正确删除,否则将删除失败。(可以使用递归来删除文件夹及其下的子文件)