IO流
IO流和容器
1. IO流
IO流图
1.1. IO概念
流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。
1.2. 数据源
data source. 提供原始数据的原始媒介。常见的:数据库、文件、其他程序、内存、网络连接、IO设备。数据源就像水箱,流就像水管中流着的水流,程序就是我们最终的用户。 流是一个抽象、动态的概念,是一连串连续动态的数据集合
1.3. IO流的分类
最长用到的 :
1.3.1. 字节流
-
输入流(InputStream)
-
操作步骤
-
选择流InputStream
-
操作流(写入或写出)
-
释放系统资源
-
-
示例
//这里是直接抛出异常 public class IO_Demo01 { public static void main(String[] args) throws IOException { //1、创建流 //FileInputStream 文件字节输入流,专门用来读入文件中数据内容的 InputStream is01=new FileInputStream("E:/test.txt"); //2、操作流 //读入到arr中的字节个数 int len=-1; byte[] arr=new byte[1024*2];//1024的整数倍 while ((len=is01.read(arr))!=-1){ System.out.println(new String(arr, 0, len)); } //3、关闭资源 is01.close(); } }
//try...catch 捕获异常,推荐这种做法 public class CopyFile01 { public static void main(String[] args) { //1、创建流 InputStream is=null; try { is=new FileInputStream("E:/aaa.txt"); //操作流 byte[] arr=new byte[1024];//按照1024 批量输入 int len=-1; while ((len=is.read(arr))!=-1){ System.out.println(new String(arr, 0, len)); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { //关闭 if(is!=null){ try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
-
-
输出流(OutputStream)
-
操作步骤
-
选择流
-
操作流
-
刷新(flush)
-
关闭系统资源
-
-
示例
/* FileOutputStream(String name) 创建一个向具有指定名称的文件中写入数据的输出文件流。 FileOutputStream(String name, boolean append) 创建一个向具有指定 name 的文件中写入数据的输出文件流。 FileOutputStream(File file) 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。 FileOutputStream(File file, boolean append) */ public class IODemo02 { public static void main(String[] args) throws IOException { //1.选择流 //输出流指向的文件,不存在,系统会自动创建,但是不会创建文件夹 OutputStream os=new FileOutputStream("E:/AAA.txt",true); //2.写出 write(int) 写出一个字节 byte[] arr = "今天是周二,开会不要忘记了!!!".getBytes(); os.write(arr); //3.刷出 os.flush(); //4.关闭 os.close(); } }
-
输入流和输出流
//将E盘下aaa.txt的内容拷贝到D盘下aaa.txt中 public class CopyFile01 { public static void main(String[] args) { //1、创建流 InputStream is=null; OutputStream os=null; try { is=new FileInputStream("E:/aaa.txt"); os=new FileOutputStream("D:/aaa.txt"); //2、操作流 byte[] arr=new byte[1024]; int len=-1; while ((len=is.read(arr))!=-1){ os.write(arr,0,len); } //3、刷新 os.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { //4、关闭 //先打开的后关闭 if(os!=null){ try { os.close(); } catch (IOException e) { e.printStackTrace(); } } if(is!=null){ try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
-
1.3.2. 字符流
-
字符输入流(Reader)
只能读纯文本文件
-
操作步骤
-
选择流
-
操作流
-
关闭系统资源
-
-
示例
public class IO_RWer { public static void main(String[] args) throws IOException { //1、创建流 Reader rd=new FileReader("E:/aaa.txt"); //2、操作流(读入) char[] arr=new char[1024]; int len=-1; while ((len=rd.read(arr))!=-1){ System.out.println(new String(arr,0,len)); } //3、关闭 wt.close(); rd.close(); } }
public class IO_RWer { public static void main(String[] args) throws IOException { //1、创建流 Reader rd=new FileReader("E:/aaa.txt"); Writer wt=new FileWriter("E:/BBB.txt"); //2、读入和写出 char[] arr=new char[1024]; int len=-1; while ((len=rd.read(arr))!=-1){ wt.write(arr); } //3、刷新 wt.flush(); //4、关闭 wt.close(); rd.close(); } }
-
1.3.3. 缓冲流
BufferedInputStream
缓冲提高性能: 字节流直接套上即可;字符缓冲流 +新增方法(不能使用多态):
//1、创建源,建立联系 File src =new File("test.txt"); //2、选择缓冲流 InputStream is =new BufferedInputStream(new FileInputStream(src)); //3、操作 : 多个读取 byte[] car =new byte[2]; int len =0; while(-1!=(len=is.read(car))){ //获取数组的内容 字节数组转字符串 new String(字节数组,0,length) System.out.println(new String(car,0,len)); } //4、释放资源 is.close();
1.3.4. 转换流
转换流:将字节流转为字符流 处理乱码(编码集、解码集)。
//读取文件 File src =new File("test.txt"); //转换流 BufferedReader br =new BufferedReader( new InputStreamReader(new BufferedInputStream(new FileInputStream(src)),"utf-8" ) ); //行读取 String msg =null; while(null!=(msg =br.readLine())){ System.out.println(msg); } br.close();
1.3.5. 数据处理流
可以处理基本类型+String,保留数据的类型。前提是读取顺序与写出顺序一致,否则读取数据不正确
/** * 数据+类型 输出到文件 */ public static void write(String destPath) throws IOException{ int point = 2; long num = 100L; String str = "数据类型"; //创建源 File dest = new File(destPath); //选择流 DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(dest))); //操作 写出的顺序 为读取作准备 dos.writeInt(point); dos.writeLong(num); dos.writeUTF(str); //刷新 dos.flush(); //释放资源 dos.close(); }
1.3.6. 对象流
以前我们学过的流都只能读写字节,字符形式的数据,而java中非常重要并且常见的对象类型的数据,如果想要存储到文件中应该怎么操作呢?这个时候就使用到了对象流。
-
序列化:是一个用于将对象状态转换为字节流的过程,可以将其保存到磁盘文件中或通过网络发送到任何其他程序
-
反序列化:从字节流创建对象的相反的过程称为 反序列化
-
对象处理流(反序列化):ObjectInputStream:
-
ObjectInputStream能够让你从输入流中读取Java对象,而不需要每次读取一个字节。你可以把InputStream包装到ObjectInputStream中,然后就可以从中读取对象了
-
首先在使用ObjectInputStream和ObjectOutputStream的时候,放置在此IO中的对象,必须要实现Serializable
-
序列化接口(Serializable实现了此接口,代表我们的对象支持序列化)但是实现了Serializable接口之后,其中并没有实现任何方法,对于这种接口,我们称之为标记接口。
-
-
反序列化:
-
先写入再读取
-
读取对象需要知道具体类型,依次读取
-
-
注意:
-
1)不是所有的对象都可以序列化 Serializable
-
2)不是所有的属性都需要序列化 transient
View Codepublic static void read(String srcPath) throws FileNotFoundException, IOException, ClassNotFoundException{ //创建源 File src=new File(srcPath); //选择流 OjbectInputStream ObjectInputStream dis=new ObjectInputStream( new BufferedInputStream( new FileInputStream(src) ) ); //操作 读取的顺序与写出的顺序一致 必须存在才能读取 Object obj=dis.readObject(); if(obj instanceof Employee){ Employee emp=(Employee)obj; System.out.println(emp.getName()); System.out.println(emp.getSalary()); } obj=dis.readObject(); int[]arr=(int[])obj; System.out.println(Arrays.toString(arr)); //释放资源 dis.close(); }
-
-
ObjectOutputStream(序列化) 注意: 要先序列化后反序列化
View Code//创建源 File dest=new File(destPath); //选择流 OjbectOutputStream ObjectOutputStream dos=new ObjectOutputStream( new BufferedOutputStream(new FileOutputStream(dest)) ); //操作 读取的顺序与写出的顺序一致 必须存在才能读取 Employee obj=new Employee ("yinwei",1500); dos.writeObject(obj); //刷出 dos.flush(); //释放资源 dos.close();
1.4. commons-IO
commons-IO是apache的一个开源的工具包,封装了IO操作的相关类,使用Commons IO可以很方便的读写文件,url 源代码等。commons-IO 需要加入classpath 的第三方 jar 包内的 class 文件才能在项目中使用
-
导入 commons-io jar包
-
commons-io-2.4.jar 就是需要导入到项目中的 jar 包,里面存放的是class文件
-
commons-io-2.4-sources.jar 工具类中原代码
-
docs 是帮助文档
-
导入 commons-io build path->add to build path
-
commons-io 的使用
3.1. IO 工具类 FilenameUtils 这个工具类是用来处理文件名(文件路径)的,可以轻松解决不同操作系统文件名称规范不同的问题,里面的方法都是静态的,直接用类进行调用
-
常用方法:
-
getName():获取文件名 getExtension(String path):获取文件的扩展名 isExtension(String fileName,String ext):判断fileName是否是ext后缀名
-
3.2. 工具类 FileUtils
提供文件操作,如移动文件、读取文件、检查文件是否存在等的方法
-
常用方法:
-
readFileToString(File file,String charset):读取文件内容,并返回一个String writeStringToFile(File file,String content, String charset):将内容content写入到file中
-
copyDirectoryToDirectory(File srcDir,File destDir):文件夹复制 copyFile(File srcFile,File destFile):文件复制
-
-
2. 容器
2.1. 容器的概念
之前我们学习过数组,数组是相同数据类型的有序集合,可以在其中放置对象或基本类型数据,说白了就是容器。 数组是一种简单的线性序列,可以快速的访问数组元素,效率高
2.2. Collection接口
Collection 表示一组对象,它是集中,收集的意思,就是把一些数据收集起来,Collection 接口的两个子接口:
-
Set 中的数据没有顺序,不可重复
-
List 中的数据有顺序,可重复
2.2.1. List接口
-
<E> 泛型
增强程序的可读性和稳定性。
-
ArrayList
ArrayList 是 List 的子类,允许存放重复元素,因此有序。集合中元 素被访问的顺序取决于集 合的类型。如果对 ArrayList 进行访问,迭代器将从索引 0 开始, 每迭代一次,索引值加 1。
-
List集合遍历
-
普通for循环方式
-
增强for循环方式
-
迭代器
-
Stream流遍历
View Codepublic class LIstDemo03 { public static void main(String[] args) { List<Integer> ls= new ArrayList(); ls.add(3); ls.add(1); ls.add(2); ls.add(7); ls.add(6); ls.add(5); //void add(int index, E element) ls.add(3,3); System.out.println(ls); // E get(int index) System.out.println(ls.get(0)); // int indexOf(Object o) System.out.println(ls.indexOf(2)); //remove(int index) ls.remove(2); System.out.println(ls); // E set(int index, E element) System.out.println(ls.set(2,2)); System.out.println(ls); //遍历方式: System.out.println("--------for普通-------"); for(int i = 1;i<ls.size();i++) { System.out.println(ls.get(i)); } System.out.println("--------for..each-------"); for(int i:ls) { System.out.println(i); } System.out.println("--------iterator-------"); Iterator<Integer> it = ls.iterator(); while(it.hasNext()) { System.out.println(it.next()); } } }
-
-
LinkedList
LinkedList 是一种可以在任何位置进行高效地插入和删除操作的有序序列。底层用双向链表实现的 List。特点:查询效率低,增删效率高,线程不安全。
ArrayList:底层用数组实现的 List。特点:查询效率高,增删效率低,线程不安全。
View Codepublic class LInkedList { public static void main(String[] args) { LinkedList<Person> linklist=new LinkedList<Person>(); linklist.add(new Person(33,"李小龙")); linklist.add(new Person(23,"李连杰")); linklist.add(new Person(33,"李广")); linklist.add(new Person(33,"李世民")); System.out.println(linklist.size()); linklist.add(2,new Person(45,"李逍遥")); System.out.println(linklist); linklist.remove(2); System.out.println(linklist); linklist.set(0,new Person(18,"李小龙")); System.out.println(linklist); } }

浙公网安备 33010602011771号