大家好,欢迎来到IT知识分享网。
今日内容
- 字节流
- 字符流
- 属性集
一. IO流
1.1 什么是IO
数据的传输,可看做一种数据的流动,按照流动的方向,以内存为基准,分为`输入input` 和`输出output` ,即流向内存是输入流,流出内存的输出流。 硬盘--->内存 输入:从硬盘中的文件 到内存中的程序 内存--->硬盘 输出 :从内存中的程序 到 硬盘上的文件 java.io包下 进行输入和输出 输入: 读取数据 输出: 写出数据
1.2 IO流的分类
根据数据的类型分为:字节流 和 字符流
- 字节流 :以字节为单位,读写数据的流。 一次操作一个字节,由于计算机上一切数据都是由字节构成
所以字节流可以操作计算机上的一切数据 例如 .txt .avi .jpg .exe .mp3 等等
- 字符流 :以字符为单位,读写数据的流。一次操作一个字符,对于字符流来说只能操作文本文件
文本文件:用记事本 notepad+=打开 能看懂不乱码 就是文本文件 例如 .txt .java .html .css .js .xml等等 需要注意:word excel 不是文本文件
根据数据的流向分为:输入流 和 输出流
字节输入流
InputStream
read 读字节
(子类)FileInputStream
字节输出流
OutputStream
write 写字节
FileOutputStream
字符输入流
Reader
read 读字符
FileReader
字符输出流
Writer
wrtie 写字符
FileWriter
IO流的命名规则 :一般情况下 前面是这个流能干什么 后面是这个流的父类是谁
1.3 IO流顶层父类
类 |
含义 |
java.io.OutputStream |
字节输出流顶层父类,抽象类,定义了写出数据方法write()。 |
java.io.InputStream |
字节输入流顶层父类,抽象类,定义了读取数据方法read()。 |
java.io.Writer |
字符输出流顶层父类,抽象类,定义了写出数据方法write()。 |
java.io.Reader |
字符输入流顶层父类,抽象类,定义了读取数据方法read()。 |
二. 字节流
2.1 字节输出流OutputStream
字节流可以传输任意文件数据, 无论使用什么样的流对象,底层传输的始终为二进制数据。 提示:8个二进制位为1个字节,0000-0000 是1个字节 java.io.OutputStream 抽象类是表示字节输出流的所有类的超类 write(int b ) 写一个字节 write(byte[] bytes) 写一个字节数组 write(byte[] bytes,int start ,int length) 写字节数组的一部分 close() 关闭资源 IO流对象一般情况 本身都没有读写功能 需要调用操作系统的读写功能 就会和操作系统进行交互 进行读写之后 需要告知操作系统 读写完毕 这样操作系统就不会占用文件资源了
2.2 FileOutputStream类
OutputStream常用子类 java.io.FileOutputStream 构造方法 绑定数据目的 public FileOutputStream(File file) public FileOutputStream(String path) 创建一个流对象时,必须传入一个文件路径, 如果文件夹不存在 抛出 FileNotFoundException 如果文件不存在 自动创建一个文件, 如果文件存在 创建一个空文件 覆盖原来的文件
public class Demo01_OutputStream { public static void main(String[] args) throws IOException { //使用File对象创建流对象 File f = new File("E:\\aaa\\2.txt"); OutputStream out = new FileOutputStream(f); /* //使用文件名称创建流对象 OutputStream out = new FileOutputStream("E:\\aaa\\2.txt");//没有该文件自动创建一个 */ //一次写一个字符 out.write(98); //一次写一个字符数组 byte[] b = {65,66,67,68}; out.write(b); //一次写字节数组的一部分 out.write(b,0,2); //写字符串 out.write("HelloWorld".getBytes()); //关闭资源 out.close(); } } 1. 虽然参数为int类型四个字节,但是只会保留一个字节的信息写出。 2. 写出的整数被直接写在目的文件中。 3. 流操作完毕后,必须释放系统资源,调用close方法
数据追加续写与换行
文件的续写与换行 续写 public FileOutputStream(File file, boolean append)创建文件输出流以写入由指定的 File对象表示的文件 public FileOutputStream(String name, boolean append)创建文件输出流以指定的名称写入文件 如果append的值为true 则不覆盖文件 进行续写 文件换行 \r\n // 文件的续写与换行 public class Demo02_OutputStream { public static void main(String[] args) throws IOException { OutputStream out = new FileOutputStream("E:\\aaa\\2.txt",true); //构造方法传入布尔值true,则会续写 out.write("我\n\r".getBytes()); out.write("爱\n\r".getBytes()); // \n\r换行 out.write("java\n\r".getBytes()); out.close(); } }
2.3 字节输入流InputStream
java.io.InputStream 抽象类 是表示字节输入流的所有类的超类 int read() 读一个字节 返回值就是每次读取到的数据 int read(byte[] bytes) 读一个字节数组 void close() 关闭资源
2.4 FileInputStream类
InputStream常用子类 java.io.FileInputStream 构造方法 绑定数据源 public FileInputStream(File file) public FileInputStream(String path) 方法 int read(byte[] bytes) byte[] bytes: 缓冲的作用 每次调用操作系统 读取到的数据 先放入到byte数组中 int: 返回的是每次读取的个数 read()方法 , 只读取一个字节 , 提升为int类型,读取到文件末尾,返回`-1` 如果文件中存在-1,读取文件时也不会直接读取到-1,因为-1是两个字节
public class Demo03_InputStream { public static void main(String[] args) throws IOException { //根据文件名创建流对象 InputStream in = new FileInputStream("E:\\aaa\\2.txt"); /* //根据File对象创建流对象 File file = new File("E:\\aaa\\2.txt"); InputStream in = new FileInputStream(file);*/ //一次读取一个字节 int num; //定义变量记录读取数据 //循环读取 while ((num = in.read())!= -1){ System.out.println((char)num); } //一次读取一个字节数组 byte[] b = new byte[5]; int length; //记录读取数据个数 while ((length = in.read(b)) != -1){ // 每次读取后,把数组变成字符串打印 // System.out.println(new String(b)); //数组中,上次读取的数据没有被完全替换,所以要通 过length ,获取有效的字节 System.out.println(new String(b,0,length)); } in.close(); } }
2.5 IO中write方法的源码解析
- 调用write方法写出数据时,JDK源代码中最终调用的方法是writeBytes()方法。
- private native void writeBytes(byte b[], int off, int len, boolean append)throws IOException方法是本地方法是和操作系统交互的方法。操作系统本身就具有IO功能,因此 JVM 是调用操作系统中的功能实现数据的读写!
三. IO流中的异常处理
使用throws抛出异常, 如果出现异常,程序将不会执行close()方法,因此异常需要使用try catch进行处理。
- try外声明变量,try内建立对象。目的是提升变量的作用域。
- finally中进行资源释放。进行流对象非空判断。如果有多个流对象,单独进行释放
public class Demo03_IO { public static void main(String[] args) { //try外定义变量 在try外为变量赋值是为了提升作用域范围 InputStream in = null; try{ in = new FileInputStream("E:\\aaa\\1.txt"); byte[] b ={'a','b','c'}; int l ; while ((l=in.read(b)) != -1){ System.out.println(new String(b,0,l)); } }catch (IOException e){ e.printStackTrace(); }finally { try{ if(in !=null) //避免空指针异常做出判断 in.close(); }catch (IOException e){ e.printStackTrace(); } } } }
双流异常处理:
// IO流异常处理 出现双流异常处理 public class Demo04_IO { public static void main(String[] args){ //try外定义变量 提升作用域范围 InputStream in = null; OutputStream out =null; try{ in = new FileInputStream("E:\\aaa\\1.txt"); out = new FileOutputStream("E:\\aaa\\2.txt"); byte[] b = new byte[1024]; int length; while ((length = in.read(b))!= -1){ out.write(b,0,length); } }catch (IOException e){ e.printStackTrace(); }finally { if (in != null){ try { in.close(); } catch (IOException e) { e.printStackTrace(); } if(out != null){ try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } } } } public class Demo05_IO { public static void main(String[] args) { ///JDK1.7 关闭资源 try( InputStream in = new FileInputStream("E:\\aaa\\1.txt"); OutputStream out = new FileOutputStream("E:\\aaa\\2.txt")){ byte[] b = new byte[1024]; int length; while ((length = in.read(b))!= -1){ out.write(b,0,length); } } catch (IOException e){ e.printStackTrace(); } } } // 自定义处理IO流异常类 public class IOUtil { //私有构造方法 private IOUtil(){} //定义关闭方法 静态方法,直接类名调用 public static void close(InputStream in, OutputStream out){ try { if(in!=null){ in.close(); } } catch (IOException e) { e.printStackTrace(); } try { if(out!=null){ out.close(); } } catch (IOException e) { e.printStackTrace(); } } public static void copyFile(String src, String dest) { InputStream in = null; OutputStream out = null; try{ in = new FileInputStream(src); out = new FileOutputStream(dest); byte[] bytes = new byte[1024]; int length = 0; while((length = in.read(bytes))!=-1){ out.write(bytes,0,length); } }catch (IOException e){ e.printStackTrace(); }finally { close(in,out); } } }
四. 文件复制
使用字节流可以进行任何文件的复制,因为字节流操作的是组成文件的最小单元-字节。
1.创建字节输入流绑定数据源
2.创建字节输出流绑定数据目的
3.循环读写
4.关闭资源
案例实现
public class Demo04_FileCopy { public static void main(String[] args) throws IOException { //创建字节输入流绑定数据源 InputStream in = new FileInputStream("E:\\aaa\\12.java"); //创建字节输出流绑定数据目的 OutputStream out = new FileOutputStream("E:\\aaa\\1.txt"); //循环读写 //一次只读取一个字节 int num; while ((num=in.read()) != -1){ out.write(num); System.out.println((char)num); } //关闭资源 in.close(); out.close(); } } public static void main(String[] args) throws IOException { // 1.创建流对象 // 1.1 指定数据源 FileInputStream fis = new FileInputStream("D:\\test.jpg"); // 1.2 指定目的地 FileOutputStream fos = new FileOutputStream("test_copy.jpg"); // 2.读写数据 // 2.1 定义数组 byte[] b = new byte[1024]; // 2.2 定义长度 int len; // 2.3 循环读取 while ((len = fis.read(b))!=-1) { // 2.4 写出数据 fos.write(b, 0 , len); } // 3.关闭资源 fos.close(); fis.close(); }
五. 字符流
当使用字节流读取文本文件时,遇到中文字符时,可能不会显示完整的字符,因为一个中文字符可能占用多个字节存储。所以Java提供一些字符流类,以字符为单位读写数据,专门用于处理文本文件。
2.1 字符输入流Reader
java.io.Reader抽象类 表示用于读取字符流的所有类的超类 方法: int read() 一次读一个字符 返回值就是读取到的内容 int read(char[] chs) 一次读一个字符数组 返回值是读取的有效个数 void close() 关闭资源
2.2 FileReader类
java.io.FileReader Reader类常用实现类 构造方法 绑定数据源 构造时使用系统默认的字符编码和默认字节缓冲区 public FileReader(String path) public FileReader(File file)
小贴士:
字符编码:字节与字符的对应规则。Windows系统的中文编码默认是GBK编码表。idea中UTF-8字节缓冲区:一个字节数组,用来临时存储字节数据。
public class FileReaderConstructor throws IOException{ public static void main(String[] args) { // 使用File对象创建流对象 File file = new File("a.txt"); FileReader fr = new FileReader(file); // 使用文件名称创建流对象 FileReader fr = new FileReader("b.txt"); } }
读取数据
public class Demo01_Reader { public static void main(String[] args) throws IOException { Reader r = new FileReader("E:\\aaa\\1.txt"); //一次读取一个字符 int n; while ((n = r.read())!= -1){ System.out.println((char)n); } //一次读取一个字符数组 char[] c = new char[10]; int length; while ((length = r.read(c))!= -1){ System.out.println(new String(c,0,length)); } r.close(); } }
2.3 字符输出流Writer
java.io.Writer 抽象类 表示用于写出字符流的所有类的超类 方法 write(int c) 写一个字符 write(char[] chs) 写一个字符数组 write(chra[] chs,int start,int length) 写字符数组的一部分 write(String str) 写字符串 public abstract void flush() :刷新此输出流并强制任何缓冲的输出字符被写出 字符流有一个缓冲区 如果不刷新缓冲区 数据就不进入到数据目的 所以 字符流每次写完数据 要进行一次刷新 close()是关闭资源的方法,在关闭之前会进行一次刷新操作
2.4 FileWriter类
java.io.FileWriter类 是Writer类子类 构造方法绑定 数据目的 public FileWriter(String path) public FileWriter(File file) public FileWriter(String path,boolean append) public FileWriter(File file,boolean append)
基本写出数据
public class Demo02_Writer { public static void main(String[] args) throws IOException { //创建字符输出流,绑定数据目的 Writer w = new FileWriter("E:\\aaa\\1.txt",true); //一次输出一个字符 w.write(99); w.flush(); //一次输出一个字符数组 char[] c = {'李','洋'}; w.write(c); w.flush(); //一次输出一个字符数组的一部分 w.write(c,0,1); w.flush(); //一次输出一个字符串 w.write("李洋今年24"); w.close(); } } /* 【注意】关闭资源时,与FileOutputStream不同。 如果不关闭,数据只是保存到缓冲区,并未保存到文件。 */
小贴士:
虽然参数为int类型四个字节,但是只会保留一个字符的信息写出。
未调用close方法,数据只是保存到了缓冲区,并未写出到文件中。
即便是flush方法写出了数据,操作的最后还是要调用close方法,释放系统资源。
六. 属性集
6.1Properties类
java.util.Properties 继承于 Hashtable 表示一个持久的属性集 System.getProperties() 方法就是返回一个`Properties`对象 java.util.Properties 属性集合 双列集合 特点 1.继承Hashtable 实现Map接口 可以使用Map的所有的方法 2.没有泛型 键String 值String 3.唯一一个可以和IO流直接结合使用的集合 4.键 无序 唯一 不允许 null键和null值 特有方法 String setProperty(String key ,String value) 添加数据 相当于 put String getProperty(String key) 根据键找值 相当于 get set<String> stringPropertyNames() 获取所有键的Set集合 相当于 keySet
public class ProDemo { public static void main(String[] args) throws FileNotFoundException { // 创建属性集对象 Properties properties = new Properties(); // 添加键值对元素 properties.setProperty("filename", "a.txt"); properties.setProperty("length", ""); properties.setProperty("location", "D:\\a.txt"); // 打印属性集对象 System.out.println(properties); // 通过键,获取属性值 System.out.println(properties.getProperty("filename")); System.out.println(properties.getProperty("length")); System.out.println(properties.getProperty("location")); // 遍历属性集,获取所有键的集合 Set<String> strings = properties.stringPropertyNames(); // 打印键值对 for (String key : strings ) { System.out.println(key+" -- "+properties.getProperty(key)); } } } 输出结果: {filename=a.txt, length=, location=D:\a.txt} a.txt D:\a.txt filename -- a.txt length -- location -- D:\a.txt
6.2与IO流结合使用
void load(InputStream in ) 可以将文件中的键值对加载到集合中 方法的参数是InputStream 可以传入其任意子类对象 FileInputStream void load(Reader r) 方法的参数是Reader 可以传入其任意子类对象 FileReader void store(OutputStream out,String comments) 此方法返回后,输出流仍保持打开状态
public class Demo03_Properties { public static void main(String[] args) throws IOException { read(); write(); } //读取配置文件 public static void read() throws IOException { Properties p = new Properties(); Reader r = new FileReader("day20\\aaa\\bbb.properties"); p.load(r); r.close(); System.out.println(p); } //向配置文件中写键值对 public static void write() throws IOException { Properties p = new Properties(); p.setProperty("柳岩","38"); p.setProperty("唐嫣","18"); p.setProperty("金莲","138"); Writer r = new FileWriter("day20\\aaa\\bbb.properties"); p.store(r,null); r.close(); /* #Wed Jun 30 22:08:28 CST 2021 唐嫣=18 金莲=138 柳岩=38 */ } }
小贴士:文本中的数据,必须是键值对形式,可以使用空格、等号、冒号等符号分隔。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/78236.html