1、io流基本定义和说明
--io流:就是数据的流动,从外界读入到内存就是输入流,从内存读出到外部设备就是输出流
--字节流:以字节为单位的数据流
--字符流:以字符为单位的,比如说一个英文字母,一个汉字这种,它们的组成可能不止一个字节,但确是一个字符是字符流传输的单位
--字节流的顶级父类
--字节输入流:InputStream
--字节输出流:OutputStream
--字符流的顶级父类
--字符输入流:Reader
--字符输出流:Writer
2、字节流:字节输出流 OutputStream
1、字节输出流 OutputStream
java.io.OutputStream 抽象类是表示字节输出流的所有类的超类,将指定的字节信息写出到目的地。它定义了字节输出流的基本共性功能方法。
--public void close() :关闭此输出流并释放与此流相关联的任何系统资源。
--public void flush() :刷新此输出流并强制任何缓冲的输出字节被写出。
--public void write(byte[] b) :将 b.length字节从指定的字节数组写入此输出流。
--public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。
--public abstract void write(int b) :将指定的字节输出流。
--必须使用close函数,使用后会释放一切相关资源
2、FileOutputStream类 和 构造方法
--java.io.FileOutputStream 类是文件输出流,用于将数据写出到文件。
--当你创建一个流对象时,必须传入一个文件路径。该路径下,如果没有这个文件,会创建该文件。如果有这个文件,会清空这个文件的数据。
--FileOutputStream的构造方法:
--public FileOutputStream(File file) :创建文件输出流以写入由指定的 File对象表示的文件。
--public FileOutputStream(String name) : 创建文件输出流以指定的名称写入文件。
--FileOutputStream类 基本使用:
// 使用File对象创建流对象
File file = new File("a.txt");
FileOutputStream fos = new FileOutputStream(file);
// 使用文件名称创建流对象
FileOutputStream fos = new FileOutputStream("b.txt");
3、FileOutputStream类 相关方法 write close
--unhandled exception: java.io.filenotfoundexception 这种情况表示可能会出现错误,但是没有加异常处理,所以会有 unhandled exception。这里hangdle不是句柄的意思而是处理
--write close方法,写入和截断写入:
try{
// 创建一个 io 输出对象
File f1 = new File("D:\\代码\\java\\helloworld\\file_data\\file_text.txt");
FileOutputStream f1_o = new FileOutputStream(f1);
FileOutputStream f2_o = new FileOutputStream("D:\\代码\\java\\helloworld\\file_data\\file_text_01.txt");
// write方法
int a = 99;
f1_o.write(99);
f1_o.write(a);
f1_o.write(0 );
byte[] b = "黑马程序员".getBytes();
f1_o.write(b);
// write指定字节长度
byte[] e = "qwert".getBytes();
f1_o.write(e, 2, 2);
f1_o.close();
}catch (Exception ex){
System.out.printf("奈奈子");
}
--写出字节数组: write(byte[] b) ,每次可以写出数组中的数据
// 使用文件名称创建流对象
FileOutputStream fos = new FileOutputStream("fos.txt");
// 字符串转换为字节数组
byte[] b = "黑马程序员".getBytes();
// 写出字节数组数据
fos.write(b);
// 关闭资源
fos.close();
--写出指定长度字节数组: write(byte[] b, int off, int len) ,每次写出从off索引开始,len个字节
// 使用文件名称创建流对象
FileOutputStream fos = new FileOutputStream("fos.txt");
// 字符串转换为字节数组
byte[] b = "abcde".getBytes();
// 写出从索引2开始,2个字节。索引2是c,两个字节,也就是cd。
fos.write(b,2,2);
// 关闭资源
fos.close();
--追加写入,而不是每次清理文本后再写入
--public FileOutputStream(File file, boolean append) : 创建文件输出流以写入由指定的 File对象表示的文件。
--public FileOutputStream(String name, boolean append) : 创建文件输出流以指定的名称写入文件。
--参数中都需要传入一个boolean类型的值, true 表示追加数据, false 表示清空原有数据。
--追加写入示例:
try{
// 创建一个 io 输出对象
File f1 = new File("D:\\代码\\java\\helloworld\\file_data\\file_text.txt");
FileOutputStream f1_o = new FileOutputStream(f1);
FileOutputStream f2_o = new FileOutputStream(f1, true);
byte[] e = "qwert".getBytes();
f1_o.write(e, 2, 2);
f1_o.close();
// 追加式写法
f2_o.write("llyl".getBytes());
f2_o.write("黑马".getBytes());
f2_o.close();
}catch (Exception ex){
System.out.printf("奈奈子");
}
--write() 方法写入 换行字符
try{
FileOutputStream f1 = new FileOutputStream("D:\\代码\\java\\helloworld
\\file_data\\file_text_01.txt");
byte[] b = new byte[]{91, 92, 93, 94, 95};
for(byte b_s: b) {
f1.write(b_s);
f1.write("\r\n".getBytes());
}
f1.close();
}
catch(Exception ex){
System.out.printf("黑马");
}
--Windows系统里,每行结尾是 回车+换行 ,即 \r\n ;
--Unix系统里,每行结尾只有 换行 ,即 \n ;
--Mac系统里,每行结尾是 回车 ,即 \r 。从 Mac OS X开始与Linux统一。
3、字节流:字节输入流 InputStream
--java.io.InputStream 抽象类是表示字节输入流的所有类的超类,可以读取字节信息到内存中。它定义了字节输入流的基本 共性功能方法 。
--public void close() :关闭此输入流并释放与此流相关联的任何系统资源。
--public abstract int read() : 从输入流读取数据的下一个字节。
--public int read(byte[] b) : 从输入流中读取一些字节数,并将它们存储到字节数组b中。
--java.io.FileInputStream 类是文件输入流,从文件中读取字节。
--FileInputStream(File file) : 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。
--FileInputStream(String name) : 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。
--FileInputStream 类的方法:基本包含了上面的共性功能方法
--读取字节:read()方法|无参数读取,每次可以读取一个字节的数据,提升为int类型,读取到文件末尾,返回 -1
--示例:
try{
FileInputStream f1 = new FileInputStream("D:\\代码\\java\\helloworld\\f
ile_data\\file_text.txt");
int b;
while((b = f1.read()) != -1){
System.out.println((char) b);
}
f1.close();
}catch(Exception ex){
System.out.printf("aaaaa");
}
--read(byte [] b): 有一个字节数组,传入多大数组就一次读多少个数据返回
--使用数组读取,每次读取多个字节,减少了系统间的IO操作次数,从而提高了读写的效率,建议开发中使用。
--示例:
try{
FileInputStream f1 = new FileInputStream("D:\\代码\\java\\helloworld\\
file_data\\file_text.txt");
int b;
byte [] len = new byte[2];
while((b = f1.read(len)) != -1){
System.out.println(new String(len, 0, b));
}
f1.close();
}catch(Exception ex){
System.out.printf("aaaaa");
}
4、字节流综合应用--复制一张图片
--打开通道
--先按照固定大小读出数据,再按照固定大小输出数据
--关闭资源
--示例代码:
try{
// 开启io通道
FileInputStream fin = new FileInputStream("D:\\代码\\java\\helloworld\\file_da
ta\\pic.jpg");
FileOutputStream fout = new FileOutputStream("D:\\代码\\java\\helloworld\\file_
data\\pic01.jpg");
byte [] bin = new byte[1024];
int len;
while((len = fin.read(bin)) != -1){
fout.write(bin, 0, len);
}
// 关闭通道
fout.close();;
fin.close();
}catch(Exception ex){
System.out.printf("aaaaa");
}
--解释一下:这里按照数组读取,不是说最后一个字节没有了,后面补一个值为-1的字节,而是说如果最后读完了,返回值为-1。而在此之前
返回值都是读取出来的有效字节的长度
5、字符输入流:Reader
--java.io.Reader 抽象类是表示用于读取字符流的所有类的超类,可以读取字符信息到内存中。它定义了字符输入流的基本共性功能方法。
--public void close() :关闭此流并释放与此流相关联的任何系统资源。
--public int read() : 从输入流读取一个字符。
--public int read(char[] cbuf) : 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中。
--FileReader类:java.io.FileReader 类是读取字符文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。
--字符编码:字节与字符的对应规则。Windows系统的中文编码默认是GBK编码表,idea中UTF-8
--字节缓冲区:一个字节数组,用来临时存储字节数据。
--构造函数:
--FileReader(File file) : 创建一个新的 FileReader ,给定要读取的File对象。
--FileReader(String fileName) : 创建一个新的 FileReader ,给定要读取的文件的名称。
--构造函数示例:
// 使用File对象创建流对象
File file = new File("a.txt");
FileReader fr = new FileReader(file);
// 使用文件名称创建流对象
FileReader fr = new FileReader("b.txt");
--读取字符: read 方法,每次可以读取一个字符的数据,提升为int类型,读取到文件末尾,返回 -1
--read():无参数,每次读取一个的示例
try{
// 字符流对象
File f1 = new File("D:\\代码\\java\\helloworld\\file_data\\file_text.txt");
FileReader fro = new FileReader(f1);
int len;
while((len = fro.read())!=-1){
System.out.println((char)fro.read());
}
fro.close();
}catch(Exception ex){
System.out.printf("aaaaa");
}
--读取字符:使用字符数组读取: read(char[] cbuf) ,每次读取b的长度个字符到数组中,返回读取到的有效字符个数,读取到末尾时,返回 -1
--read():每次读取一定数量的字符 示例:
try{
// 字符流对象
File f1 = new File("D:\\代码\\java\\helloworld\\file_data\\file_text.txt");
FileReader fro = new FileReader(f1);
int len;
char [] getchar = new char[40];
String all = "";
while((len = fro.read(getchar))!=-1){
all += new String(getchar, 0, len);
}
fro.close();
System.out.println(new String(all));
}catch(Exception ex){
System.out.printf("aaaaa");
}
6、字符输出流:Writer 和 FileWriter类
--java.io.Writer 抽象类是表示用于写出字符流的所有类的超类,将指定的字符信息写出到目的地。它定义了字节输出流的基本共性功能方法。
--基本共性功能方法:
void write(int c) 写入单个字符。
void write(char[] cbuf) 写入字符数组。
abstract void write(char[] cbuf, int off, int len) 写入字符数组的某一部分,off数组的开始索引,len写的字符个数。
void write(String str) 写入字符串。
void write(String str, int off, int len) 写入字符串的某一部分,off字符串的开始索引,len写的字符个数。
void flush() 刷新该流的缓冲。
void close() 关闭此流,但要先刷新它。
--java.io.FileWriter 类是写出字符到文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。
--构造方法:
--FileWriter(File file) : 创建一个新的 FileWriter,给定要读取的File对象。
--FileWriter(String fileName) : 创建一个新的 FileWriter,给定要读取的文件的名称。
--构造方法示例:
// 使用File对象创建流对象
File file = new File("a.txt");
FileWriter fw = new FileWriter(file);
// 使用文件名称创建流对象
FileWriter fw = new FileWriter("b.txt");
--方法:
--write(int b) 方法,每次可以写出一个字符数据
--flush :刷新缓冲区,流对象可以继续使用。
--close :先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了。
--因为内置缓冲区的原因,如果不关闭输出流,无法写出字符到文件中。但是关闭的流对象,是无法继续写出数据的。如果我们既想写出数据,又想继续使用流,就需要 flush 方法了。
--write() flush() close() 代码示例:
try{
File f2 = new File("D:\\代码\\java\\helloworld\\file_data\\file_text_0
1.txt");
FileWriter fw = new FileWriter(f2);
fw.write("奥啦啦啦啦");
fw.write(99);
fw.write('A');
fw.write(30000);
fw.flush();
fw.close();
}catch(Exception ex){
System.out.printf("aaaaa");
}
--write(char[] cbuf) 和 write(char[] cbuf, int off, int len) ,每次可以写出字符数
组中的数据,用法类似FileOutputStream
--示例:
// 使用文件名称创建流对象
FileWriter fw = new FileWriter("fw.txt");
// 字符串转换为字节数组
char[] chars = "黑马程序员".toCharArray();
// 写出字符数组
fw.write(chars); // 黑马程序员
// 写出从索引2开始,2个字节。索引2是'程',两个字节,也就是'程序'。
fw.write(b,2,2); // 程序
// 关闭资源
fos.close();
--write(String str) 和 write(String str, int off, int len) ,每次可以写出字符串中的
数据
--示例:
// 使用文件名称创建流对象
FileWriter fw = new FileWriter("fw.txt");
// 字符串
String msg = "黑马程序员";
// 写出字符数组
fw.write(msg); //黑马程序员
// 写出从索引2开始,2个字节。索引2是'程',两个字节,也就是'程序'。
fw.write(msg,2,2);
// 程序
// 关闭资源
fos.close();
--续写和换行:操作类似于FileOutputStream
--示例:
// 使用文件名称创建流对象,可以续写数据
FileWriter fw = new FileWriter("fw.txt",true);
// 写出字符串
fw.write("黑马");
// 写出换行
fw.write("\r\n");
// 写出字符串
fw.write("程序员");
// 关闭资源
fw.close();
7、io异常处理
--io中需要最基本的对文件不存在等各种异常进行,因此io操作需要被异常结构包围
try{}
catch(){}
finally{}
--最基本try catch finally结构
public static void main(String[] args) {
// 声明变量
FileWriter fw = null;
try {
//创建流对象
fw = new FileWriter("fw.txt");
// 写出数据
fw.write("黑马程序员"); //黑马程序员
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fw != null) {
fw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
--try-with-resource格式,有点和python的上下文管理器类似或者我觉得就是借鉴了上下文管理器
--该语句确保了每个资源在语句结束时关闭。所谓的资源(resource)是指在程序完成后,必须关闭的对象。
try (创建流对象语句,如果多个,使用';'隔开) {
// 读写数据
} catch (IOException e) {
e.printStackTrace();
}
--示例:
public static void main(String[] args) {
// 创建流对象
try ( FileWriter fw = new FileWriter("fw.txt"); ) {
// 写出数据
fw.write("黑马程序员"); //黑马程序员
} catch (IOException e) {
e.printStackTrace();
}
}
--try-with-resource 的改进,就是对象可以在外面定义好,try的时候直接使用变量名即可
--改进前:
// 被final修饰的对象
final Resource resource1 = new Resource("resource1");
// 普通对象
Resource resource2 = new Resource("resource2");
// 引入方式:创建新的变量保存
try (Resource r1 = resource1;
Resource r2 = resource2) {
// 使用对象
}
--改进后:
// 被final修饰的对象
final Resource resource1 = new Resource("resource1");
// 普通对象
Resource resource2 = new Resource("resource2");
// 引入方式:直接引入
try (resource1; resource2) {
// 使用对象
}
--示例:
public static void main(String[] args) throws IOException {
// 创建流对象
final FileReader fr = new FileReader("in.txt");
FileWriter fw = new FileWriter("out.txt");
// 引入到try中
try (fr; fw) {
// 定义变量
int b;
// 读取数据
while ((b = fr.read())!=‐1) {
// 写出数据
fw.write(b);
}
} catch (IOException e) {
e.printStackTrace();
}
}
8、属性集
--java.util.Properties 继承于 Hashtable ,来表示一个持久的属性集。它使用键值结构存储数据,每个键及其对应值都是一个字符串。该类也被许多Java类使用,比如获取系统属性时, System.getProperties 方法就是返回一个 Properties 对象。
--导入模块:java.util.Properties
--基本方法:
--构造方法:
public Properties() :创建一个空的属性列表。
--基本功能方法:
public Object setProperty(String key, String value) : 保存一对属性。
public String getProperty(String key) :使用此属性列表中指定的键搜索属性值。
public Set<String> stringPropertyNames() :所有键的名称的集合。
--基本功能示例:
try{
// 最基本的设置和获取
Properties pro01 = new Properties();
pro01.setProperty("liming", "lalala");
pro01.setProperty("pide", "qwerty");
pro01.setProperty("5678", "1234");
System.out.println(pro01.getProperty("liming"));
System.out.println(pro01.getProperty("pide"));
System.out.println(pro01.getProperty("5678"));
// 使用方法遍历
Set<String> str_key = pro01.stringPropertyNames();
for(String key:str_key){
System.out.println(pro01.getProperty(key));
}
}catch(Exception ex){
System.out.printf("aaaaa");
}
--Properties类的load方法:
public void load(InputStream inStream) : 从字节输入流中读取键值对。参数中使用了字节输入流,通过流对象,可以关联到某文件上,这样就能够加载文本中的数据了。
--Properties 的流对象使用:记住这个流对象是字节对象,如果输入函数会出错
try{
Properties pro02 = new Properties();
pro02.load(new FileInputStream("D:\\代码\\java\\helloworld\\file_data\\file_
text.txt"));
Set<String> str_key = pro02.stringPropertyNames();
for(String key: str_key){
System.out.println(pro02.getProperty(key));
}
}catch(Exception ex){
System.out.printf("aaaaa");
}