ok了家人们今天继续学习io流,废话不多说,我们一起看看吧
一.File类
1.1 File类的概述
通过
File
类与
IO
流进行搭配使用就可以通过
Java
代码将数
据从内存写入到硬盘文件 或者从硬盘文件读取到内存
中。
File
类就是文件和目录路径名的抽象表示形式。
主要用于
文件和目录的创建、查找和删除等操作。
也就是说
File
类可以表示一个文件也可以表示一个文件
夹,我们可以通过操作
File
对象提供的相关方法对它所表
示的文件
/
文件夹进行操作。
1.2 File类的构造方法
public File(String pathname)
:通过将给定的
路径名
字符串
转换为抽象路径名来创建新的
File
实例。
public File(String parent, String child)
:从
父路径名
字符串和子路径名字符串
创建新的
File
实例。
public File(File parent, String child)
:从
父抽象路径
名和子路径名字符串
创建新的
File
实例。
1.3 File类的判断方法
public boolean exists()
:此
File
表示的文件或目录是
否实际存在。
public boolean isFile()
:此
File
表示的是否为文件。
public boolean isDirectory()
:此
File
表示的是否为
目录。
1.4 File类的获取方法
public String getAbsolutePath()
:返回此
File
的绝对
路径名字符串。(带盘符的路径)
public String getPath()
:将此
File
转换为路径名字符
串。 (获取的是 封装路径)
public String getName()
:返回由此
File
表示的文件或
目录的名称。
public long length()
:返回由此
File
表示的文件的长
度。 不能获取目录的长度。
1.5 相对路径和绝对路径
绝对路径:从盘符开始的路径,这是一个完整的路
径。
相对路径:在
IDEA
中,是相对于
idea
中的
project
的
路径!
1.6 File类的创建和删除方法
public boolean createNewFile()
:当且仅当具有该名
称的文件尚不存在时,创建一个新的空文件。
public boolean delete()
:删除由此
File
表示的文件或
目录。
public boolean mkdir()
:创建一个单级文件夹
public boolean mkdirs()
:创建一个多级文件夹。
1.7 File类的遍历方法
public String[] list()
:返回一个
String
数组,存储的是
File
目录中所有的子文件或子目录的名称。
public File[] listFiles()
:返回一个
File
数组,存储的是
File
目录中所有的子文件或子目录的路径的
File
对象。
二.方法递归
递归要有出口
(
结束方法
),
否则会报栈内存溢出错误
StackOverflowError
递归次数不宜过多
2.1
递归获取文件夹下所有文件
/**
* 需求:设计一个方法,可以遍历某个文件夹下所有的文件 包含子目录中的文件
* 并把文件的绝对路径打印出来
*/
public class DemoTest {
public static void main(String[] args) throws IOException {
File dir = new File("java_0709\\A");
printDir(dir);
}
public static void printDir(File dir){
//被传入的文件夹
//获取 当前dir下所有的文件和文件夹
File[] files = dir.listFiles();
//进行遍历 拿到每个文件和文件夹 对象file
for (File file : files) {
//file是文件还是文件夹 都有
if(file.isFile()){
// 文件
System.out.println("文件的路 径是:"+file.getAbsolutePath());
}else {
//file是一个文件夹 怎么办? 继 续找'
printDir(file);
}
}
}
}
三.IO概述
1.1 IO流介绍
学习
IO
流的目的:
1,将数据写到文件中,实现数据永久化存储
2,把文件中的数据读取到内存中(Java程序
)
I
表示
intput
,是数据从硬盘进内存的过程,称之为读数据。
O
表示
output
,是数据从内存到硬盘的过程。称之为写数据。
1.2 IO的分类
根据数据的流向分为:
输入流
和
输出流
。
1,输入流:把数据从硬盘上读取到内存中的流。
2,输出流:把数据从内存 中写出到硬盘上的流。
根据数据的类型分为:
字节流
和
字符流
。
1,字节流:以字节为单位,操作所有类型的文件,包括音频视频图
片等
2,字符流:以字符为单位,只能操作纯文本文件。能用windows
记
事本打开并能读的懂
1.3 IO的顶层父类
字节输入流
:
顶层父类
InputStream 抽象类
字节输出流
:
顶层父类
OutputStream
抽象类
字符输入流
:
顶层父类
Reader
抽象类
字符输出流
:
顶层父类
Writer
抽象类
四.字节流
一切文件数据
(
文本、图片、视频等
)
在存储时,都是以二进制数字的
形式保存,都一个一个的字节,那么传输时一样如此。所以,字节
流可以传输任意文件数据。在操作流的时候,我们要时刻明确,无
论使用什么样的流对象,底层传输的始终为二进制数据。
2.1 字节输出流OutputStream
方法:
public abstract void write(int b):一次写一个字节数据。
public void write(byte[] b):一次写一个字节数组数据。
public void write(byte[] b, int off, int len) :一次写一个字节数
组的部分数据
public void close():关闭此输出流并释放与此流相关联的任何系
统资源。
2.2 FileOutputStream类
FileOutputStream
类的概述
java.io.FileOutputStream 类是OutputStream类的子类,用来表示是
文件输出流,用于将数据写出到文件。
FileOutputStream
类的构造方法
public FileOutputStream(File file):
创建文件输出流以写入由指定的 File对象表示的文件。
public FileOutputStream(String name):
创建文件输出流以指定的名称写入文件。
注意
:当你创建一个流对象时,必须传入一个文件路径。该路径
下,如果没有这个文件,会创建该文件。如果有这个文件,会清空
这个文件的数据。
2.3 数据换行与追加
数据追加续写
public FileOutputStream(File file, boolean append):
创建文件输出流以指定的名称写入文件。
如果第二个参数为true ,不会清空文件里面的内容。
public FileOutputStream(String name, Boolean append):
创建文件输出流以指定的名称写入文件。
如果第二个参数为true ,不会清空文件里面的内容。
写出换行
windows : \r\n
linux : \n
mac : \r
2.4 字节输入流InputStream
java.io.InputStream
抽象类是表示字节输入流的所有类的超类,可
以读取字节信息到内存中。它定义了字节输入流的基本共性功能方
法。
public abstract int read():
每次可以读取一个字节的数据,提升为int类型,读取到文件末尾,返回 -1。
public int read(byte[] b):
每次读取b的长度个字节到数组中,返回读取到的有效字节个数,读取到末尾时,返回 -1。
public void close():
关闭此输入流并释放与此流相关联的任何系统资源。
2.5 FileInputStream类
FileInputStream
类的概述
java.io.FileInputStream
类是
InputStream
类的子类
,
用来表示文件
输入流,从文件中读取字节。
FileInputStream
类的构造方法
FileInputStream(File file):
通过打开与实际文件的连接来创建一个FileInputStream ,
该文件由文件系统中的文件对象 file命名。
FileInputStream(String name):
通过打开与实际文件的连接来创建一个 FileInputStream ,
该文件由文件系统中的路径名 name命名。
注意:
当你创建一个流对象时,必须传入一个文件路径。该路径
下,如果没有该文件
,
会抛出
FileNotFoundException
2.6 读取字节
int read()
,每次可以读取一个字节的数据,提升为
int
类型,读取到
文件末尾,返回
-1
。
2.7 IO资源的处理
JDK7
版本前异常的捕获处理
public class demo01 {
public static void main(String[] args) throws Exception {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream("D:\\IO流(一).pdf");
fos = new FileOutputStream("java_0725\\IO流(一).pdf");
long begin = System.currentTimeMillis();
int data;
while ((data=fis.read())!=-1){
fos.write(data);
}
long end = System.currentTimeMillis();
System.out.println("所用时间为:"+(end-begin));
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(fis!=null){
fis.close();
}
if(fos!=null){
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
JDK7版本异常的捕获处理
JDK7
版本对流的释放做了优化
.
可以使用
try-with-resource
语句
,
该语句确保了每个资源在语句结束时自动关闭。简单理解
:
使用此语
句
,
会自动释放资源
,
不需要自己在写
finally
代码块了
注意
:
使用前提
,
资源的类型必须是
AutoCloseable
接口的实现类
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
public class demo02 {
public static void main(String[] args) throws Exception {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream("D:\\小米官网.html");
fos = new FileOutputStream("java_0726\\小米官网.html");
long begin = System.currentTimeMillis();
byte[] buf = new byte[1024];
int read;
while ((read = fis.read(buf)) != -1) {
fos.write(buf,0,read);
}
fis.close();
fos.close();
long end = System.currentTimeMillis();
System.out.println("消耗时间:"+(end-begin));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
2.8 读字节数组
int read(byte[] b)
每次读取b的长度个字节到数组中,返回读取到的有效字节个数,读取到末尾时,返回-1
helloworld~
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
public class demo03 {
public static void main(String[] args) throws Exception {
FileInputStream fis = new FileInputStream("java_0726\\hello.txt");
byte[] buf = new byte[5];
int len;
while ((len=fis.read(buf))!=-1){//StringIndexOutOfBoundsException fis.read()
System.out.println("输入数据为"+new String(buf,0,len));
}
fis.close();
}
}
三.字节缓冲流
增加代码高效率运行
字节缓冲流
:
BufferedInputStream
,
BufferedOutputStream
字符缓冲流
:
BufferedReader
,
BufferedWriter
缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大
小的缓冲区数组,通过缓冲区读写,减少系统
IO
次数,从而提高读
写的效率。
字节缓冲流的构造方法
public BufferedInputStream(InputStream in) :
创建一个 新的缓冲输入流。
public BufferedOutputStream(OutputStream out):
创建一个新的缓冲输出流。
import java.io.*;
public class demo04 {
public static void main(String[] args) throws Exception {
String fis = "D:\\小米官网.html";
String fos = "java_0726\\小米官网.html";
BufferedInputStream bis =
new BufferedInputStream(new FileInputStream(fis));
BufferedOutputStream bos =
new BufferedOutputStream(new FileOutputStream(fos));
long begin = System.currentTimeMillis();
byte[] buf = new byte[1024];
int len;
while ((len=bis.read(buf))!=-1){
bos.write(buf,0,len);
}
long end = System.currentTimeMillis();
System.out.println("共消耗:"+(end-begin));
bis.close();
bos.close();
}
}
四.Properties集合
4.1 Properties类的概述
java.util.Properties
继承于
Hashtable
,来表示一个持久的属性
集。它使用键值结构存储数据,每个键及其对应值都是一个字符
串。
4.2 Properties类的构造方法
public Properties() :
创建一个空的属性列表
4.3 Properties类存储方法
public Object setProperty(String key, String value):
保存一对属性。
public String getProperty(String key) :
使用此属性列表中指定 的键搜索属性值。
public Set stringPropertyNames() :
获取所有键的名称的集合
public class DemoTest {
public static void main(String[] args){
// 创建属性集对象
Properties properties = new Properties();
public void load(InputStream inStream):以字节流形式 , 把文
件中的键值对, 读取到集合中
// 添加键值对元素
properties.setProperty("张三", "北京");
properties.setProperty("李四", "上海");
properties.setProperty("王五", "深圳");
properties.setProperty("赵六", "广州");
// 打印属性集对象
System.out.println(properties);
// 通过键,获取属性值
System.out.println(properties.getProperty("张 三"));
System.out.println(properties.getProperty("李 四"));
System.out.println(properties.getProperty("王 五"));
System.out.println(properties.getProperty("赵 六"));
// 遍历属性集,获取所有键的集合
Set<String> strings =
properties.stringPropertyNames();
// 打印键值对
for (String key : strings ) {
System.out.println(key+" --
"+properties.getProperty(key));
}
}
}
4.4 Properties类与流相关的方法
作用:
通过流对象,可以关联到配置文件上,这样就能够加载配置
文件中的数据了。
public void load(Reader reader):以字符流形式 , 把文件中的
键值对, 读取到集合中
public void store(OutputStream out, String comments):把集
合中的键值对,以字节流形式写入文件中 , 参数二为注释
public void store(Writer writer, String comments):把集合中
的键值对,以字符流形式写入文件中 , 参数二为注释
public class DemoTest {
public static void main(String[] args) throws
IOException {
//创建对象
Properties prop=new Properties();
//读取 db.properties属性配置文件
FileInputStream fis=new
FileInputStream("java_0709\\db.properties");
prop.load(fis);
// 关闭流,释放资源
fis.close();
System.out.println(prop);
}
}
注意事项:
文本中的数据,必须是键值对形式,可以使用空格、等号、冒号
等符号分隔。
如果配置文件中有中文,那么加载文件文件时,使用字符流
,
但是
开发中一般配置文件中不要写中文
public class DemoTest {
public static void main(String[] args) throws
IOException {
//创建对象
Properties prop = new Properties();
//存储元素
prop.setProperty("name","zhangsan");
prop.setProperty("age","18");
//把集合中的数据,写入到配置文件
FileOutputStream fos=new
FileOutputStream("java_0709\\info.properties");
prop.store(fos,"lzw");
// 关闭流
fos.close();
}
}
4.5 ResourceBundle工具类
java.util.ResourceBundle
它是一个抽象类我们可以使用它的子类
PropertyResourceBundle
来读取以
.properties
结尾的配置文件。
通过静态方法直接获取对象:
static ResourceBundle
getBundle(String baseName)
可以根据名字直接获取默认语言环境
下的属性资源。参数注意
: baseName
属性集名称不含扩展名。
属性集文件是在
src
目录中的
ResourceBundle
中常用方法:
String getString(String key) :
通过
键,获取对应的值
public class DemoTest {
public static void main(String[] args) throws
IOException {
//获取对象 (作用:读取项目工程的src目录下的.properties配置文件)
ResourceBundle rb =ResourceBundle.getBundle("db");
//只需要指定配置文件的名字即可
//获取配置文件中的value值
String username = rb.getString("username");
String password = rb.getString("password");
System.out.println(username);
System.out.println(password);
}
}
五.字符集
为什么字节流读取纯文本文件,会出现乱码 ?
如果使用字节流
,
把文本文件中的内容读取到内存时
,
可能会出现
乱码
如果使用字节流
,
把中文写入文本文件中
,
也有可能会出现乱码
读取hello.txt中 "你好" 两个汉字
public class DemoTest {
public static void main(String[] args) throws
IOException {
//字节输入流(读取中文数据)
FileInputStream fis = new
FileInputStream("java_0709/hello.txt");
//读取字节数据
System.out.println((char)fis.read());
System.out.println((char)fis.read());
//释放流
fis.close();
}
}
因为字节流读中文,每次只能读一部分所以出现了乱码。
public class DemoTest {
public static void main(String[] args) throws
IOException {
//字节输入流(读取中文数据)
FileInputStream fis = new
FileInputStream("java_0709/hello.txt");
//读取字节数据
byte[] buf=new byte[3];
fis.read(buf);
System.out.println(new String(buf));
fis.read(buf);
System.out.println(new String(buf));
//释放流
fis.close();
}
}
字符集(
Character set
)
,顾名思义是字符的集合。字符是各种文
字和符号的总称,包括文字、标点符号、图形符号、数字、控制符
号等。常用的字符集有:
ASCII
字符集、
GBK
字符集、
Unicode
字符
集等。
标准
ASCII
字符集
ASCII(American Standard Code for Information Interchange)
:
美国信息交换标准代码,包括了英文、符号等。
标准
ASCII
使用
1
个字节存储一个字符,首尾是
0
,总共可表示
128
个
字符
ASCII(American Standard Code for Information Interchange)
:
美国信息交换标准代码,包括了英文、符号等。
标准
ASCII
使用
1
个字节存储一个字符,首尾是
0
,总共可表示
128
个
字符
二.字符流
当使用字节流读取文本文件时,可能会有一个小问题。就是遇到中
文字符时,可能不会显示完整的字符,那是因为一个中文字符可能
占用多个字节存储。所以
Java
提供一些字符流类,以
字符
为单位读
写数据,专门用于处理文本文件。
2.1 字符输出流【Writer】
字符输出流Writer类的概述
java.io.Writer
抽象类是表示用于写出字符流的所有类的超类,将指
定的字符信息写出到目的地。它定义了字节输出流的基本共性功能
方法。
字符输出流
Writer
类的常用方法
public void write(int c):写出一个字符。
public void write(char[] cbuf):将 b.length字符从指定的字符
数组写出此输出流。
public abstract void write(char[] b, int off, int len):从指定的
字符数组写出 len字符,从偏移量 off开始输出到此输出流。
public void write(String str) :写出一个字符串。
public void write(String str,int off,int len):写出一个字符串的
一部分。
public abstract void close():关闭流,释放资源,但是在关闭
之前会先刷新流。一旦关闭,就不能再写数据。
public abstract void flush():刷新流,还可以继续写数据。
2.2 FileWriter类
FileWriter
类的概述
java.io.FileWriter
类是写出字符到文件的便利类。构造时使用系统默
认的字符编码
(UTF-8)
和默认字节缓冲区。
FileWriter
类的构造方法
FileWriter(File file):创建一个新的 FileWriter,给定要读取的File对
象。
FileWriter(String fileName):创建一个新的 FileWriter,给定要读
取的文件的名称。
FileWriter(File file,boolean append): 创建一个新的 FileWriter,
追加写入。
FileWriter(String fileName,boolean append): 创建一个新的
FileWriter,追加写入。
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
public class dm02 {
public static void main(String[] args) throws Exception {
FileWriter fw = new FileWriter("java_0727\\hello.txt");
fw.write(97);
fw.write('a');
fw.write("\r\n");
char[] cs = {'你','好','c','+','+'};
fw.write(cs);
fw.write("\r\n");
fw.write(cs,0,4);
fw.write("\r\n");
fw.write("不知道写什么");
fw.write("\r\n");
fw.write("还是不知道写什么",0,8);
fw.close();
}
}
追加写入
import java.io.FileWriter;
import java.io.IOException;
public class dm03 {
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("java_0727\\hello.txt",true);
fw.write("111111"+"\n");
fw.close();
}
}
因为内置缓冲区的原因,如果不关闭输出流,无法写出字符到文件
中。但是关闭的流对象,是无法继续写出数据的。如果我们既想写
出数据,又想继续使用流,就需要
flush
方法了。
flush:刷新缓冲区,流对象可以继续使用。
close:关闭流,释放系统资源。关闭前会刷新缓冲区。防止数
据丢失
即便是flush方法写出了数据,操作的最后还是要调用close方
法,释放系统资源。
2.3 字符输入流【Reader】
字符输入流
Reader
类的概述
java.io.Reader
抽象类是表示用于读取字符流的所有类的超类,可以
读取字符信息到内存中。它定义了字符输入流的基本共性功能方
法。
字符输入流
Reader
类的常用方法
public int read():每次可以读取一个字符的数据,读取到文件末
尾,返回-1。 返回字符数据的编码值。
public int read(char[] cbuf):一次最多读取cbuf.length个字符数
据,并把读取的字符数据存储到cbuf数组中。返回实际读取到的字
符数据个数。 读取到文件末尾返回:-1
2.4 FileReader类
FileReader
类的概述
java.io.FileReader
类是读取字符文件的便利类。构造时使用系统默
认的字符编码
(UTF-8)
和默认字节缓冲区。
FileReader
类的构造方法
FileReader(File file)
: 创建一个新的
FileReader
,给定要读取的
File
对象。
FileReader(String fileName)
: 创建一个新的
FileReader
,给定要
读取的文件的名称。
public class DemoTest {
public static void main(String[] args) throws
IOException {
//创建流对象
FileReader fr=new
FileReader("java_0709\\hello.txt");
//操作 读数据
int read = fr.read();
/*
System.out.println(read);
System.out.println((char)read);
*/
int len;
while( (len=fr.read())!=-1 ){
System.out.println((char)len);
}
//关闭流
fr.close();
}
}
public class DemoTest {
public static void main(String[] args) throws
IOException {
//创建流对象
FileReader fr=new
FileReader("java_0709\\hello.txt");
//操作 读数据
char[] cbuf=new char[5];
// int len=fr.read(cbuf);
// System.out.println("第1次读取到的字符数据个
数:"+len);
// System.out.println("第1次读取到的字符数
据:"+new String(cbuf,0,len));
//
// len=fr.read(cbuf);
// System.out.println("第2次读取到的字符数据个
数:"+len);
// System.out.println("第2次读取到的字符数
据:"+new String(cbuf,0,len));
//
// len=fr.read(cbuf);
// System.out.println("第3次读取到的字符数据个
数:"+len);
// System.out.println("第3次读取到的字符数
据:"+new String(cbuf,0,len));
//
// len=fr.read(cbuf);
// System.out.println("第4次读取到的字符数据个
数:"+len);
// System.out.println("第4次读取到的字符数
据:"+new String(cbuf,0,len));
int len;
while((len=fr.read(cbuf))!=-1){
String str = new String(cbuf,0,len);
System.out.println(str);
}
//关闭流
fr.close();
}
}
ok了家人们。下周见