1.FileOutputStream文件字节输出流
作用:把内存中的数据写入到硬盘当中
构造方法
public FileOutputStream(File file) :创建文件输出流以写入由指定的 File对象表示的文件。
public FileOutputStream(String name) : 创建文件输出流以指定的名称写入文件。
当你创建一个流对象时,必须传入一个文件路径。该路径下,如果没有这个文件,会创建该文件。如果有这个文件,会清空这个文件的数据。
写入数据的原理:(内存 - - > 硬盘)
Java程序 - - > JVM(java虚拟机)- - > OS(操作系统)- - > OS调用写数据的方法 - - > 把数据写入文件当中
public class OUTPutStream { public static void main(String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("D:\JA\Part1-basic\src\basicpart\day01\StreamM\a.txt"); fos.write(95); fos.close(); } }
一次写多个字节:
如果写的第一个字节是正数(0-127),那么显示的时候会查ASCII码表
如果写的第一个字节是负数,那第一个字节会和第二个字节,两个字节组成一个中文显示,查询系统默认码表(GBK)
写出指定长度字节数组: write(byte[] b, int off, int len) ,每次写出从off索引开始,len个字节
写入字符串的方法:可以使用String类中的方法把字符串,转换为字节数组
byte【】 getBytes() 将字符串转换为字节数组
public class OUTPutStream { public static void main(String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("D:\JA\Part1-basic\src\basicpart\day01\StreamM\a.txt"); byte[] bytes = "chris".getBytes(); System.out.println(Arrays.toString(bytes)); fos.write(bytes); fos.close(); } }
续写和换行,在构造方法中将append参数设置为true
Windows换行符号:
Linux:/n
mac:/r
public class OUTPutStream { public static void main(String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("D:\JA\Part1-basic\src\basicpart\day01\StreamM\a.txt",true); fos.write("你好 ".getBytes()); fos.write("咋啦 ".getBytes()); fos.close(); } }
2.FileInputStream 文件字节输入流
public class FileINputStream { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("Part1-basic\src\basicpart\day01\StreamM\a.txt"); //相对路径 int len = 0; //记录读取到的字节 //循环遍历文件 while ((len = fis.read()) != -1) { System.out.print(len); } fis.close(); } }
一次读取多个字节的方法:
public class FileINputStream { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("Part1-basic\src\basicpart\day01\StreamM\a.txt"); //相对路径 byte[] bytes = new byte[4];//建立一个能装四个字节的数组 int len = fis.read(bytes); //此时bytes里面会从文件中抓取前四个字节放入到数组中 System.out.println(len);//len表示的是读取的有效字节个数 System.out.println(Arrays.toString(bytes)); System.out.println(new String(bytes)); } }
改进方法:
public class FileINputStream { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("Part1-basic\src\basicpart\day01\StreamM\a.txt"); //相对路径 byte[] bytes = new byte[1024];//建立一个能装1024个字节的数组 int len = 0; while ((len = fis.read(bytes)) != -1) { System.out.println(new String(bytes, 0, len)); //len为有效字节个数 } } }
文件复制:
public class FileCopy { public static void main(String[] args) throws IOException { long startTime = System.currentTimeMillis(); FileInputStream fis = new FileInputStream("D:\Baseball\cai.jpg");//创建文件字节输入流 读取数据 FileOutputStream fos = new FileOutputStream("D:\AAD\cai.jpg");//创建文件字节输出流 写入数据 int len = 0;//记录读取的有效字节 byte[] bytes = new byte[1024];//一次多读一些 while ((len = fis.read(bytes)) != -1){ fos.write(bytes,0,len);//用字节输出流把读取到的字节写入到文件中 } //释放资源,先关写的 fos.close(); fis.close(); long endTime = System.currentTimeMillis(); System.out.println("复制文件的时间"+(endTime - startTime)+ "毫秒"); } }
3.文件字符输入流 FileReader
读取文件:
public class FR { public static void main(String[] args) throws IOException { FileReader fr = new FileReader("Part1-basic\src\basicpart\day01\StreamM\a.txt"); char[] cs = new char[1024];//用来存储读取到的多个字符 int len = 0;//记录的是每次读取的有效字符个数 while ((len = fr.read(cs)) != -1) { System.out.print(new String(cs, 0, len)); } } }
4.文件字符输出流 FileWriter 写入时先写入内存缓冲区中 因为要把字符转换为字节 flush一下就行了
public class FR { public static void main(String[] args) throws IOException { FileWriter fw = new FileWriter("Part1-basic\src\basicpart\day01\StreamM\b.txt",true); fw.write(98); char[] cs = {'a','c','e'}; fw.write(cs); fw.write("帅哥"); fw.flush(); fw.close(); } }
5.处理流中异常相关问题
变量在定义的时候可以没有值,但在使用的时候必须有值
public class FR { public static void main(String[] args) { FileWriter fw = null;//提高变量的作用域,变量的值必须先定义,不然局部无法使用 try { fw = new FileWriter("r:Part1-basic\src\basicpart\day01\StreamM\b.txt", true); fw.write("船只"); fw.flush(); } catch (IOException e) { System.out.println(e); } finally { //如果创建对象失败了,那么fw的默认值为空,就会抛出空指针异常,需要进行判断 if (fw != null) { try { fw.close();//本身存在异常,需要try catch } catch (IOException e) { e.printStackTrace(); } } } } }
JDK7的新特性 try()括号里放对象,作用域只在try里有效,而且自动释放
public class FR { public static void main(String[] args) { try (FileWriter fw = new FileWriter("r:Part1-basic\src\basicpart\day01\StreamM\b.txt", true)) { fw.write("船只"); fw.flush(); } catch(IOException e) { System.out.println(e); } } }
6.Properties属性集 双列集合(key和value默认都是字符串) 唯一一个和IO流相结合的集合
public Object setProperty(String key, String value) : 保存一对属性。
public String getProperty(String key) :使用此属性列表中指定的键搜索属性值。
public Set<String> stringPropertyNames() :所有键的名称的集合。
public class FR { public static void main(String[] args) { Properties prop = new Properties(); //存储属性值 prop.setProperty("chris","21"); prop.setProperty("joe","20"); prop.setProperty("Lin","23"); //获取此集合中的健集 Set<String> set = prop.stringPropertyNames(); //遍历set集合,取出每一个键 for (String key : set) { //使用方法得到值 String value = prop.getProperty(key); System.out.println(key + value); } } }
(1)public void load(InputStream inStream) : 从字节输入流中读取键值对。
参数中使用了字节输入流,通过流对象,可以关联到某文件上,这样就能够加载文本中的数据了。
(2)public void store(OutputStream out,String comment)
不能写入中文!!字节输出流
(3)public void store(Writer writer,String comment)
字符输出流,可以写入中文
注释不能使用中文,一般使用空字符串
public class FR { public static void main(String[] args) throws IOException { Properties prop = new Properties(); //存储属性值 prop.setProperty("chris","21"); prop.setProperty("joe","20"); prop.setProperty("Lin","23"); FileWriter fw = new FileWriter("D:\Baseball\cai.txt"); prop.store(fw,"sava data"); fw.close(); } }
7.缓冲流
缓冲流,也叫高效流,是对4个基本的 FileXxx 流的增强,所以也是4个流,按照数据类型分类:
字节缓冲流: BufferedInputStream , BufferedOutputStream
字符缓冲流: BufferedReader(特有方法readline,无数据时返回null,末尾不含任何终止符,需自己换行) , BufferedWriter(提供了个newline方法来换行)
缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写的效率。
public class Buffered { public static void main(String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("D:\JA\Part1-basic\src\basicpart\day01\StreamM\f.txt",true); BufferedOutputStream bos = new BufferedOutputStream(fos); bos.write("我是帅哥".getBytes()); bos.flush(); bos.close(); } }
复制文件的效率大大提升:
public class Buffered { public static void main(String[] args) throws IOException { long s = System.currentTimeMillis(); BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\JA\Part1-basic\src\basicpart\day01\StreamM\f.txt")); FileOutputStream fos = new FileOutputStream("D:\JA\Part1-basic\src\basicpart\day01\StreamM\g.txt",true); BufferedOutputStream bos = new BufferedOutputStream(fos); byte[] bytes = new byte[1024]; int len = 0; while ((len = bis.read(bytes))!= -1){ bos.write(bytes,0,len); } bis.close(); bos.close(); long e = System.currentTimeMillis(); System.out.println("共耗时" + (e-s) + "毫秒"); } }
文本排序练习!!!重点
public class TextSort { public static void main(String[] args) throws IOException { //1.先创建hashmap集合对读取的数据进行存储 HashMap<String, String> map = new HashMap<>(); //2.创建两个流对象 BufferedReader reader = new BufferedReader(new FileReader("Part1-basic\src\basicpart\day01\StreamM\f.txt")); BufferedWriter writer = new BufferedWriter(new FileWriter("Part1-basic\src\basicpart\day01\StreamM\new.txt")); //3.使用readline方法来逐行读取文本 String line; //用来记录文本 while ((line = reader.readLine()) != null) { //4.对读取的文本进行切割 String[] arr = line.split("\."); //序号和文本以.来分割 //5.把切割好的键和值写入到hashmap中 map.put(arr[0], arr[1]); //每次读取时arr【0】为序号 arr【1】为文本 } //6.遍历hashmap集合 for (String key : map.keySet()){ String value = map.get(key); // 通过key获取value line = key + "." + value; //这就是完整的一条内容 //7.将数据写回去 writer.write(line); writer.newLine();//换行 } reader.close(); writer.close(); } }
8.转换流
转换流 java.io.InputStreamReader ,是Reader的子类,是从字节流到字符流的桥梁。它读取字节,并使用指定的字符集将其解码为字符。它的字符集可以由名称指定,也可以接受平台的默认字符集。
构造方法
InputStreamReader(InputStream in) : 创建一个使用默认字符集的字符流。
InputStreamReader(InputStream in, String charsetName) : 创建一个指定字符集的字符流。
转换流 java.io.OutputStreamWriter ,是Writer的子类,是从字符流到字节流的桥梁。使用指定的字符集将字符编码为字节。它的字符集可以由名称指定,也可以接受平台的默认字符集。
构造方法
OutputStreamWriter(OutputStream in) : 创建一个使用默认字符集的字符流。
OutputStreamWriter(OutputStream in, String charsetName) : 创建一个指定字符集的字符流。
public class FileINputStream { public static void main(String[] args) throws IOException { OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("Part1-basic\src\basicpart\day01\StreamM\f.txt"),"gbk"); osw.write("你好"); osw.flush(); osw.close(); } }
9.序列化和反序列化流
序列化操作
1. 一个对象要想序列化,必须满足两个条件:
该类必须实现 java.io.Serializable 接口, Serializable 是一个标记接口,不实现此接口的类将不会使任何状态序列化或反序列化,会抛出 NotSerializableException 。
该类的所有属性必须是可序列化的。如果有一个属性不需要可序列化的,则该属性必须注明是瞬态的,使用transient 关键字修饰。
Static关键字修饰的变量是不能被序列化的,序列化的都是对象,因为static优先于对象进入到内存中
public class FileINputStream { public static void main(String[] args) throws IOException { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("Part1-basic\src\basicpart\day01\StreamM\f.txt")); oos.writeObject(new Person("chris",20)); //该类必须是标记接口的可序列化对象 oos.close(); } }