IO流
输入(input)与输出(output)
Java语言在IO设计方面取得较大的成功,它是完全面向对象的,主要采用装饰器模式避免大量的类,包括了最大的可能,提供了较好的扩展机制。
流
Java的IO主要包含三个部分:
- 流式部分——IO的主题部分
- 非流式部分——主要包含一些辅助流式部分的类,如File类
- 文件读取部分的与安全相关的类以及与本地操作系统相关的文件系统的类
Java中的流操作分为两种
- 基于字节流(InputStream读取,OutPutStream写入)
- 字符流(Reader读取、Writer写入)
Java IO流可以概括为:两个对应、一个桥梁
两个对应:字节流(Byte Stream)和字符流(Char Stream)的对应,输入流和输出流的对应
一个桥梁:字节流道字符流的桥梁
Java中,设计了四个抽象类来表示流:
- inputStream,字节流,读取数据
- OutputStream,字节流,写入数据
- Reader,字符流,读取数据
- Writer,字符流,写入数据
其他多种多样变化的流均是继承了他们,并进行豪华装饰派生出来的加强版
一、File类
File类 是文件和目录路径名的抽象形式,他提供了与平台无关的方法来对磁盘上的文件或目录进行操作。
可以获得文件本身的一些信息,例如文件所在的目录、文件长度、文件读买权限等Java中File类是Java.IO包中唯一代表磁盘文件本身的对象。
表示处理文件和文件系统的相关信息,不具备读取文件信息和向文件写入信息的功能,仅描述文件本身的属性。
构造方法 | 摘要 |
---|---|
File(File parent, String child) | 从父抽象路径名和子路径名字符串创建新的 File实例 |
File(String pathname) | 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例 |
File(String parent, String child) | 从父路径名字符串和子路径名字符串创建新的 File实例 |
File(URI uri) | 通过将给定的 file: URI转换为抽象路径名来创建新的 File实例 |
常用方法 | 摘要 |
---|---|
boolean createNewFile() | 当且仅当具有该名称的文件尚不存在时,原子地创建一个由该抽象路径名命名的新的空文件 |
boolean mkdir() | 创建由此抽象路径名命名的目录 |
boolean mkdirs() | 创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录 |
boolean delete() | 删除由此抽象路径名表示的文件或目录 |
String[] list() | 返回一个字符串数组,命名由此抽象路径名表示的目录中的文件和目录 |
File[] listFiles() | 返回一个抽象路径名数组,表示由该抽象路径名表示的目录中的文件 |
public class Demo1 {
public static void main(String[] args) {
File f1 = new File("D:\\abc.txt");//在D盘创建一个叫abc的文件
File f2 = new File("abc.txt");//在项目中创建abc的文件
File f3 = new File("D:\\abcd");//在D盘创建一个abcd文件夹
File f4 = new File("D:\\abcde\\efg");//在D盘中abcd文件夹下创建一个efg文件夹
try {
boolean b1 = f1.createNewFile();//创建文件
boolean b2 = f2.createNewFile();
boolean b3 = f3.mkdir();//创建由此抽象路径名命名的目录。(文件夹)
boolean b4 = f4.mkdirs();//创建由此抽象路径名命名的目录, 需要父目录可以不存在
if(b1&&b2&&b3&&b4) {
System.out.println("ok");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
二、字节流
Java中的字节流根据流向的不同,可以分为输入流,输出流。
字节输入流类的父类是InputStream,它是一个抽象类。
字节输出流类的父类是OutputStream,它也是一个抽象类。
字节流可以处理所有文件类型的数据(图片、视频、文本。。。)
FileInputStream类
FileInputStream类用于从文件读取数据,它的对象可以用关键字new来创建。
1.可以使用字符串类型的文件名来创建一个输入流对象来读取文件:
FileInputStream fis = new FileInputStream("D:\\abc.txt");
2.也可以使用一个文件对象来创建一个输入流对象来读取文件
File file = new File("D:\\abc.txt");
FileInputStream fis = new FileInputStream(file);
常用方法 | 摘要 |
---|---|
int available() | 返回从此输入流中可以读取(或跳过)的剩余字节数的估计值,而不会被下一次调用此输入流的方法阻塞 |
void close() | 关闭此文件输入流并释放与流相关联的任何系统资源 |
protected void finalize() | 确保当这个文件输入流的 close方法没有更多的引用时被调用 |
FileChannel getChannel() | 返回与此文件输入流相关联的唯一的FileChannel对象 |
FileDescriptor getFD() | 返回表示与此 FileInputStream正在使用的文件系统中实际文件的连接的 FileDescriptor对象 |
int read() | 从该输入流读取一个字节的数据 |
int read(byte[] b) | 从该输入流读取最多 b.length个字节的数据为字节数组 |
int read(byte[] b, int off, int len) | 从该输入流读取最多 len字节的数据为字节数组 |
long skip(long n) | 跳过并从输入流中丢弃 n字节的数据 |
FileOutputStream类
FileOutputStream类用来创建一个文件并向文件中写数据,如果不存在会自动创建
FileOutputStream fos = new FileOutputStream("D:\\efg.txt");
常用方法 | 摘要 |
---|---|
void close() | 关闭此输出流并释放与流相关联的任何系统资源 |
void flush() | 刷新此输出流,并强制将任何缓冲的输出字节写入流 |
void write(byte[] b) | 将 b.length个字节写入此输出流 |
void write(byte[] b, int off, int len) | 将 len字节从位于偏移量 off的指定 byte阵列写入此输出流 |
void write(int b) | 写入指定 byte此输出流 |
使用缓冲区 通过byte[] b 的大小来提高效率
下面是一个实例:
public class Demo2 {
public static void main(String[] args) {
try {
FileInputStream fis = new FileInputStream("D:\\abc.txt");
FileOutputStream fos = new FileOutputStream("D:\\efg.txt");
//读一次1024个字节
byte[] b = new byte[1024];
int length = 0;
try {
//不等于-1 意味着文件读取完毕
while ((length = fis.read(b)) != -1) {
fos.write(b, 0, length);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
三、字符流
Reader是一个字符输入流,以char为单位读取
Writer是一个字符输出流,以char为单位写入
缓冲区 为提高字符流读写的效率,引入了缓冲区机制,进行字符批量的读写,提高了单个字符读写的效率
BufferdReader和BufferdWriter实现了自带缓冲区的字符流高效读写,其中最小操作单元为一个字符(16位),同时,我们也可以自己指定缓冲区的大小,默认的缓冲区有8192个字符,通常情况下已经足够了
BufferdReader类
BufferdReader类是为了提供读的效率而设计的包装类,他可以包装字符流。可以从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取
BufferedReader br = new BufferedReader(new FileReader("D:\\abc.txt"));
常用方法 | 摘要 |
---|---|
void close() | 关闭流并释放与之相关联的任何系统资源 |
Stream lines() | 返回一个 Stream ,其元素是从这个 BufferedReader读取的行 |
void mark(int readAheadLimit) | 标记流中的当前位置 |
boolean markSupported() | 告诉这个流是否支持mark()操作 |
int read() | 读一个字符 |
int read(char[] cbuf, int off, int len) | 将字符读入数组的一部分 |
String readLine() | 读一行文字 |
boolean ready() | 告诉这个流是否准备好被读取 |
void reset() | 将流重置为最近的标记 |
long skip(long n) | 跳过字符 |
BufferdWriter类
BufferdWriter类是为了提供读的效率而设计的包装类,他可以包装字符流。可以从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取
BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\efg.txt"));
常用方法 | 摘要 |
---|---|
void close() | 关闭流,先刷新 |
void flush() | 刷新流,不写有时会少数据 |
void newLine() | 写一行行分隔符 |
void write(char[] cbuf, int off, int len) | 写入字符数组的一部分 |
void write(int c) | 写一个字符 |
void write(String s, int off, int len) | 写一个字符串的一部分 |
下面是一个实例:
public class Demo3 {
public static void main(String[] args) {
try {
BufferedReader br = new BufferedReader(new FileReader("D:\\abc.txt"));
try {
BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\efg.txt"));
String temp = "";
while ((temp = br.readLine()) != null) {
bw.write(temp);// 写入
bw.newLine();// 换行
}
bw.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}