IO流1
① IO简介
- IO流的概念
定义:Input-Output.程序运行时程序与外部系统进行通信的过程, 外部系统可能是文件, 数据库, 其它程序, 网络, IO设备等等.
Input: 可以让程序从外部系统获得数据(核心是"读", 读取外部的数据)
- 常见应用:
*读取硬盘上的文件内容到程序当中, 例如: 播放器打开一个视频文件, word打开一个doc文件
*读取网络上的某个位置的内容到程序. 例如: 浏览器9中输入网址后,打开对应的页面, 下载网络上某个网址的文件
*读取数据库系统的数据到程序
*读取某些硬件数据到程序. 例如: 车载电脑读取雷达扫描的信息到程序; 温控系统等.Output: 程序输出数据给外部系统(核心含义是"写", 将数据写入到外部系统)
- 常见应用:
*将数据写到硬盘中. 例如: 编辑完一个wrod后,将内容写道硬盘上进行保存.
*将数据写到数据库系统中. 例如: 注册一个网站会员, 实际就是向后台数据库写入一条记录.
*将数据写到某些硬件系统中. 例如: 导弹系统导航程序将心的路径输出到飞控子系统,飞控子系统根据数据修改飞行路径实现: 在java.io包中提供了相关的API, 实现了对所有的外部系统的输入输出操作.
数据源(Data Source):
是提供数据的原始媒介. 常见的数据源有: 数据库, 文件, 其它程序, 内存, 网络连接, io设备
数据源分为: --源设备 --目标设备
- 源设备: 为程序提供数据, 一般对应输入流
- 目标设备: 程序数据的目的地,一般对应输出流
IO流的概念
流是一个抽象的, 动态的概念, 是一连串连续动态的数据的集合
对于输入流:
- 数据源就像是水箱, 流(Stream)就像水管中的水流, 程序就是最终用户. 通过流(A Stream)将数据源(Source)中的数据(information)输送到程序当中.
对于输出流:
- 目标数据源就是目的地(dest), 我们通过流(A Stream)将程序(Program)中的数据(information)输送到数据源(dest)中.
> 注意: 输入与输出是相对程序来说的, 不是相对数据源的概念.
- Java中的四大IO抽象类
InputStream / OutputStream(字节流) 和 Reader / Writer(字符流)类是所有的IO流类的抽象父类.
InputStream:
- 该抽象类是字节输入流的所有类的父类, InputStream是一个抽象类,不可实例化. 它的所有功能都需要靠子实现类来实现. 根据节点的不同, 它派生出了不同的节点流子类.
- 继承自InputStream的流都是用于向程序中输入数据,且数据的单位为字节.
常用方法 | 说明 |
---|---|
int read() | 读取一个字节的数据, 并将字节的值作为int类型返回(0 - 255). 返回值为-1表示读取结束 |
void close() | 关闭输入流对象, 释放相关系统的资源 |
OutputStream:
- 该抽象类表示字节输出流的所有类的父类. 输出流接受字节数据,并将这些字节发送到某一个目的地
常用方法 | 说明 |
---|---|
void write(int n) | 向目的地中写入一个字节 |
void close() | 关闭输出流对象,释放相关系统资源 |
Reader:
Reader用于读取的字符流抽象类, 数据单位为字符
常用方法 | 说明 |
---|---|
int read() | 读取一个字符数据,将值作为int返回(0-65535 Unicode),返回-1结束 |
void close() | 关闭流对象, 释放相关系统资源 |
Writer:
writer是用于输出字符流的抽象类,数据单位为字符
常用方法 | 说明 |
---|---|
void writer(int n) | 向输入流中写入一个字符数据 |
void close() | 关闭输出流对象,释放相关系统资源 |
- Java中流概念的细分
按流的方向分类:
输入流: 数据流从数据源到程序(以InputStream, Reader结尾的流)
输出流: 数据流从程序到目的地(以OutputStream, Writer结尾的流)
按处理的数据单元分类:
字节流(读取二进制文件时): 以字节为单位获取数据,命名S上tream结尾的流一般是字节流, 如FileInputStream, FileOutputStream
字符流(读取文本形式的数据时): 以字符为单位获取数据, 命名上以Reader/Writer结尾的流,如FileReader, FileWriter按处理对象的不同分类:
节点流: 可以直接从数据源/目的地读写数据, 如FileInputStream, FileReader, DataInputStream等
处理流: 不直接链接到数据源或目的地,是"处理流的流",通过对其它流的处理提高程序的性能. 如BufferedInputStream, BufferedReader等, 处理流也叫包装流.节点流位于IO操作的第一线, 所有的操作必须通过它们进行; 处理流可以对节点流进行包装,提高性能或提高程序的灵活性.
-Java中IO流类的体系
- File: 不在IO体系中, File类能够对目录或文件进行包装. 将目录/文件包装成对象, 提供更多的对其进行操作的方式.
- RandomAccessFile: 随机访问流,不在IO体系当中. 只能对文件进行读写操作的随机访问.
- 四大抽象类:
汇总:
- InputStream/OutputStream: 字节流的抽象类
- Reader/Writer: 字符流的抽象类
- FileInputStream/FileOutputStream: 节点流: 以字节为单位直接操作"文件"
- ByteArrayInputStream/ByteArrayOutputStream:
节点流: 以字节为单位, 直接操作"字节数组对象"- ObjectInputStream/ObjectOutputStream:
处理流: 以字节为单位直接操作"对象"- DataInputStream/DataOutputStream:
处理流: 以字节为单位直接操作"基本数据类型与字符串类型"- FileReader/FileWriter:
节点流: 以字符为单位, 直接操作"文本文件"(只能读取文本文件)- BufferedReader/BufferedWriter:
处理流: 将Reader/Writer对象进行包装,增加缓存功能,提高读写效率- BufferedInputStream/BufferedOutputStream:
处理流: 将InputStream/OutputStream对象进行包装,增加缓存功能,提高读写效率.- InputStreamReader/OutputStreamWriter:
处理流: 将字节流对象转化成字符流对象.- PrintStream:
处理流: 将OutputStream进行包装, 方便的输出字符, 更加灵活.
② 入门案例
package com.IOLearning;
import java.io.FileInputStream;
import java.io.IOException;
public class SecondDemo {
public static void main(String[] args) {
FileInputStream fis = null;
try {
//创建字节输入流对象
fis = new FileInputStream("C:\\Users\\iFinder\\Desktop\\Java Learnning\\JavaSE\\src\\com\\IOLearning\\Test.txt");
StringBuilder sb = new StringBuilder();
int temp = 0;
while((temp = fis.read()) != -1){ //read()方法只获取一个字符,当文件内容读取完毕时read()方法返回-1
sb.append((char) temp);
}
System.out.println(sb.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
try{
if(fis != null){
fis.close(); //操作结束之后一定要关闭流对象
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
③ File类的使用
- File类的作用
Java提供的针对磁盘中文件或目录, 转化成对象的一个包装类. 一个File类可以代表一个问价或一个目录, File对象可以实现获取问价和目录属性等功能, 可以实现对文件和目录的创建, 删除等功能.
- File类的常用方法
针对文件的操作方法
方法 | 说明 |
---|---|
CreateNewFile() | 创建一个新文件 |
delete() | 直接从磁盘上删除 文件/目录 |
exists() | 查询磁盘中的文件是否存在 |
getAbsolutePath() | 获取绝对路径 |
getPath() | 获取相对路径 |
getName() | 获取文件名, 相当于调用了一个toString()方法 |
isFile() | 判断是否是一个文件 |
length() | 查看文件中的字节数 |
isHidden() | 测试文件是否时一个隐藏文件 |
import java.io.File;
import java.io.IOException;
public class FileDemo {
public static void main(String[] args) throws IOException {
//创建一个File对象
File file = new File("C:/Users/iFinder/Desktop/Java Learnning/JavaSE/src/com/IOLearning/FileTest.txt"); //给定位置及名称
System.out.println(file.createNewFile()); //true
System.out.println(file.exists()); //true 一旦指定了file对象的路径以及名称,之后进行的操作就都是针对该对象的
// System.out.println(file.delete()); //true 若文件存在,则删除,返回true
System.out.println(file.getAbsolutePath()); //返回文件绝对路径
System.out.println(file.getPath()); //返回文件相对路径
System.out.println(file.getName()); //返回文件名
System.out.println(file.isFile()); //是否是一个文件
System.out.println(file.isHidden()); //是否是一个隐藏文件
}
}
针对目录的操作方法
方法 | 说明 |
---|---|
exists() | 查询目录是否存在 |
isDirectory() | 判断当前路径是否为目录 |
mkdir() | 创建目录 |
getParentFile() | 获取当前目录的父级目录 |
list() | 返回一个字符串数组, 包含目录中的文件和目录的路径名 |
listFiles | 返回一个File数组, 表示用此抽象路径名表示的目录中的文件 |
import java.io.File;
public class DirectoryDemo {
public static void main(String[] args) {
//创建File对象,操作目录
File file = new File("C:/Users/iFinder/Desktop/Java Learnning/JavaSE/src/com/IOLearning/directory"); //指定位置与目录名
System.out.println(file.mkdir()); //true创建了一个目录 mkdirs()可以创建多级目录 "c:.../dirA/dirB/dirC"多级创建调用 mkdirs()
System.out.println(file.exists()); //判断路径是否存在
System.out.println(file.isDirectory()); //true 判断是否为目录
System.out.println(file.isFile()); //false 判断是否为文件
System.out.println(file.getParent()); // 获取父级目录的名字 getParentFile() 返回一个父级目录的File对象
File file1 = new File("C:/Users/iFinder/Desktop/Java Learnning/JavaSE/src/com/");
String[] list = file1.list(); //获取该路径下的全部文件名和目录名
for(String s:list){
System.out.println(s);
}
File[] files = file1.listFiles(); //将该路径下所有文件与目录作为File对象获取
for (File f:files){
System.out.println(f);
}
}
}