Java IO概述
java.io
Java IO即Java 输入输出系统。
流
在Java IO中,流是一个核心的概念。流从概念上来说是一个连续的数据流。你既可以从流中读取数据,也可以往流中写数据。流与数据源或者数据流向的媒介相关联。在Java IO中流既可以是字节流(以字节为单位进行读写),也可以是字符流(以字符为单位进行读写)。在JAVA中把不同的输入/输出源(键盘、文件、网络等)抽象表述为“流”。
字节流中包含输入流【InputStream】和输出流【OutputStream】两种情况
字符流中包含输入流【Reader】和输出【Writer】两种情况
在Java中,Reader和Writer是java.io包中所有字符流API类的基类。
由这四个抽象类派生出来的子类的名称是以其抽象父类名称为后缀,以功能为前缀。所以判定某一个具体的流的父类,就找出它的结尾的类名是什么,它的抽象父类就是什么。
File类
File类构造函数
File(String pathname)
根据一个路径得到File对象
File(String parent, String child)
根据一个目录和一个子文件/目录得到File对象
File(File parent, String child)
根据一个父File对象和一个子文件/目录得到File对象
需求:创建一个File类型对象,路径分为相对路径和绝对路径,判断该对象对应的文件/路径在电脑中是否存在
exists()用于判断File对象是否存在
File f1 = new File(相对路径/绝对路径);
System.out.println(f1.exists());
File f2 = new File(父路径,子路径/文件名);
System.out.println(f2.exists());
File f3 = new File(File类型对象,子路径/文件名);
System.out.println(f3.exists());
File类的创建功能
boolean mkdir()
创建文件夹,如果存在这样的文件夹,就不创建了,路径不存在返回flase
boolean mkdirs()
创建文件夹,如果父文件夹不存在,会帮你创建出来
boolean createNewFile()
创建文件,路径不存在抛出异常,如果存在这样的文件,就不创建了
注意事项:若创建文件或者文件夹忘了写盘符路径,那么默认在项目路径下
需求:指定路径的File对象,mkdir创建文件夹,路径存在和路径不存在
需求:指定路径的File对象,mkdirs创建文件夹,路径存在和路径不存在
需求:指定路径的File对象,createNewFile创建文件,路径存在和路径不存在
File类的获取功能
String getAbsolutePath()
获取文件的绝对路径
File getAbsoluteFile()
获取文件的绝对路径
String getPath()
获取文件的相对路径
String getName()
获取名称
String[] list()
获取指定目录下的所有文件或者文件夹的名称数组
File[] listFiles()
获取指定目录下的所有文件或者文件夹的File数组
File[] listRoots()
获取电脑中的盘符
String[] list (FilenameFilter filter)
获取指定目录下被FilenameFilter筛选后的文件,返回String类型数组
注意:
FilenameFilter实现类中的accept(File file,String name)中两个参数,第一个参数为File对象可以表示为一个路径,第二个参数为该路径下的文件名
File[] list (FilenameFilter filter)
获取指定目录下被FilenameFilter筛选后的文件,返回String类型数组
File[] listFiles (FileFilter filter)
获取指定目录下被FileFilter筛选后的文件,返回File类型数组
注意:
FileFilter实现类中的accept(File file)只有一个参数,该参数指代的是一个文件的路径,和FilenameFilter中的区别在于,FilenameFilter中两个参数合在一起才能指定一个文件,而FileFilter则没有将路径和文件名分开,通过观察两个接口的名称也能看出二者的区别
File类的判断功能
boolean exists()
判断路径表示的文件或者文件夹是否存在
boolean isDirectory()
判断当是否是一个文件夹
boolean isFile()
判断当前是否是一个文件
判断当前File类型是否是一个文件夹,isDirectory()
判断当前File类型是否是一个文件,isFile()
File类的删除功能
boolean delete()
若是文件就直接删除,若是文件夹则必须是空文件夹
访问文件
字节流
字节输入流【FileInputStream】
字节输入流读取文件的实现步骤:
- 关联实体文件,创建FileInputStream对象
- 调用read方法
- 关闭输入流【close】
字节输入流对象,使用构造函数:
FileInputStream(File file)
返回一个字节输入流对象,该对象使用字节流读取文件,参数为File类型关联实体文件
FileInputStream(String name)
返回一个字节输入流对象,传入的name为路径+文件名
使用字节输入流对象读取文件:
字节输入流对象在读取到最终的数据结尾时,返回-1
int read()
单字节读取文件,返回读取的下一次的数据字节数,若下一次读取没有数据则返回为-1
int read(byte[] b)
多字节读取文件,读取指定数组长度的数据字节,若下一次读取没有数据则返回为-1
多字节读取时,使用byte类型的数组作为缓冲区,可能会存在数据重复问题
int read(byte[] b,int off,int len)
多字节读取文件,读取指定数组长度的数据字节,若下一次读取没有数据则返回为-1
参数2和参数3是针对数组缓冲区进行的设置
参数off:从缓冲区数组第几个下标开始读取
参数len:从缓冲区数组中读取指定长度的数据
注意:参数2和参数3相加的值不能大于等于数组的长度,否则会引发下标异常
关闭输入流对象
void close()
关闭输入流对象
代码示例
单个字节读取
FileInputStream inputStream = new FileInputStream(new File
("D:/work/STS/JavaSE-Day24-IO/1.txt"));
//System.out.println(inputStream.read());
//System.out.println((char)inputStream.read());
//循环遍历读取数据
int n;
while ((n=inputStream.read())!=-1) {
System.out.println((char)n);
}
//关闭输入流
inputStream.close();
多个字节读取,采用byte类型数组为缓冲区,若缓冲区不能被数据长度整除则可能造成数据重复输出
FileInputStream inputStream = new FileInputStream
("D:/work/STS/JavaSE-Day24-IO/1.txt");
byte[] b=new byte[4];
//将字节数组打印输出
for (byte c : b) {
System.out.println((char)c);
}
int n;
while ((n=inputStream.read(b))!=-1) {
System.out.println(new String(b));
}
//关闭输入流
inputStream.close();
多个字节读取,解决数据重复问题
FileInputStream inputStream = new FileInputStream
("D:/work/STS/JavaSE-Day24-IO/1.txt");
// 定义读取数据的缓冲区
byte[] b = new byte[4];
//循环读取并输出
int n;
while ((n = inputStream.read(b)) != -1) {
System.out.println(new String(b,0,n));
}
//关闭输入流
inputStream.close();
多个字节读取,对数组缓冲区进行设置
使用read(byte[] b,int off,int len)
参数2和参数3是针对缓冲区进行设置,相加的值不能大于等于数组长度
FileInputStream inputStream = new FileInputStream
("D:/work/STS/JavaSE-Day24-IO/1.txt");
// 定义读取数据的缓冲区
byte[] b = new byte[4];
//循环读取并输出
int n=0;
while ((n = inputStream.read(b,1,2)) != -1) {
System.out.println(new String(b));
}
//关闭输入流
inputStream.close();
字节输出流【FileOutputStream】
字节流输出数据的代码实现步骤:
- 关联实体文件,创建输出流对象
- 调用write方法
- 关闭输出流
字节输出流对象,构造函数:
FileOutputStream(File file)
返回一个字节输出流对象,参数为File类型关联实体文件
FileOutputStream(String name)
返回一个字节输出流对象,参数为String类型,取值为路径+文件名
向文件中设置是否追加数据:
FileOutputStream(File file, boolean append)
返回一个字节输出流对象,参数1File类型关联实体文件,参数2布尔值true代表追加
FileOutputStream(String name, boolean append)
返回一个字节输出流对象,参数1String类型关联实体文件,参数2布尔值true代表追加
字节输出流对象输出数据到指定文件:
注意:
如果输出的路径不存在会抛出异常,如果输出的路径存在而文件不存在则会创建新的文件
如果不需要对输出的文件进行追加效果,那么需要在创建输出流对象的时候添加布尔值
void write(int b)
将指定字节写入文件输出流中
void write(byte[] b)
将指定的byte数组中的数据写入到文件
void write(byte[] b,int off,int len)
将指定byte数组中的数据指定起始位置和长度的数据输出到文件中
d. 关闭字节输出流对象:
void close()
关闭文件输出流
代码示例
注意事项: 如果输出的文件路径不存在,则抛出异常 如果输出的文件不存在,则自动创建新的文件
如果输出流对象没有设置追加,且输出路径和文件是一致的,则会覆盖前次的输出内容
使用FileOutputStream(File file)创建对象输出数据到文件:
FileOutputStream fos = new FileOutputStream
(new File("D:/work/STS/JavaSE-Day24-IO/2.txt"));
fos.write(97); //97 是ASCII码值,文件中写入的是a
fos.close();
使用FileOutputStream(String name)创建对象输出数据到文件:
FileOutputStream fos = new FileOutputStream
("D:/work/STS/JavaSE-Day24-IO/2.txt");
byte[] b="abcdefghijk".getBytes();
fos.write(b); //传入的是一个byte类型的数组
fos.close();
FileOutputStream(File file,boolean append)创建追加输出流对象:
FileOutputStream fos = new FileOutputStream
("D:/work/STS/JavaSE-Day24-IO/2.txt",true);
byte[] b="0123456789".getBytes();
fos.write(b, 2, 6);
fos.close();
FileOutputStream(String name,Boolean append)创建追加输出流对象:
FileOutputStream fos = new FileOutputStream
("D:/work/STS/JavaSE-Day24-IO/2.txt", true);
byte[] b="0123456789".getBytes();
fos.write(b, 2, 2);
fos.close();
字符流
-
字符输入流【FileReader】
详见字节流 -
字符输出流【FileWriter】
详见字节流
转换流
字节流转字符流【InputStreamReader】
字节流转成字符流的步骤:
- 准备一个字节流
- 将字节流转成字符流输出
- 关闭流
将字节流转换为字符流,使用InputStreamReader构造函数
InputStreamReader(InputStream in)
将字节流对象包装成一个InputStreamReader对象,默认使用本机字符编码
InputStreamReader(InputStream in,String charset)
将字节流对象包装成一个InputStreamReader对象,使用指定的编码格式
代码示例
先使用字节流读取包含中文的文件并输出
FileInputStream fis = new FileInputStream
("D:/work/STS/JavaSE-Day24-IO/src/cn/itsource/readerandwriter/ReaderAndWriterTest.java");
byte[] b=new byte[4];
int len;
StringBuilder build=new StringBuilder();
while ((len=fis.read(b))!=-1) {
build.append(new String(b));
}
System.out.println(build.toString());
fis.close();
优化字节流读取文件时可能出现的乱码问题
FileInputStream fis = new FileInputStream
("D:/work/STS/JavaSE-Day24-IO/src/cn/itsource/readerandwriter/ReaderAndWriterTest.java");
//将字节流包装为字符流
InputStreamReader isr = new InputStreamReader(fis);
char[] c=new char[4];
int len;
StringBuilder build=new StringBuilder();
while ((len=isr.read(c))!=-1) {
build.append(new String(c));
}
System.out.println(build.toString());
isr.close();
fis.close();
字符流转字节流【OutputStreamWriter】
字符流转字节流步骤:
- 准备一个字符流
- 将字符流转换为字节流
- 关闭流
将字符流转换为字节流
OutputStreamWriter(OutputStream out) 将一个字符流中的数据内容写入到转换为显示指定的字节流对象
OutputStreamWriter(OutputStream out,String charset)
使用指定的编码格式将字符流转换为字节流
代码示例
字符流输出数据到文件中,使用字节流关联文件
FileOutputStream fos = new FileOutputStream
("D:/work/STS/JavaSE-Day24-IO/5.txt"); //字节流关联实体文件
OutputStreamWriter osw = new OutputStreamWriter(fos); //字符流输出
osw.write("输出中文");
osw.close();
fos.close();