1、IO(Input Output)流的概述
1、io的概念及其特点
流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流.
宏观上io有以下特点。
· IO流用来处理设备之间的数据传输。
· Java对数据的操作是通过流(系统资源)的方式。
· Java用于操作流的对象都在java.io包中。
· 流按操作数据分为两种:字节流与字符流。
· 流按流向分为:输入流,输出流。
2、io的体系结构
2、IO中常用的类
1. File(文件特征与管理):用于文件或者目录的描述信息,例如生成新目录,修改文件名,删除文件,判断文件所在路径等。
2. InputStream(二进制格式操作):抽象类,基于字节的输入操作,是所有输入流的父类。定义了所有输入流都具有的共同特征。
3.OutputStream(二进制格式操作):抽象类。基于字节的输出操作。是所有输出流的父类。定义了所有输出流都具有的共同特征。
4.Reader(文件格式操作):抽象类,基于字符的输入操作。
5. Writer(文件格式操作):抽象类,基于字符的输出操作。
6. RandomAccessFile(随机文件操作):一个独立的类,直接继承至Object.它的功能丰富,可以从文件的任意位置进行存取(输入输出)操作。
3、File详解
1、File(文件特征与管理)
用来将文件或者文件夹封装成对象。
方便对文件与文件夹的属性信息进行操作。
File对象可以作为参数传递给流的构造函数。
2、File API
package com.xyq.file;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
public class FileTest {
public static void main(String[] args) throws IOException {
// method_1();
// method_2();
// method_3();
// method_4();
// method_5();
// method_6();
// method_7();
File file = new File("E:\\test");
FilesFilter(file);
}
/*
* file类的四个静态常量
* public static String separator 与系统有关的目录分隔符 Windows中 :\
* public static char separatorChar Linux中: /
* public static String pathSeparator 与系统有关的路径分隔符 Windows中 ; 分号
* public static char pathSeparatorChar Linux中 : 冒号
*/
public static void method_1(){
File file = new File("E:\\");
String s = file.separator;
System.out.println(s);
s = file.pathSeparator;
System.out.println(s);
}
/*
* file 类的构造方法
* 1. File(String pathName)
* 2. File(String parent, String child)
* 3. File(File parent, String child)
*/
public static void method_2(){
File file = new File("E:\\KeCheng");
File file2 = new File("E:\\","KeCheng");
File file3 = new File(file, "");
System.out.println(file);
System.out.println(file2);
System.out.println(file3);
}
/* File类的创建方法 ,目标文件或者路径存在时,均会返回false
* 1. boolean createNewFile() 创建文件,成功返回true
* 2. boolean mkdir() 创建文件夹,成功返回true,只能创建一级目录
* 3. boolean mkdirs() 创建多级文件夹
*/
public static void method_3()throws IOException{
File file = new File("E:\\text.txt");
System.out.println(file.createNewFile());
File file2 = new File("E:\\test\\test\\test");
System.out.println(file2.mkdirs());
}
/* File类的删除方法
* 1. boolean delete() 删除指定目录或者文件,成功返回true,注意此删除不走回收站,文件夹不为空时没有办法删除
* 2. void deleteOnExit() jvm退出前删除,
*/
public static void method_4()throws IOException{
File file = new File("E:\\test.txt");
System.out.println(file.createNewFile());
System.out.println(file.delete());
}
/* File类的判断方法
* boolean exists() 判断构造方法中封装的路径或者文件是否存在
* boolean isAbsolute() 判断构造方法中封装的路径是不是绝对路径,是返回真
* boolean isDirectory() 判断是不是路径,是返回true
* boolean isFile() 判断是不是文件,是返回true
* boolean isHidden() 判断封装的路径(包括文件)是不是隐藏属性是返回true
*/
public static void method_5(){
File file = new File("E:\\abcde");
System.out.println(file.exists());
System.out.println(file.isAbsolute());
}
/*
* File类的获取方法
* 1.String getName() 获取封装路径最后部分的名字,此方法不会判断路径是否存在,使用之前最好判断
* 2.String getParent() 返回封装路径的父路径
* 3.File getParentFile() 返回封装路径的父路径的File对象
* 4.String getAbsolutePath() 返回封装路径的绝对路径
* 5.File getAbsoluteFile() 返回封装路径的绝对路径的File对象
*/
public static void method_6(){
File file = new File("scr");
System.out.println(file.getAbsoluteFile().getParent());
}
/*
* File的list方法
* 1. static File[] listRoots() 静态的方法,列出系统所以的根,光驱和移动设备存储也会算进去
* 2. String[] list()返回File构造方法封装的路径下的所有文件和文件夹
* 3. File[] listFiles()返回File构造方法封装的路径下的所有文件和文件夹,返回的Filed对象,带全路径
*/
public static void method_7(){
File []roots = File.listRoots();
for(File file:roots){
System.out.println(file);
}
}
//递归过滤方法的实现,选出目录下的*.java文件
//直接使用匿名内部内实现了FileFilter接口
public static void FilesFilter(File file){
File []files = file.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
if (pathname.getName().endsWith(".java") || pathname.isDirectory()) {
return true;
} else {
return false;
}
}
});
if(files != null){
for(File file2:files){
if(file2.isFile()){
System.out.println(file2);
}else {
FilesFilter(file2);
}
}
}
}
}
4、IO流常用基类
- 字节流的抽象基类:
- InputStream 读取一个文本文件中的数据
- OutputStream 向一个文本文件中写入数据
- 用输出流还是输入流 参考标准是内存
字符流的抽象基类:
- Reader
- Writer
比较常用的字节流
- FileInputStream
- FileOutputStream
- BufferedInputStream
- BufferedOutputStream
4.1字节输出流——FileOutputStream
注意 在创建字节输出流对象用于操作文件,在对象初始化时必须明确数据存储的目的地,输出流所关联的目的地,如果不存在,则会自动创建;如果存在,则会覆盖。
具体用法 例 向一个文本文件中写入数据
package com.xyq.outputstream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamTest {
/*
* 将数据写入到文件中。
* 使用字节输出流。FileOutputStream。
*/
public static void main(String[] args) throws IOException{
//1、创建文件夹
File dir = new File("tempFile");
if(!dir.exists()){
dir.mkdir();
}
//显示创建文件的路径
System.out.println(dir.getAbsoluteFile().getParent());
// 2、创建字节输出流对象,用于操作文件,在对象初始化时必须明确数据存储的目的地。
// 输出流所关联的目的地,如果不存在,会自动创建。如果存在,则覆盖。
FileOutputStream fos = new FileOutputStream("tempFile\\test.txt");
// 3、调用输出流的写功能。
fos.write("abcd".getBytes());
//4、释放资源
fos.close();
}
}
4.2字节输入流——FileInputStream
具体用法 例 读取一个文本文件中的数据
4.2.1 read():一个一个字节的读
package com.xyq.outputstream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class FileInputStreamTest {
public static void main(String[] args) throws IOException{
//1、为了确保文件一定在读之前是存在的,将字符串路径封装成File对象。
File file = new File("tempFile\\test.txt");
//2、判断文件是否存在
if(!file.exists()){
throw new RuntimeException("要读取的文件不存在");
}
//3、创建文件字节读取流对象时,必须明确与之关联的数据源。
FileInputStream fis = new FileInputStream(file);
//4、调用读方法
int by = 0;
while ((by = fis.read()) != -1) {
System.out.println(by);
}
//5、关闭资源
fis.close();
}
}
4.2.2read(byte[] buf):先把字节存入到缓冲区字节数组中,一下读一个数组(常用)
package com.xyq.outputstream;
import java.io.FileInputStream;
import java.io.IOException;
public class FileInputStreamTest2 {
//1、定义缓冲区的大小可以是1024的整数倍
private static final int SIZE = 1024;
public static void main(String[] args) {
//2、创建文件字节读取流对象。
FileInputStream fis = null;
try {
fis = new FileInputStream("tempFile\\test.txt");
//3、创建一个字节数组。
byte [] buf = new byte[SIZE];
//4、调用读方法
int len = 0;// len记录的是往字节数组里存储的字节个数。
while((len = fis.read(buf)) != -1){
// 将字节数组转成字符串,打印并看一下效果。
System.out.println(new String(buf, 0, len));
}
} catch (IOException e) {
// 将异常信息写入到日志文件中以进行记录。
}finally {
//5、关闭资源
if(fis != null){
try {
fis.close();
} catch (IOException e) {
// 一般可以throw RuntimeException异常,或者将异常信息写入到日志文件中以进行记录。
e.printStackTrace();
}
}
}
}
}
4.3缓冲流-BufferedInputStream、BufferedOutputStream
4.3.1有了InputStream和OutputStream为什么还要有BufferedInputStream和BufferedOutputStream?
因为不带缓冲的操作,每读一个字节就要写入一个字节,由于涉及磁盘的IO操作相比内存的操作要慢很多,所以不带缓冲的流效率很低。带缓冲的流,可以一次读很多字节,但不向磁盘中写入,只是先放到内存里。等凑够了缓冲区大小的时候一次性写入磁盘,这种方式可以减少磁盘操作次数,速度就会提高很多!
同时正因为它们实现了缓冲功能,所以要注意在使用BufferedOutputStream写完数据后,要调用flush()方法或close()方法,强行将缓冲区中的数据写出。否则可能无法写出数据。
4.3.2 BufferedInputStream和BufferedOutputStream的具体用法
例 图片的复制package com.xyq.outputstream;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyPicBufferTest {
//1、定义缓冲区的大小可以是1024的整数倍
private static final int SIZE = 1024;
public static void main(String[] args) {
File oldFile = new File("tempFile\\1.jpg");
File newFile = new File("tempFile\\abc.jpg");
copyFile(oldFile, newFile);
}
public static void copyFile(File oldFile, File newFile){
//2、创建流
FileInputStream fis = null;
BufferedInputStream bis = null;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
try {
fis = new FileInputStream(oldFile);
bis = new BufferedInputStream(fis);
fos = new FileOutputStream(newFile);
bos = new BufferedOutputStream(fos);
//3、进行读写操作
byte []byf = new byte[SIZE];
int len = 0;// len记录的是往字节数组里存储的字节个数。
//先读后写
while((len = bis.read(byf)) != -1){
bos.write(byf, 0, len);
}
bos.flush();//冲刷没有达到缓存限度的数据,确保数据全部写完
System.out.println("复制完成。。。");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//4、关闭资源
if(fis != null){
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(bis != null){
try {
bis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(fos != null){
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(bos != null){
try {
bos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}