java中 File类 和 IO流相关操作

张开发
2026/4/17 13:25:46 15 分钟阅读

分享文章

java中 File类 和 IO流相关操作
文章目录1. file类的使用1 概述2) 构造方法3 相对路径和绝对路径4File类的获取方法5File类的判断方法6File类的创建方法7File类的删除方法8File类的遍历方法9File类的递归方法10文件过滤器2. IO流1 概述2字节与字符3 IO流顶层分类4 字节输入流5 字节输出流6 字符输入流7 字符输出流8 字节流和字符流的区别9 IO流的异常处理操作10 IO流总结11 IO流分类3. 缓冲流1分类2特点3使用步骤4字节输入缓冲流5字节输出缓冲流6字符输入缓冲流7字符输出缓冲流8 字符缓冲流的特殊方法4. 转换流1编码表2转换流的作用3 InputStreamReader4 OutputStreamWriter5) 关系5. 序列化流1 序列化流ObjectOutputStream2 反序列化流ObjectInputStream3 序列化中的static4 序列化版本问题6. 打印流1 特点2 分类3 构造方法4 其他方法5 调用write()方法写出和调用print()方法写出的区别6 标准输出流7. Properties集合1) 介绍2 常用方法3使用步骤4具体示例1. file类的使用1 概述在现实中 1. 目录directory: 目录指的是文件夹用来存放文件。 2. 文件File: 文件用来保存一些数据。 3. 路径Path:指的是计算机的一个位置可以是文件的位置也可以是文件夹的位置。 在java中 1. 有一个类可以表示计算机中的文件和文件夹这个类叫File类。 2. 虽然File的本义是文件但是在java中File类既可以表示文件也可以表示文件夹。 3. 也就是说我们可以调用File类的一些方法来完成对文件或者是对文件夹的操作。 4. java.io.File类是文件和文件夹路径名的抽象表示所指向的路径对应的文件或者文件夹不一定真实存在。2) 构造方法1. file(String pathName) 参数是一个路径名称这个路径名称可以是文件也可以是文件夹。 2. file(String parent,String child) 参数是2个路径(父路径子路径)根据父路径和子路径组合构造成一个File对象。父路径和自路径都是字符串。 比如 现在有一个文件路径为 D:\it\aa\bb\cc\dd.txt 那么 对应的父路径 parent : D:\it\aa\bb\cc 对应的子路径 child : dd.txt 3. File(File parent,String child) 根据父路径和子路径组合构造一个File对象 。 父路径是 File 类型子路径是 String 类型。 因为父路径是File类型所以等于是先用构造方法构造一个父路径再去拼接一个子路径因为还有子路径所以这样构造的父路径一般是文件夹而不是文件。 注意点 使用构造方法可以创建出一个File对象这个File对象表示的是计算机中的一个文件或者文件夹 并且表示的这个文件或者文件夹可以在计算机中是实际存在的也可以是不存在的。3 相对路径和绝对路径1. 相对路径 一个不是特别详细的路径没有从盘符开始。 没有从盘符开始的路径就是 相对路径在idea中相对路径相对的是当前项目。 2. 绝对路径 是一个非常详细的路径绝对路径都是从盘符开始的。 从盘符开始书写的路径就是绝对路径。4File类的获取方法1. String getAbsolutePath() 获取此file对象表示的绝对路径(从盘符开始)。 如果创建的时候使用的是相对路径那么创建时的相对路径表示的是该项目下的相对路径。 获取到的还是从盘符开始的绝对路径。 2. String getPath() 获取此file对象表示的路径。 在创建file对象的时候给的是什么获取到的就是什么。 如果创建file对象的时候使用的是相对路径那么获取到的就是相对路径。 如果创建file对象的时候使用的是绝对路径那么获取到的就是绝对路径。 3. String getName() 获取此file对象表示的文件或者是文件夹的名字。 这个方法不在乎这个文件或者文件夹是否真实存在只要给一个路径就能获取到对应的名称。 其本质是截取的最后一个分隔符(\) 后的内容返回。 4. Long lenth() 获取此File对象表示的文件的字节数大小。 只能准确的获取文件的字节数大小如果是文件夹获取的是一个不固定的值(没法准确获取). 如果要获取的File对象表示的文件不存在那么结果为 0 。5File类的判断方法1. Boolean exists() 判断此file对象表示的文件或者文件夹是否真实存在。 2. Boolean isDirectory() 判断此file对象表示的 是否是一个真实存在的文件夹。 如果这个File对象表示的 确实是一个文件夹并且真实存在那么返回true 如果不是文件夹或者是文件夹但是不存在返回的都是false。 3. Boolean isFile() 判断此File对象表示的是否是一个真实存在的文件。 如果这个File对象表示的是一个真实存在的文件那么返回true 如果不是文件或者是文件但不是真实存在的那么返回的都是false。6File类的创建方法1. Boolean createNewFile() 创建一个文件如果文件已经存在那么创建失败。 如果创建文件时对应的上级目录不存在那么会报异常。 eg: File file new File“D:\\test\\aa.txt“; file.creatNewFile() ; //true 2. Boolean mkdir() 创建一个文件夹如果文件夹已经存在那么创建失败。 如果创建文件夹时上级目录不存在那么会创建失败 但是不会报错。 3. Boolean mkdirs() 创建一个文件夹如果文件夹已经存在那么创建失败。 如果创建文件夹时上级目录不存在那么会先自动创建上级目录再创建指定文件目录。 eg File file new File(“D:\\test\\aa\bb\cc”); file.mkdirs() ; //true 注 mkdir()只能创建单级目录mkdirs()可以创建多级目录使用的时候一般用mkdirs()比较多用mkdir()较少。7File类的删除方法1. Boolean delete () 删除一个文件或者是文件夹。 注意点 a. 如果delete删除的是一个文件夹那么这个文件夹必须是空文件夹否则删除失败不能删除。 b. 调用delete()方法删除时不会走回收站而是直接彻底删除所以需要特别注意小心误删。8File类的遍历方法1. String[ ] list() 获取指定目录下的所有文件和文件夹返回字符串数组。 数组里面放的是所有文件和文件夹的名字跟getName()方法获取的一样。 2. File[ ] listFiles() 获取指定目录下的文件和文件夹返回的是File数组。 可以直接对File数组进行其他操作。 3. File[ ] listFiles(FileFilter fileFilter) 传递一个文件过滤器接口的子类实现可以按照指定的规则对文件进行过滤返回符合要求的文件或者文件夹。 注意点 1. 如果File对象表示的是一个文件而不是文件夹那么调用listFiles()方法得到的是 null如果遍历会报空指针异常 。 2. 如果File对象表示的是一个空的文件夹那么调用listFiles()方法得到的是一个空的数组{ }遍历时没有内容但不会报错。 4. static File[ ] listRoots() 列举出操作系统的根目录。9File类的递归方法1. 概念 递归指的是 方法直接或者间接的调用方法本身。 2. 包括的内容 直接递归 A--A 间接递归 A--B B--C C--A 3. 可能产生的问题 内存溢出内存不够用的情况。 内存泄漏有些对象虽然没有用了但是却不能够被回收这种现象就是内存泄漏。 内存泄漏会导致内存溢出。 4. 递归注意点 a. 递归要有结束的条件 b. 因为递归比较占用栈内存所以递归的循环次数不能太多否则会造成栈内存溢出。10文件过滤器1. 定义 文件过滤器接口涉及的类为 java.io.FileFilter 。 2. 可以作为listFiles()方法的 传入参数。 3. 接口中有且只有一个抽象方法 boolean accept (File file ) 。 4. 重写抽象方法确定文件保留的原则比如 要么是.java文件要么是文件夹再次遍历。 5. 本质就是一个文件过滤器 可以过滤不符合要求的文件而只留下符合要求的文件。 eg: File dir new File(D:\\qqq); public static void printDir2File dir{ File[ ] fileList dir.listFiles(new FileFilter(){ Override public Boolean accept(File file){ return file.getName().endWith(.java)|| file.isDirectory(); } }) 也可以用lambada表达式 File[] fileList dir.listFiles(file - file.getName().endsWith(.java) || file.isDirectory() ); //循环打印 for(File file fileList){ if(file.isFile(){ sout(这是个文件文件名称 file.getAbsolutePath()) })else{ //递归文件夹重新便利 printDir2(file) } }2. IO流1 概述1. 计算机中一般用来存储的设备有2个 内存和硬盘。 内存 用来运行程序 所有的程序都是在内存中运行的也可以临时存储数据但是当程序关闭后保存的数据会丢失。 硬盘用于持久化的存储数据。 只要不删除一直存在。 2. IO流 Iinput ,输入读取 将数据从其他设备(硬盘)读取到内存中。 Ooutput, 输出写出将内存中的数据写出到硬盘或其他设备中。 流 数据传输的通道可以传输数据。 注 IO流的输入和输出都是依照内存为参照物进行的。 输入是读取到内存中输出是从内存中写出到外面。 作用 IO流主要用来传输数据像文件拷贝上传下载 等等。图示2字节与字符字节 计算机存储的基本单位8位二进制(0~255) 主要处理二进制数据(文件网络传输) 直接操作原始数据 字符 人类可读的文本单位(如字母数字符号) 主要处理文本数据(字符串文档内容) 需要编码/转码 转换成字节。 字节与字符可以相互转化但是需要一定的转化规则。 字节--- 字符 需要指定字符编码如 UTF-8, GBK进行解码。 解码将存储在计算机中的二进制数按照某种规则解析显示出来。 字符--- 字节 通过编码规则转换为字节序列。 编码按照某种规则将字符以二进制的形式存储到计算机中。 常见的编码规则 ASCII1 字节表示 1 字符英文字符。 UTF-8变长编码1~4 字节兼容 ASCII。 GBK中文编码1~2 字节。 注意 在计算机中一切文件数据文本图片视频等在存储时都是以二进制数字的形式保存的都是一个一个的字节数据传输的时候也是这样。 也就是说最基本的结构都是通过字节构成的只不过是因为通过不同的方式(不同的解码规则)打开才展示出我们想让它展示的效果。3 IO流顶层分类1. 从流向上分 输入流 字节输入流 InputStream 字符输入流 Reader 输出流 字节输出流 OutputStream 字符输出流 Writer 2. 从数据类型上分 字节流 字节输入流 InputStream 字节输出流 OutputStream 字符流 字符输入流 Reader 字符输出流 Writer 注意 这4个顶层父类都是抽象类实际上一般使用的是他们的子实现类。4 字节输入流1. 概述 a. InputStream是字节输入流主要是将硬盘中的文件写入到内存中。可以将文件中的内容写入到java程序中 。 b. InputStream是所有字节输入流的顶层父类并且是一个抽象类我们需要用它的子类才可以。一般用的比较多的是它的一个子实现类FileInputPutStream 。 2. FileInputPutStream 1 构造方法 FileInputPutStream (File file ) : 参数需要传递一个File类型的文件表示从这个文件中读取数据到内存。 FileInputStream (String name) : 参数需要传递一个String类型的文件路径表示从这个文件路径中读取数据到内存。 2) 读取方法 int read( ) : 从该文件中读取一个字节(只能是1个字节)到内存并且返回读取到的字节。如果读取结束返回-1 。 int read(byte [ ] bArr) : 从该文件中读取数据到指定的字节数组中。 返回的是读取到的有效的字节个数如果读取结束返回-1。 int read ( byte [ ] bArr, int off, int length) : 从文件中读取数据到指定的字节 数组返回的是读取到的有效的字节个数如果读取结束返回-1。 注意 byte [ ] bArr 字节数组。 off : 从哪个位置开始读取。 length: 每次读取的字节个数。 3) 关闭资源的方法 void close( ) ; 关闭流释放资源。 4 使用实例 a. 创建一个字节输入流 FileInputStream绑定一个获取文件数据的数据源。 InputStream in new FileInputStream(“aa.txt”);// 文件内容abcde //相对路径表示的是本项目下的地址,如果绑定的数据源不存在那么会抛出 FIleNotFoundException 。 注意 这一步骤做了2件事情 1. 创建一个字节输入流对象。 2. 将要绑定的数据源(aa.txt)绑定到这个字节输入流(in)上以后通过这个字节输入流操作的就是这个绑定的数据源文件的内容如果数据源不存在会抛出异常。 b. 读取数据【read()方法一次读取一个字节read(byte[ ] byteArr) 方法一次读取一个字节数组】 int i in.read(); //一次读取一个字节当没有读取结束时返回的是读取到的内容当读取结束时返回的是 -1 。 byte[ ] byteArr new byte[1024] ; int length in.read(byteArr) ; // c. 判断是否读完 While((len in.read(byteArr) ) ! -1){ // 说明还没有读完,可以对数组中的数据进行操作 } 注意 该条件判断做了如下事情 1. 调用了输入流的read()方法将数据读取到byteArr数组中。 2. 返回了读取到的有效个数并且将这个有效个数的值赋值给len。 3. 判断len是否不等于-1如果不等于-1表示读取到了内容那么就在循环中对数据进行处理读取到的数据在byteArr数组中存储着。 4. 如果len等于-1表示数据已经读取结束。 5. 这里不能直接读取或者打印byteArray[ ]数组的内容因为可能会有上次读取的残留。需要使用Syste.out.println(new String(byteArr0len)) ; d. 关闭资源 5注意点 a. 采用字节数组的方式比采用单字节的方式要快很多一般用的字节数组的大小是 1024的整数倍最快的是1024的8倍。 b. 通过字节输入流读取数据如果采取一次读取一个字节数组的方式进行读取那么会将数据读取到参数byteArr数组中 参数byteArr数组的长度是几那么就一次读取几个字节。如果读取的是UTF-8的文件而一次读取字节数组的长度又不是3的倍数 那么还是会出现把中文拆开的情况导致错误。哪怕长度是3的倍数但是读取的文字中如果既有中文又有字符还是会出现错误。 所以不能用字节流来读取/写出 文本数据。5 字节输出流1. 概述 a. OutPutStream是字节输出流主要是将内存中的文件写出到硬盘中。可以将java程序中的数据写到文件中。 b. OurPutStream是所有字节输出流的顶层父类并且是一个抽象类我们需要用它的子类才可以。一般用的比较多的是它的一个子实现类 FileOutPutStream 。 2. FileOutPutStream 1) 构造方法 FileOutPutStream(File file ) 参数需要传递一个File类型的文件表示向这个文件中写出数据。 FileOutPutStream(String name) 参数需要传递一个String类型的文件路径表示向这个文件路径中写出数据。 FileOutPutStream(File fileBoolean append ) File file : 需要进行写出的文件 Boolean append 是否进行追加写 FileOutPutStream(String nameBoolean append ) String name : 一个String类型的文件路径表示向这个文件路径中写出数据。 Boolean append : 是否进行追加写。 注意 如果FileOutPutStream没有加第二个参数true,那么后面执行的会覆盖前面执行的每次都会新创建一个文件再把内容写入 如果加了true那么不会新创建文件而是在原文件的基础上追加写入。 2 写出的方法 void write( int b) : 将指定的字节写出到文件中。每次只能写出一个字节 void write(byte [ ] bArr) : 将指定的字节数组写出到文件中。 void write( byte [ ] bArr, int off, int length) : 将指定字节数组的一部分字节写出到文件中。 byte[ ] bArr: 指定的字节数组 off : 从哪个位置开始写出。 length: 写出几个字节。 3 关闭资源的方法 void close( ) ; 关闭流释放资源。 void flush() 刷新该输出流并强制任何缓冲的输出字节被写出不是强制使用。 4 使用实例 a. 创建一个输出流FileOutPutStream参数传递一个写出的文件路径。 OutPutStream os new FileOutPutStream(“D:\\aa\\bb.txt”); 注意这一步骤做了3件事情 1. 调用系统资源在D盘的aa文件夹下创建文件bb.txt如果这个文件已经存在那么会新建一个新文件覆盖之前的文件。 2. 创建一个字节输出流对象。 3. 将创建的文件(bb.txt)绑定到这个字节输出流(os)上以后通过这个字节输出流操作的就是这个文件的内容。 b. 向路径中写出数据。 write(int b) 注意 1. 使用write(int b) 方法每次只能写出一个字节如果超过一个字节写出时会进行截取导致写出时有问题。 2. 数字可以安全写出 如果传入的是一个数字那么会先将这个数字转换成ASCII码上对应的字符再将字符写出。 3. 字符也可也安全写出在java中一个字符是占两个字节但是如果这个字符是ASCII码表上的字符那么这个字符在操作系统中是占用一个字节的所以这个字符用一次写一个字节的方式也是可以安全写出的。 4. 中文不可以安全写出会有问题中文在操作操作系统中是大于一个字节的(如果采用的是GBK那么占用两个字节如果采用的是UTF-8,那么占用3个字节)所以如果用一次写一个字节的方式来写出中文那么会造成字节溢出产生问题。 write(byte [ ] bArr) write( byte [ ] bArr, int off, int length) 注意 1. 也可以使用字节数组的方式进行写出。 2. 字节数组和字符串可以进行相互转化 字节数组--- 字符串(直接构造方法) String (byte[ ] bytes) : 将整个字节数组转换成String . String (byte[ ] bytes, int offset, int length )将指定字节数组的一部分转换成字符串。 参数: bytes 要转换的byte数组 offset 从哪个位置开始转换(索引位置) length: 转换几个字节 例 String ss2 new String(byteArr,1,2) ; byteArrabcde System.out.println(“ss2”) ; // bc 字符串---- 字节数组 byte[ ] getBytes( ); 使用平台默认的编码格式(开发环境)将字符串转换成字节数组。 byte[ ] getBytes(String s ) ; 使用指定的编码格式将字符串转换成字节数组。 例 String s2 “中国” ; byte [ ] byteArr2 s2.getBytes(); System.out.println(Ayyays.toString(byteArr2)) ; // [-28,-72,-83,-27,-101-67] 3. 因为一个中文占用3个字节那么很可能因为开始的位置不是中文的第一个字节位置或者length不是3的倍数而导致写出文本失败。 c. 续写/换行写 续写 使用带有 append 参数的多参数构造。 FileOutPutStream(File fileBoolean append ) FileOutPutStream(String nameBoolean append ) 换行写 windows : \r\n linux : \n macOs : \r eg: OutPutStream os1 new FileOutPutStream(“aa.txt”); os1.write(“床前明月光\r\n ”.getBytes()); d. 关闭流 os.close() ;6 字符输入流1. 概述 a .字符输入流的顶层父类是 Reader,可以将文件中的数据读取到程序中Reader也是一个抽象类,一般用的是它的子类: FileReader 。主要用来读取文本文件。 2. FileReader 1) 构造方法 FileReader(File file) : 传递一个File类型的文件作为用来获取数据的数据源。 FileReader(String name ) : 传递一个String类型的文件路径作为获取数据的数据源。 2 读取数据的方法 int read() ; 一次读取一个字符并返回读取到的字符如果读取结束返回-1。不管是中文还是字母还是数字都是一个字符。 int read(char[ ] charArr); 一次读取一个字符数组返回的是读取到的字符数组的长度如果读取结束返回-1。 3) 关闭资源的方法 void close( ) ; 关闭流释放资源。7 字符输出流1. 概述 a . 字符输出流的顶层父类是 Writer, 可以将内存(程序)中的数据写出到文件中。Writer是一个抽象类一般用的是它的子类 FileRwiter 。 2. 2 FileWriter 1) 构造方法 FileWriter(File file) : 传递一个File类型的文件表示向这个File文件中写出数据。 FileReader(String name ) : 传递一个String类型的文件路径表示向这个文件路径中写出数据。 FileWriter(File file ,Boolean append) : 向file文件中追加写出数据。 File file 表示向这个File文件中写出数据 。 Boolean append : 是否追加写出数据true表示追加写。 FileWriter(String nameBoolean append) 向给出的文件路径中追加写数据。 String name String类型的文件路径表示向这个文件路径中写出数据。 Boolean append : 是否追加写出数据true表示追加写。 2 写出数据的方法 void write(int c) : 向指定文件中写出一个字符。 void write(char[ ] charArr) : 向指定文件中写出一个字符数组。 void write(char[ ] charArr, int off , int len) : 向指定文件中写出一个字符数组的一部分内容。 char[ ] charArr : 指定的字符数组。 int off 开始写出的位置索引位置 int len 写出的长度多少个字符 void write(String str) : 向指定文件中写出一个字符串内容。 void write(String str, int off , int len) : 向指定文件中写出一个字符串内容的一部分。 String str: 指定的字符串。 int off 字符串开始写出的位置索引位置 int len 写出的长度多少个字符 3) 资源处理相关的方法 void flush() : 刷新仅仅是刷新操作而且刷新后还可以向文件中再写出数据。 void close( ) ; 先刷新再关闭关闭之后不能再向文件中再写出数据否则会直接报错。 4注意点 a. 调用write()方法只是把数据写出到了内存缓冲区中并没有放入到文件中要想把写出的内容放到文件中必须要进行fluch()刷新操作才可以。 b. 仅仅字符输出流写完数据后要刷新其他流不需要该操作。8 字节流和字符流的区别字节流: 不能操作中文但是可以操作其他类型的文件如图片、视频、音乐等。 字符流 只能操作文本文件(用记事本打开能看懂的文件就是文本文件)。 总结 如果操作文本文件就用字符流如果操作的是非文本文件就用字节流。9 IO流的异常处理操作1. JDK1.7之前需要手动try...catch...finally 然后在finally中手动关闭流。 2. JDK1.7处理方式 代码 try 创建流对象1 创建流对象2 { //操作流的代码 } catch (IOException e){ e.printStackTrace(); } ------这种格式称为 try…with…resource 注 小括号内也可以创建多个对象多个对象之间用分号隔开。 这种方式不需要我们自己去调用close()方法关闭流系统会自动调用方法帮我们关闭流而且不管程序有没有异常都可以关闭流。 原因 try后面小括号中创建的对象必须实现AutoCloseable接口。这个接口中有重写的close()方法不管有没有异常这个方法都会执行作用就是关闭流或者关闭其他资源相当于try…catch的语法糖。 3. 如果要释放处理try外面的流资源 jdk1.7以及之前需要将外面的流赋值给新的流 FileWriter fw new FileRwiter(file1.txt) try(FileWriter fw2 fw){ fw2.write你好 }catchIOException e{ } jdk1.9以及之后直接将流放到try后面 try(fw2){ fw2.write你好 }catchIOException e{ }10 IO流总结11 IO流分类1. BIO 同步阻塞IO线程在执行IO操作的时候会阻塞等待不能做其他事情。 2. NIO用的较多: 同步非阻塞IO线程在执行IO操作的时候会去干别的事情。并且会实时的去看IO操作有没有结束如果结束了就会回来继续io后的操作。 3. AIO 异步非阻塞IO 找别人帮我完成一些事情。3. 缓冲流1分类字节缓冲流 字节输入缓冲流 BufferedInputStream 字节输出缓冲流 BufferedOutputStream 字符缓冲流 字符输入缓冲流 BufferedReader 字符输出缓冲流 BufferedRwiter2特点a. 缓冲流的特点就是快。可以提高读写的速率 b. 缓冲流本身并不具备读或者写的功能它的作用只是给其他流提供加速。 缓冲流效率高的原因是因为 它的内部有一个缓冲区缓冲区的大小是1024*83使用步骤1. 创建缓冲流对象 2. 调用方法进行读或者写操作 3. 关闭流。4字节输入缓冲流构造方法 BufferedInputStream(InputStream in ) : 将一个普通的字节输入流作为入参转换为字节输入缓冲流默认字节数组大小为1024*8 BuffredInputStream(InputStream in, int size ) : 将一个普通的字节输入流和一个字节数组(缓冲区)大小作为入参转换为字节输入缓冲流。5字节输出缓冲流构造方法 BufferedOutputStream(OutputStream out) : 将一个普通的字节输出流作为入参转换为字节输出缓冲流默认字节数组大小为1024*8 BufferedOutputStream (OutputStream out, int size ) : 将一个普通的字节输出流和一个字节数组(缓冲区)大小作为入参转换为字节输出缓冲流。示例6字符输入缓冲流BufferedReader(Reader in) : 将一个普通的字符输入流作为入参转换为字符输入缓冲流默认字符数组大小为1024*8 BufferedReader (Reader in, int size ) : 将一个普通的字符输入流和一个字符数组(缓冲区)大小作为入参转换为字符输入缓冲流。7字符输出缓冲流BufferedWriter(Writer out) : 将一个普通的字符输出流作为入参转换为字符输出缓冲流默认字符数组大小为1024*8 BufferedWriter (Writer out, int size ) : 将一个普通的字符输出流和一个字符数组(缓冲区)大小作为入参转换为字符输出缓冲流。示例8 字符缓冲流的特殊方法字符输入缓冲流 BufferReader中有一个方法可以一次读取一行数据。 String readLine() ; 读取一行数据并返回读取结束时返回 null 。 注意readLine()方法不会读取换行符需要自己手动换行println。 字符输出缓冲流 BufferWriter有一个方法可以实现跨平台换行。 void newline() : 实现一个跨平台的换行。示例4. 转换流1编码表1. 计算机中存储的数据都是二进制的但是我们在屏幕上看到的文字却是各式各样这些都是二进制转换过后的结果。 编码按照某种规则将字符以二进制的形式存储到计算机中称为编码 解码将存储在计算机中的二进制数按照某种规则解析显示出来称为解码。 2. 字符编码指的是自然语言的字符和二进制数之间的对应规则。 3. 字符集 又叫做编码表。 是一个系统支持的所有字符的集合包括各个国家的文字标点符号图形符号汉字等。 编码表指的是计算机中的字节和我们看到的字符的对应关系表。 4. 在windows操作系统中默认的是gbk编码在 gbk 编码中 一个中文占用两个字节。 在idea中默认的是utf-8编码在utf-8 编码中一个中文占用3个字节。2转换流的作用在windows系统中文本文件默认使用的是 gbk编码一个中文占用两个字节。 但是在java程序(idea)中文本文件默认使用的是utf-8编码一个中文占用3个字节。 那么当用idea 读取windows系统下的文本文件时就会因为中文占用的字节数不同而导致乱码。 这时候就需要用到转换流来指定统一的编码格式。3 InputStreamReader1. 介绍 InputStreamReader 是将(硬盘中的)文件读取到java程序中。 在文件中所有的数据都是以字节的形式保存读取到java后以字符的形式展示。 所以 InputStreamReader是字节到字符的桥梁。 InputStreamReader的本质先查询码表再进行转换。 2. 构造方法 InputStreamReader (InputStream in ) 传递一个字节输入流。 InputStreamReader (InputStream in ,String charName) InputStream in : 传递一个字节输入流 String charName一个字符串类型的编码格式表示要通过这种编码格式进行读取。 3. 使用 a. 创建流。 b. 读取。 c. 释放资源。 4. 示例 BufferedReader br new BufferedReader(new InputStreamReader(new FileInputStream(file.txt), StandardCharsets.UTF_8))); String line; while ((line br.readLine()) ! null) { System.out.println(line); }4 OutputStreamWriter1. 介绍 OutputStreamWriter其实就是将内存中的数据写出到硬盘中。 OutputStreamWriter可以指定编码格式来向硬盘中写出数据。 2. 构造方法 OutputStreamWriter(OutputStream out ): 传递一个字节输出流会按照idea默认的编码格式向文件中写出数据。 OutputStreamWriter(OutputStream out String charsetName): OutputStream out : 传递一个字节输出流 String charsetName: 设置一个编码格式使数据按照指定的编码格式向文件中写出数据。 3. 使用步骤 a. 创建流。 b. 写出。 c. 释放资源。 4. 具体示例 BufferedWriter bw new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file.txt), StandardCharsets.UTF_8))); bw.write(1111); bw.close(); }5) 关系InputStreamReader: 从文件中读取的是字节在idea中看到的是字符 OutputStreamWriter: 在idea中写出的是字符保存到文件中的是字节。5. 序列化流1 序列化流ObjectOutputStream1. 定义 ObjectOutputStream: 将java对象写出到硬盘(文件)中。 2. 构造方法 ObjectOutputStream (OutputStream out ) :传递一个字节输出流。 3. 写对象的方法 void writeObject(Object obj) : 向文件中写出一个对象。 4. 使用步骤 a. 创建一个序列化流。 b. 调用writeObject()方法向文件中写对象。 c. 释放资源。 5. 示例 public class test{ public static void main (String[ ] args){ ObjectOutputSream os new ObjectOutputSream (new FileOutputStream(aa.txt)); Person p new Person(张三,18); os.writeObject(p); os.close(); } } 6. 注意点 a. 只有实现Serializable接口的类的对象才能够被序列化。 b. Serializable接口中没有任何方法它只是做一个标记表示实现该接口的类的对象可以被序列化。2 反序列化流ObjectInputStream1. 定义 ObjectInputStream: 将之前序列化写出的对象重新反序列化读入内存(java程序)中。 2. 构造方法 ObjectInputStream(InputStream out ) :传递一个字节输入流。 3. 读取对象到内存(java程序)的方法 Object readObject() : 将之前序列化的对象进行反序列化,读入内存(java程序)中。 4. 使用步骤 a. 创建一个反序列化流。 b. 调用readObject()方法进行读取操作。 c. 释放资源。 5. 示例 public class test{ public static void main (String[ ] args){ ObjectInputSream os new ObjectInputSream (new FileInputStream(aa.txt)); Object obj os.readObject(); Person p (Person) obj; Sout(p.getNamep.getAge); os.close(); } } 6. 注意点 a. 要读取的文件必须是之前序列化生成的文件。 b. 如果读取的文件时候这个类不存在那么会抛出classNotFoundException异常。 c. 如果读取文件的时候类存在但是由于类发生了改变版本号也发生改变导致版本号不一致而无法反序列化时会抛出InvalidClassException异常。3 序列化中的static1. 被static修饰的成员变量不能被序列化。 2. 被static修饰的成员变量会变为静态变量其值或者引用将不能被改变。 如果希望一个变量不被序列化又不想用static修饰那么可以用transient修饰被transient修饰的成员变量不会改变其原来属性而且不会被序列化。4 序列化版本问题1. 当一个类的对象先进行序列化写出到文件中然后对类进行了修改(不包括加空格加注释等)再对之前序列化的文件进行反序列化读取时就会因为类的修改而导致这个类的版本号发生改变序列化文件中类的版本号和现在类的版本号对应不上而导致反序列化失败。 2. 解决方法 给类分配一个固定的版本号不管类是否进行修改版本号都不会发生改变。 3. 给类分配固定版本号方法 提供一个静态成员变量这个静态成员变量的内容为 private static final Long serialVersionUID 1L; // 1 也可以是其他数只要固定就可以。6. 打印流1 特点输出数据非冲方便但是打印流只能输出数据不能输入数据。2 分类字节打印流PrintStream ; 字符打印流PrintWriter3 构造方法PrintStream (File file ) :传递一个file类型的文件 PrintStream (String fileName) :传递一个字符串类型的文件路径 PrintStream (OutputStream out) : 传递一个字节输出流4 其他方法Print() ; 输出不换行 Println(); 输出并换行 Write() 写出5 调用write()方法写出和调用print()方法写出的区别调用write()写出数字时会对照ASCII码表转换成字符 而调用print()方法不会对照码表会直接输出数字。6 标准输出流System.out.println() 里面的System.out 是一个打印流也叫做标准输出流。 我们可以调用System的setOut(PrintlnStream out) 方法来改变打印流的走向使打印流不是打印到控制台而是打印到指定的文件目录。 eg: PrintStream() ps new PrintStream(aa.txt); System.setOut(ps); //打印到指定目录7. Properties集合1) 介绍Properties是一个双列集合里面是以键值对的形式存放数据的。 特点 1. Properties实现了Map接口拥有Map中的所有功能并且是一个双列集合。 2. Properties键值对没有泛型键和值都是String类型的。 3. Properties支持对流的操作可以从流中加载键值对。使用的主要原因2 常用方法1. Properties; 无参构造 2. object setProperty(String key , String value) ; 向Properties集合中添加键值对。 3. String getProperty( String key) ; 根据key获取value值。 4. SetString stringPropertyNames(); 获取所有存放key的集合相当于keySet。 5. void load(InputStream inputStream) ; 从字节流(文件)中加载键值对。 6. void load (Reader reader) ; 从字符流(文件)中加载键值对。3使用步骤1. 创建一个Properties集合。 2. 创建一个输入流对象绑定一个数据源文件表示要从这个文件中读取数据。 3. 调用Properties集合的load()方法传递刚才创建的输入流对象就可以将输入流绑定的文件中的键值对加载到Properties对象中。 要读取的文件的要求 1. 一般文件以.properties 结尾这种后缀的文件是配置文件。 2. 文件的内容是键值对而且必须按照以下方式存储 key value key value key value 注 1不能有分号如果有分号会当做value值的一部分获取 2value 如果是中文用字节流读会产生乱码需要指定解码规则。 如果使用的是idea,那么需要修改配置中的编码规则修改步骤为 File—settings--Editor--Code Style---File Encodinds------ 项目编码UTF-8 properties默认编码ISO-8859-1 ; 勾选自动转换为UTF-8。4具体示例

更多文章