java-IO流,文件操作
思维导图:
简述:
1.流:从一端移动到另一端,源头与目的地
2.Io流分类:
(1)流向:输入流,输出流
(2)数据:
字节流:二进制,可以一切文件,包括,纯文本,doc,音频,视频等等
字符流:文本文件,只能处理文本文件
(3)功能:
节点:包裹源头
处理:增强功能,提供性能
3.字符流与字节流及文件
(1)字节流:
输入流:->InputStream:
read(byte[] b),
read(byte[] b,int off,int len),
close();
->FileInputStream
1 //文件读取 2 public void readFile(String PATH) throws IOException { 3 //获得当前路径下面的文件对象 4 Long start=System.currentTimeMillis(); 5 File file=new File(PATH); 6 InputStream in=null; 7 try{ 8 //创建输入流 9 in = new FileInputStream(file); 10 //创建缓冲区用于存放流中的二进制内容,大小为1M 11 byte [] bytes=new byte[1024*1024]; 12 int len=0; 13 while(-1!=(len=in.read(bytes))){ 14 in.read(bytes); 15 } 16 //进行文件读取 17 in.read(bytes); 18 }catch(Exception e){ 19 e.printStackTrace(); 20 }finally { 21 if(in!=null){ 22 in.close(); 23 } 24 } 25 System.out.println("程序耗时:"+(System.currentTimeMillis()-start)); 26 }
输出流:->OutputStream:
write(byte[] b),
write(byte[] b,int off,int len),
flush(),
close();
->FileOutputStream
1 //文件写入 2 public void writeFile(String PATH) throws IOException{ 3 OutputStream outputStream=null; 4 try{ 5 //创建输出流 6 outputStream=new FileOutputStream(new File(PATH)); 7 byte bytes[]=new String("hello").getBytes("UTF-8"); 8 //将文件内容写入字节数组l 9 outputStream.write(bytes); 10 outputStream.flush(); 11 12 }catch (IOException e){ 13 e.printStackTrace(); 14 }finally { 15 if(outputStream!=null){ 16 outputStream.close(); 17 } 18 } 19 }
(2)字符流:
输入流: ->Reader:
read(char[] cbuf),
read(char[] cb,int off,int len ),
close();
->FileReader
1 //用于测试字符输入流,读取字符 2 public void testReader() throws IOException{ 3 Reader reader=null; 4 try { 5 reader= new FileReader(new File(PATH)); 6 reader=new BufferedReader(new FileReader(new File(PATH))); 7 char c[]=new char[5]; 8 int len=0; 9 while(-1!=(len=reader.read())){ 10 reader.read(c); 11 } 12 System.out.println(Arrays.toString(c)); 13 }catch (Exception e){ 14 15 }finally{ 16 if(reader!=null){ 17 reader.close(); 18 } 19 } 20 }
输出流:->Writer:
write(char[] cbuf),
write(char[] cbuf,int off,int len),
flush(),
close();
->FileWriter
字符流:只能处理纯文本文件或者文本内容,全部为可见字符
类似输入流: Reader-> FileReader
类似输出流: Writer->FileWriter
1).纯文本读取
(1)建立联系
(2)选择流 Reader-> FileReader
(3)读取 char[] charRead=new char[1024]
(4)关闭流
2).纯文本写出
(1)建立联系
(2)选择流 Writer-> FileWriter
(3)写入 char[] charWrite=new char[1024]
(4)关闭流
4.处理流
处理流:增强功能,提供性能(在节点流之上)
1).缓冲流
(1)字节缓冲流
BufferedInputStream
//缓冲流 public void testBufferedStream() throws IOException{ Long start=System.currentTimeMillis(); BufferedInputStream inputStream=null; try { inputStream= new BufferedInputStream(new FileInputStream(new File(PATH))); byte [] b=new byte[1024*1024]; int len=0; while(-1!=(len=inputStream.read(b))) { inputStream.read(b); } System.out.println(Arrays.toString(b)); }catch (IOException e){ }finally { if(inputStream!=null){ inputStream.close(); } } System.out.println("程序耗时:"+(System.currentTimeMillis()-start)); }
BufferedOutputStream
(2)字符缓冲流
BufferedReader
BufferedWriter
2).转换流 -> 字节流转化为字符流 处理乱码(编码集,解码集)
(1)编码与解码的概念:
编码: 字符 ->编码字符集->二进制
解码: 二进制->解码字符集->字符
(2)乱码:
编码与解码的字符集不一致
字节缺少,长度丢失
5.其他流
节点流:
1.字节数组 字节 节点流
输入流:ByteArrayInputStream
输出流:ByteArrayOutputStream
1 //测试节点流 2 public void testByteArrayStream() throws IOException{ 3 ByteArrayInputStream inputStream=null; 4 byte[] bytes=null; 5 try { 6 bytes= new String("hello").getBytes("UTF-8"); 7 inputStream= new ByteArrayInputStream(bytes); 8 inputStream.markSupported(); 9 //当前流在索引为1的位置上标记 10 inputStream.mark(1); 11 inputStream.read(bytes); 12 //设置再次读取的内容限制在索引1位置及之前 13 inputStream.reset(); 14 }catch (Exception e){ 15 16 } 17 finally { 18 if(inputStream!=null){ 19 inputStream.close(); 20 } 21 } 22 System.out.println(Arrays.toString(bytes)); 23 }
处理流:
1.基本类型String 保留数据+类型
输入流:DataInputStream readXxx()
输出流:DataOutputStream writeXxx();
2.引用类型(对象) 保留数据+类型
反序列化 输入流:ObjectInputStream readObject()
序列化 输出流 :ObjectOutputStream writeObject()
1 //一般用于对象的序列化保存以及反序列化操作,被操作的对象需要实现序列化接口Serializable 2 public void testObjectStream() throws IOException{ 3 ObjectOutputStream outputStream=null; 4 try { 5 //将对象的信息存储到本地文件上面 6 outputStream=new ObjectOutputStream(new FileOutputStream(new File(PATH))); 7 //将对象写入 8 outputStream.writeObject(new User(1,"张三")); 9 //创建输入流读取文件内容 10 ObjectInputStream inputStream=new ObjectInputStream(new FileInputStream(new File(PATH))); 11 //强制转换 12 User user=(User)inputStream.readObject(); 13 System.out.println(user); 14 }catch (Exception e){ 15 16 } 17 finally { 18 if(outputStream!=null) { 19 //关闭流 20 outputStream.close(); 21 } 22 } 23 }
//实体类实现序列化接口 class User implements Serializable { private int id; private String name; public User(int id, String name) { this.id = id; this.name = name; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + '}'; } }
注意:
先序列化后反序列化,反序列化顺序必须与序列化一致;
不是所有的对象都可以序列化:java.io.Serializable
不是所有的属性都需要序列化 :transient ->(透明的)
6.操作:
读取文件->建立与文件的联系->选择对应流->读取/写出->定义数组大小->读取/写出->释放资源
文件->流操作代码:
1 /* 2 * 两个常量:路径分割符,文件分割符:File.pathSeparator(),File.Separator(); 3 * 文件的读取,写入,创建 4 * 操作目录:mkdir(),父目录必须存在,如果不存在创建失败,mkdirs(),无要求,若父目录不存在直接新建,相当于新建一条文件目录链 5 * list(),返回文件名,目录名的字符串形式,需用数组进行存储。 6 * listFiles();返回子文件或子目录的抽象File对象,可利用for循环获取相关信息 7 */ 8 public class FileIO { 9 10 public static void main(String[] args) throws IOException { 11 System.out.println("***文件读取***"); 12 readFile("test.txt"); 13 System.out.println("***文件目录查看***"); 14 showDir("F:/Test"); 15 System.out.println("***创建目录***"); 16 makeDir("F:/span"); 17 System.out.println("***获取文件部分信息***"); 18 getfileInfo("test.txt"); 19 System.out.println("***简单信息写入文件***"); 20 writeFileTest("F:/test.txt"); 21 System.out.println("***输入流数据写入输出流***"); 22 writeFileFromInputStream("F:/test.txt","E:/test.txt"); 23 System.out.println("***文件递归读取文件信息***"); 24 readFolder("F:/Test"); 25 copyDir("F:/测试","F:/Test1"); 26 } 27 28 public static void readFile(String path) throws IOException { 29 //相对路径,直接从当前工作目录读取路径 30 File file=new File(path); 31 //文件写入io流,然后写入byte数组,转String字符串输出 32 InputStream fis=new BufferedInputStream(new FileInputStream(file)); 33 //建立缓冲区大小与文件大小一致 34 byte[] b=new byte[fis.available()]; 35 fis.read(b); 36 //关闭流 37 fis.close(); 38 System.out.println(new String(b)); 39 } 40 41 public static void showDir(String path) { 42 //建立路径并将其文件引入 43 File file=new File(path); 44 //判断文件是否存在 45 System.out.println(file.exists()); 46 //判断是否为目录 47 System.out.println(file.isDirectory()); 48 //获取绝对路径 49 System.out.println(file.getAbsolutePath()); 50 //利用String 数组存放文件名和目录名 51 String[] src=file.list(); 52 //循环遍历 53 for(String name:src) { 54 System.out.println(name); 55 } 56 System.out.println("************************"); 57 //另一种形式获取 58 File[] sf=file.listFiles(); 59 for(File name:sf) { 60 System.out.println(name); 61 } 62 } 63 64 //新建目录/新建目录链 65 public static void makeDir(String path) { 66 File file=new File(path); 67 //由于span目录不存在,所以调用file.mkdir()并没有真正实现目录的创建 68 boolean bo=file.mkdir(); 69 System.out.println(bo?"成功":"失败"); 70 boolean bool=file.mkdirs(); 71 System.out.println(bool?"成功":"失败"); 72 } 73 74 //获取当前文件的具体信息 75 public static void getfileInfo(String path) { 76 File file=new File(path); 77 //获取相对路径 78 System.out.println(file.getParent()); 79 //获取文件袋绝对路径 80 System.out.println(file.getAbsoluteFile()); 81 //判断是否为绝对路径 82 System.out.println(file.isAbsolute()); 83 } 84 85 //将信息写入文件 86 public static void writeFileTest(String path) throws IOException { 87 File file=new File(path); 88 //定义输出流将信息存放至指定文件下 89 OutputStream in=new BufferedOutputStream(new FileOutputStream(file)); 90 //初始化输入数据->byte的数字范围-128~127 91 byte[] b=new byte[50]; 92 for(byte i=0;i<50;i++) { 93 b[i]=i; 94 } 95 in.write(b); 96 //关闭资源 97 in.close(); 98 99 } 100 //从输入流读取数据放入输出流然后写入新文件 ps:即实现了文件的拷贝 readpath读取文件路径,writepath写入文件路径 101 public static void writeFileFromInputStream(String readpath,String writepath) throws IOException { 102 //路径引入,文件获取 103 File fileIn=new File(readpath); 104 File fileOut=new File(writepath); 105 copyFile(fileIn,fileOut); 106 } 107 108 //实现文件复制:根据现实情景改进方法 109 public static void copyFile(File fileread,File filewrite) throws IOException { 110 //文件输入流 111 InputStream inStream=new BufferedInputStream(new FileInputStream(fileread)); 112 //定义缓冲区大小 113 byte[] b=new byte[inStream.available()]; 114 //读入流 115 inStream.read(b); 116 //关闭流 117 inStream.close(); 118 //文件输出流 119 OutputStream outStream=new BufferedOutputStream(new FileOutputStream(filewrite)); 120 //写入流 121 outStream.write(b); 122 //关闭流 123 outStream.close(); 124 } 125 126 //利用递归读取文件,将递归读取的文件以list集合的形式返回 127 public static ArrayList<File> readFolder(String path) throws IOException{ 128 ArrayList<File> fileList=new ArrayList<File>(); 129 File file=new File(path); 130 if(file.exists()) { 131 //判断该文件是否为目录 132 if(file.isDirectory()){ 133 //定义一个文件数组用于存放文件夹file下面的所有文件 134 File[] files=file.listFiles(); 135 for(File file3: files){ 136 //如果这个文件为目录 137 if(file3.isDirectory()){ 138 //递归读文件夹 139 readFolder(file3.getAbsolutePath()); 140 } 141 else 142 //普通文件则将其放入集合中 143 fileList.add(file3); 144 //获取文件名 145 System.out.println("文件名称:"+file3.getName()); 146 } 147 } 148 }else { 149 System.out.println("不存在该路径!"); 150 } 151 return fileList; 152 } 153 154 //拷贝文件夹真正方法实现 155 public static void copyDir(String readpath,String writepath) throws IOException{ 156 //源目录 157 File file1=new File(readpath); 158 //目标目录 159 File file2=new File(writepath); 160 if(file1.isDirectory()) { 161 file2=new File(readpath,file1.getName()); 162 } 163 if(file2.getAbsolutePath().contains(file1.getAbsolutePath())){ 164 System.out.println("父目录不能拷贝在子目录中!"); 165 return; 166 } 167 copyFileDetail(file1,file2); 168 169 } 170 171 //拷贝文件方法具体细节实现 172 private static void copyFileDetail(File file1, File file2) throws IOException { 173 //是文件则直接复制 174 if(file1.isFile()) { 175 copyFile(file1,file2); 176 } 177 //文件夹 178 else if(file1.isDirectory()) { 179 //创建目录与file1目录对应 180 file2.mkdirs(); 181 //获取下一级目录,递归 182 for(File dir:file1.listFiles()) { 183 copyFileDetail(dir,new File(file2,dir.getName())); 184 } 185 } 186 } 187 }
效果截图:
1.控制台:
2.具体文件:
教师信息文件的读取以及写入新文件:
实例:
1 package com.test; 2 3 import java.io.BufferedInputStream; 4 import java.io.BufferedOutputStream; 5 import java.io.File; 6 import java.io.FileInputStream; 7 import java.io.FileOutputStream; 8 import java.io.IOException; 9 import java.io.InputStream; 10 import java.io.OutputStream; 11 12 /** 13 * 现在对基本的文件操作已经比较熟悉,所以现在利用面向对象的理念实现教师信息从文本文件中获取 14 * 1.具体步骤 15 * (1)读取文件信息并利用缓冲流进行性能优化 16 * (2)进行编码管理,防止出现乱码,默认时编码为一致的,所以不担心乱码 17 * 2.读取完数据后,新建一个文件将读取出来的数据存放过去 18 * 2019年4月30日 19 */ 20 public class TeacherInfo { 21 22 public static void main(String[] args) throws IOException { 23 24 /*getInfo("C:/Users/Administrator/Desktop/教师信息录入.txt");*/ 25 writeInfo("C:/Users/Administrator/Desktop/教师信息录入.txt","C:/Users/Administrator/Desktop/test.txt"); 26 27 } 28 29 //文件信息读取 30 public static void getInfo(String path) throws IOException { 31 File file=new File(path); 32 //输入流初始化 33 InputStream filein=new BufferedInputStream(new FileInputStream( file)); 34 //建立缓冲区,存放数据 35 byte[] by=new byte[filein.available()]; 36 //数据读入 37 filein.read(by); 38 //关闭流 39 filein.close(); 40 System.out.println(new String(by)); 41 } 42 //文件信息写入新文件,流处理,为方便还是依旧重写输入流 43 public static void writeInfo(String readpath,String writepath) throws IOException{ 44 //文件信息引入 45 File filein=new File(readpath); 46 File fileout=new File(writepath); 47 //流初始化 48 InputStream streamIn=new BufferedInputStream(new FileInputStream(filein)); 49 OutputStream streamOut=new BufferedOutputStream(new FileOutputStream(fileout)); 50 byte[] by=new byte[streamIn.available()]; 51 //数据填充 52 streamIn.read(by); 53 streamIn.close(); 54 System.out.println(new String(by)); 55 //数据写入 56 streamOut.write(by); 57 streamOut.close(); 58 } 59 }
效果截图:
文章若有不当之处欢迎指正,必定加以改正,虚心求学。