- 概述:
IO流用来处理设备之间的数据传输
- Java对数据的操作是通过流的方式
- Java用于操作流的类都在IO包中
- 流按流向分为两种:输入流,输出流。
- 流按操作类型分为两种:
- 字节流 : 操作字节的。字节流可以操作任何数据,因为在计算机中任何数据都是以字节的形式存储的
- 字符流 : 操作字符的。字符流只能操作纯字符数据,比较方便。
- IO流常用父类
- 字节流的抽象父类:
- InputStream
- OutputStream
- 字符流的抽象父类:
- Reader
- Writer
- 字节流的抽象父类:
基本框架:
public static void main(String[] args) { //需要异常处理 FileInputStream fis = new FileInputStream("xxx.txt"); //异常:读的文件可能不存在 FileOutputStream fos = new FileOutputStream("yyy.txt"); //异常:写的路径可能不存在 int b; while((b = fis.read()) != -1) { //异常:可能文件不可读 fos.write(b); //异常:可能文件不可写 } fis.close(); //异常:可能无法关闭输入流 fos.close(); //异常:可能无法关闭输出流 }
流的标准处理异常代码(jdk1.6版本)
public static void demo1() throws FileNotFoundException, IOException { FileInputStream fis = null; FileOutputStream fos = null; try { fis = new FileInputStream("xxx.txt"); fos = new FileOutputStream("yyy.txt"); int b; while((b = fis.read()) != -1) { fos.write(b); } }finally { try{ if(fis != null) fis.close(); }finally { //try fianlly的嵌套目的是能关一个尽量关一个 if(fos != null) fos.close(); } } } }
流的标准处理异常(jdk1.7版本)
public static void main(String[] args) throws IOException { try( FileInputStream fis = new FileInputStream("xxx.txt"); //已具备自动关闭(流)功能 FileOutputStream fos = new FileOutputStream("yyy.txt");{ int b; while((b = fis.read()) != -1) { fos.write(b); } } }
缓冲区拷贝:BufferInputStream,BufferOutputStream,开发时推荐使用
提高开发效率:活用匿名对象//FileInputStream fis = new FileInputStream("xxx.mp3"); //BufferedInputStream bis = new BufferedInputStream(fis); BufferedInputStream bis = new BufferedInputStream(new FileInputStream("xxx.mp3")); //使用了匿名对象
close方法
- 具备刷新的功能,在关闭流之前,就会先刷新一次缓冲区(也就是将缓冲区的内容同步到文件中去),将缓冲区的字节全都刷新到文件上,再关闭,close方法刷完之后就能写了
flush方法
- 具备刷新的功能,刷完之后还可以继续写,可以实现查看实时进度
IO流实现图片传输加密
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class Test1 { /** * @param args * @throws IOException * 将写出的字节异或上一个数,这个数就是密钥,解密的时候再次异或就可以了 */ public static void main(String[] args) throws IOException { BufferedInputStream bis = new BufferedInputStream(new FileInputStream("xxx.jpg")); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.jpg")); //复制后得到的图片无法打开,完成加密。把该图片同理再加密一次(双异或),即可解密。 int b; while((b = bis.read()) != -1) { bos.write(b ^ 123); } bis.close(); bos.close(); } }
拷贝指定路径文件实例
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.Scanner; public class Test2 { /** * 在控制台录入文件的路径,将文件拷贝到当前项目下 * * 分析: * * 1,定义方法对键盘录入的路径进行判断,如果是文件就返回 * 2,在主方法中接收该文件 * 3,读和写该文件 * @throws IOException */ public static void main(String[] args) throws IOException { File file = getFile(); //获取文件 BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file.getName())); int b; while((b = bis.read()) != -1) { bos.write(b); } bis.close(); bos.close(); } /* * 定义一个方法获取键盘录入的文件路径,并封装成File对象返回 * 1,返回值类型File * 2,参数列表无 */ public static File getFile() { Scanner sc = new Scanner(System.in); //创建键盘录入对象 System.out.println("请输入一个文件的路径:"); while(true) { String line = sc.nextLine(); //接收键盘录入的路径 File file = new File(line); //封装成File对象,并对其进行判断 if(!file.exists()) { System.out.println("您录入的文件路径不存在,请重新录入:"); }else if(file.isDirectory()) { System.out.println("您录入的是文件夹路径,请重新录入:"); }else { return file; } } } }
录入数据拷贝到文件
import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.Scanner; public class Test3 { /** * 将键盘录入的数据拷贝到当前项目下的text.txt文件中,键盘录入数据当遇到quit时就退出 * * 分析: * 1,创建键盘录入对象 * 2,创建输出流对象,关联text.txt文件 * 3,定义无限循环 * 4,遇到quit退出循环 * 5,如果不quit,就将内容写出 * 6,关闭流 * @throws IOException */ public static void main(String[] args) throws IOException { //1,创建键盘录入对象 Scanner sc = new Scanner(System.in); //2,创建输出流对象,关联text.txt文件 FileOutputStream fos = new FileOutputStream("text.txt"); System.out.println("请输入数据:"); //3,定义无限循环 while(true) { String line = sc.nextLine(); //将键盘录入的数据存储在line中 //4,遇到quit退出循环 if("quit".equals(line)) { break; } //5,如果不quit,就将内容写出 fos.write(line.getBytes()); //字符串写出必须转换成字节数组 fos.write("\r\n".getBytes()); } //6,关闭流 fos.close(); } }
字符流(FileReader类,FileWriter类)是什么
- 字符流是可以直接读写字符的IO流
- 字符流读取字符, 就要先读取到字节数据, 然后转为字符. 如果要写出字符, 需要把字符转为字节再写出.
IO流(什么情况下使用字符流)
- 字符流也可以拷贝文本文件, 但不推荐使用. 因为读取时会把字节转为字符, 写出时还要把字符转回字节.
- 程序需要读取一段文本, 或者需要写出一段文本的时候可以使用字符流
- 读取的时候是按照字符的大小读取的,不会出现半个中文
- 写出的时候可以直接将字符串写出,不用转换为字节数组
- (字符流是否可以拷贝非纯文本的文件)
- 不可以拷贝非纯文本的文件
- 因为在读的时候会将字节转换为字符,在转换过程中,可能找不到对应的字符,就会用?代替,写出的时候会将字符转换成字节写出去
- 如果是?,直接写出,这样写出之后的文件就乱了,无法重现
带缓冲的字符流)
- BufferedReader的read()方法读取字符时会一次读取若干字符到缓冲区, 然后逐个返回给程序, 降低读取文件的次数, 提高效率
- BufferedWriter的write()方法写出字符时会先写到缓冲区, 缓冲区写满时才会写到文件, 降低写文件的次数, 提高效率
BufferedReader br = new BufferedReader(new FileReader("aaa.txt")); //创建字符输入流对象,关联aaa.txt BufferedWriter bw = new BufferedWriter(new FileWriter("bbb.txt")); //创建字符输出流对象,关联bbb.txt int ch; while((ch = br.read()) != -1) { //read一次,会先将缓冲区读满,从缓冲去中一个一个的返给临时变量ch bw.write(ch); //write一次,是将数据装到字符数组,装满后再一起写出去 } br.close(); //关流 bw.close();
readLine()和newLine()方法,整行读写
- BufferedReader的readLine()方法可以读取一行字符(不包含换行符号)
- BufferedWriter的newLine()可以输出一个跨平台的换行符号”\r\n”
BufferedReader br = new BufferedReader(new FileReader("aaa.txt")); BufferedWriter bw = new BufferedWriter(new FileWriter("bbb.txt")); String line; //等同于 String line = null; while((line = br.readLine()) != null) { bw.write(line); //bw.write("\r\n"); //只支持windows系统 bw.newLine(); //跨平台的 } br.close(); bw.close();
ReadLine() 方法只存在于 BufferedReader() ;NewLine() 方法只存在于 BufferedWriter()。在FileReader和FileWriter中是没有这两种方法的。
装饰设计模式:
方法:
1. 获取到被包装的类的引用
2. 通过构造函数创建对象的时候,传入被包装的对象
3. //对其原有功能进行升级
优势:- 耦合性不强,被装饰的类的变化与装饰类的变化无关
编码表–CharSet
流程:(使用指定码表的转换流)
(utf-8).txt–>FileInputStream–>InputStreamReader(字节流,编码表),字节转行为字符–>BufferedReader–>Java程序–>BufferedWriter–>OutPutStreamWriter(字节流,编码表),字符转化为字节–>FileOutputStream–>(gbk).txt实例:获取给定文本的每种字符出现的个数
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.TreeMap; public class Test3 { /** * 获取一个文本上每个字符出现的次数,将结果写在times.txt上 * * 分析: * 1,创建带缓冲的输入流对象 * 2,创建双列集合对象TreeMap * 3,将读到的字符存储在双列集合中,存储的时候要做判断,如果不包含这个键,就将键和1存储,如果包含这个键,就将该键和值加1存储 * 4,关闭输入流 * 5,创建输出流对象 * 6,遍历集合将集合中的内容写到times.txt中 * 7,关闭输出流 * @throws IOException */ public static void main(String[] args) throws IOException { //1,创建带缓冲的输入流对象 BufferedReader br = new BufferedReader(new FileReader("zzz.txt")); //2,创建双列集合对象TreeMap TreeMap<Character, Integer> tm = new TreeMap<>(); //3,将读到的字符存储在双列集合中,存储的时候要做判断,如果不包含这个键,就将键和1存储,如果包含这个键,就将该键和值加1存储 int ch; while((ch = br.read()) != -1) { char c = (char)ch; //强制类型转换 /*if(!tm.containsKey(c)) { tm.put(c, 1); }else { tm.put(c, tm.get(c) + 1); }*/ tm.put(c, !tm.containsKey(c) ? 1 : tm.get(c) + 1); } //4,关闭输入流 br.close(); //5,创建输出流对象 BufferedWriter bw = new BufferedWriter(new FileWriter("times.txt")); //6,遍历集合将集合中的内容写到times.txt中 for(Character key : tm.keySet()) { switch (key) { case '\t': bw.write("\\t" + "=" + tm.get(key)); break; case '\n': bw.write("\\n" + "=" + tm.get(key)); break; case '\r': bw.write("\\r" + "=" + tm.get(key)); break; case ' ': bw.write("space" + "=" + tm.get(key)); break; default: bw.write(key + "=" + tm.get(key)); //写出键和值 break; } bw.newLine(); } //7,关闭输出流 bw.close(); } }
学习日记44--java学习--I/O流1
最新推荐文章于 2023-07-14 20:00:40 发布