Java 持久化之 --io流与序列化操作
1)File类操作文件的属性
1.File类的常用方法
1.
文件的绝对完整路径:getAbsolutePath()
文件名:getName()
文件相对路径:getPath()
文件的上一级目录:getParent()
文件的大小为:length()
删除文件:delete()
具体操作请参考如下代码:
2)IO流(堵塞型io)
如何读写文件?
分析:流是指一连串流动的字符,是以先进先出方式发送信息的通道
输入/输出流于数据源:
java流的分类:
我们可以对它进行如下分类:
· 按处理的数据类型可分为字节流与字符流
· 按流的流向可分为输入流(in)与输出流(out)
· 按流的功能可分为节点流(Node)和过滤流(Filter)
在Java中,字节流一般适用于处理字节数据(诸如图片、视频),字符流适用于处理字符数据(诸如文本文件),但二者并没有严格的功能划分,因为有转换流的存在,使得对于数据的处理变得更加灵活。
1)字节流读写文件
一般用于处理字节数据,但字节流采用ASCII编码的,所以处理字符数据时容易出现中文乱码
1. 输入流
InputStream:此抽象类是表示字节输入流的所有类的超类(基类)
序号 |
方法描述 |
1 |
public final int read(byte[] r, int off, int len)throws IOException |
2 |
Public final int read(byte [] b)throws IOException |
3 |
1. public final Boolean readBooolean()throws IOException, 2. public final byte readByte()throws IOException, 3. public final short readShort()throws IOException 4. public final Int readInt()throws IOException 从输入流中读取字节,返回输入流中两个字节作为对应的基本数据类型返回值。 |
4 |
public String readLine() throws IOException |
所有字节输入流都是以此类发散出来的,但此类是一个抽象类,不可被实例化,所以实际编程过程中,都是使用它发散出来的一些子类,下面是输入流的关系图:
输入流最常用的就是FileInputStream类:
1-1 文本文件的读取:用FileInputStream
该流用于从文件读取数据,它的对象可以用关键字 new 来创建。
·有多种构造方法可用来创建对象。
·可以使用字符串类型的文件名来创建一个输入流对象来读取文件:
·····InputStream f = new FileInputStream("C:/java/hello");
·也可以使用一个文件对象来创建一个输入流对象来读取文件。我们首先得使用 File() 方法来创建一个文件对象:
·····File f = new File("C:/java/hello");
·····InputStream out = new FileInputStream(f);
·创建了InputStream对象,就可以使用下面的方法来读取流或者进行其他的流操作。
字节流:
基类:InputStream 子类:FileInputStream
构造:
FileInputStream(File file) || FileInputStream(String name)
方法:
read() 按字节读
read(byte[] b) 读到字节数组缓冲区,数组存满统一批次循环读取
read(byte[] b, int off, int len) 向数组存放时进行了限制,起始位置off和终止位置len
int available() 表示当前还剩多少个字节未读取
注意:read方法返回 int 类型 返回读入字节数组的长度,如果读取到文件末尾的时候,则返回-1
代码演示按字节读取到控制台:
四步走:1.导入相关类 2.创建字节流对象 3.实现读取文本文件的数据 4.关闭文件流对象
测试文档:
使用Read()读取
废话不多说 举个栗子:
package text; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.FileInputStream; public class FileInputStream01 { public static void main(String[] args) { //创建字节流对象 InputStream fls=null; try { fls=new FileInputStream("D://TextFile//A.txt"); //实现读取操作 int data;//存储读取的字节 while((data=fls.read())!=-1) { //System.out.print(data);//读取的是数字 System.out.print((char)data);//读取的是和文件一致 } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { try { if(fls!=null) fls.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
修改代码使用Read(byte[] b)读取
int len;//存储读入数组的长度 byte[] wrods=new byte[1024]; while((len=fls.read(wrods))!=-1) { System.out.print(new String(wrods,0,len));//String构造方法 把字节byte[] 转换成字符串形式,0代表截取起始位置,len表示截取终止位置 }
结果与上述一致:
1. 输出流
OutputStream:此抽象类是表示字节输出流的所有类的超类(基类)
序号 |
方法描述 |
1 |
public final void write(byte[] w, int off, int len)throws IOException |
2 |
Public final int write(byte [] b)throws IOException |
3 |
1. public final void writeBooolean()throws IOException, 2. public final void writeByte()throws IOException, 3. public final void writeShort()throws IOException, 4. public final void writeInt()throws IOException 这些方法将指定的基本数据类型以字节的方式写入到输出流。 |
4 |
Public void flush()throws IOException |
5 |
public final void writeBytes(String s) throws IOException |
所有字节输出流都是以此类发散出来的,但此类是一个抽象类,不可被实例化,所以实际编程过程中,都是使用它发散出来的一些子类,下面是输出流的关系图:
输出流最常用的就是FileOutputStream 类:
1-2文本文件的写入:用FileOutputStream
该类用来创建一个文件并向文件中写数据。
如果该流在打开文件进行输出前,目标文件不存在,那么该流会创建该文件。
有两个构造方法可以用来创建 FileOutputStream 对象。
使用字符串类型的文件名来创建一个输出流对象:
OutputStream f = new FileOutputStream("C:/java/hello")
也可以使用一个文件对象来创建一个输出流来写文件。我们首先得使用File()方法来创建一个文件对象:
File f = new File("C:/java/hello");
OutputStream f = new FileOutputStream(f);
输出流:
基类:OutputStream
子类:FileOutputStream ..............
构造:
方法:
废话不多说 举个栗子:
1-3文件读取和写入同步
废话不多说 举个栗子:
2)字符流读和缓冲流读文件
用BufferedReader 和 BufferedWriter读写文本文件//字符流
或 FileReader
字符编码:ASCII码 0~127 8位二进制数1个字节。 16位二进制数表示一个字符 两个字节
字符流:输入流
基类:Reader----FileReader
构造:
常用方法:
1)如果 使用字节流读取带有汉字的文件会怎么样那
package text; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.FileInputStream; public class FileInputStream01 { public static void main(String[] args) { //创建字节流对象 InputStream fls=null; try { fls=new FileInputStream("D://TextFile//A.txt"); //实现读取操作 int data;//存储读取的字节 while((data=fls.read())!=-1) { //System.out.print(data);//读取的是数字 //System.out.println("还剩:"+fls.available()+"字节未读取"); System.out.print((char)data); } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { try { if(fls!=null) fls.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
运行结果如下:
很明显出现了乱码
2)下面使用FileReader字符流 Read()读取文件,示例如下
package text; /** * 使用字符流读取文本文件 *<p>Title:FileReaderDemo</p> *<p>Description:</p> *<p>Company:</p> * @author MLQ * @date 2018年3月7日 下午12:38:35 */ import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.Reader; public class FileReaderDemo { public static void main(String[] args) { //创建一个字符流对象 Reader rd=null; try { rd=new FileReader("D://TextFile//A.txt"); int word;//就收读取的字符 while((word=rd.read())!=-1) { System.out.print((char)word); } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { if(rd!=null) { try { rd.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
运行结果你会发现,乱码消失了
3)下面使用FileReader字符流 Read(char[] b)读取文件,示例如下
修改代码如下:
package text; /** * 使用字符流读取文本文件 *<p>Title:FileReaderDemo</p> *<p>Description:</p> *<p>Company:</p> * @author MLQ * @date 2018年3月7日 下午12:38:35 */ import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.Reader; public class FileReaderDemo { public static void main(String[] args) { //创建一个字符流对象 Reader rd=null; StringBuffer sb=new StringBuffer(); try { rd=new FileReader("D://TextFile//A.txt"); int word;//就收读取的字符 char[] ch=new char[1024]; while((word=rd.read(ch))!=-1) { sb.append(ch,0,word); } System.out.println(sb.toString()); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { if(rd!=null) { try { rd.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
运行结果如下:
温馨提示:如果上述的代码 sb.append(ch,0,word) 只写数组的话,会把空格也会追加到 StringBuffer。读取文
件的时候最后可能没有写满数组
4)使用BufferedReader读取文本文件
(增强)
BufferedReader类是Reader类的子类
bufferedReader类带有缓冲区
按行读取内容的ReadLine()方法
实现步骤:
构造:
方法:
演示代码如下:
运行结果如下:
3)字符流读和缓冲流写文件
基类:Write 子类:FileWrite
构造:
方法:
演示代码如下:
3-1)使用FileWrite字符流写入文档
3-2)使用BufferedWrite字符流写入文件
如何提高字符流写文本文件的效率?
解:使用FileWrite类与BufferReader类
BufferedWrite类是Write类的子类
BufferedWrite类带有缓冲区
步骤:
构造:
方法:
代码演示如下:
package text; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.Reader; import java.io.Writer; public class BufferedWrite01 { public static void main(String[] args) { //创建FileWrite 和 BufferedWrite 对象 Writer wd=null; BufferedWriter bw=null; //创建FileReader 和 BufferedReader 对象 Reader ed=null; BufferedReader br=null; try { wd=new FileWriter("D:\\TextFile\\A.txt"); bw=new BufferedWriter(wd); bw.write("我是测试员"); bw.newLine();//换行符方法 bw.write("负责测试程序运行问题"); bw.flush(); System.out.println("成功写入"); //读取文本文件信息 ed=new FileReader("D:\\TextFile\\A.txt"); br=new BufferedReader(ed); String word=null; while((word=br.readLine())!=null) { System.out.println(word); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if(wd!=null){ try { wd.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(bw!=null){ try { bw.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(ed!=null){ try { ed.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(bw!=null){ try { bw.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
4)使用数据流读写文件
二进制文件读写:
使用DataInputStream 和 DataOutputStream 读写二进制文件 //属于字节流
DataInputStream 类:
FileInputStream的子类
与FileInputStream类结合使用读取二进制文件
DataOutputStream 类:
FileOutputStream的子类
与FileOutputStream类结合使用写二进制文件
DataOutputStream:
演示代码如下:
实现步骤:
package text; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; @SuppressWarnings("unused") public class DataInOutStream { @SuppressWarnings("resource") public static void main(String[] args)throws Exception { DataInputStream di=null; DataOutputStream ds=null; di=new DataInputStream(new FileInputStream("D://TextFile//dd.class")); ds=new DataOutputStream(new FileOutputStream("D://TextFile//coty.class")); int len;//接收读取的字节 while((len=di.read())!=-1) { ds.write(len); } System.out.println("执行完毕"); if(di!=null) di.close(); ds.close(); } }
3)序列化和反序列化
序列化和反序列化的过程
序列化的步骤:
1.实现 Serializable 接口
2.创建对象输出流
3.调用 writeObject()方法将对象写入文件
4.关闭对象输出流
使用集合保存对象,可以将集合中的所有对象序列化
序列化构造和常用方法
反序列化构造和常用方法
实现序列化 和 反序列化 演示代码:
package text; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; public class TextStudent { @SuppressWarnings("unchecked") public static void main(String[] args) { //创建序列化对象 ObjectOutputStream xl=null; //创建反序列化对象 ObjectInputStream xl1=null; //初始化要序列化的对象 Map<String,Student> map=new HashMap<String,Student>(); Map<String,Student> map1=new HashMap<String,Student>(); Student stu=new Student("小明",18,"男"); Student stu1=new Student("小红",18,"女"); map.put(stu.getName(), stu); map.put(stu1.getName(), stu1); try { xl=new ObjectOutputStream(new FileOutputStream("D://TextFile//xuliehua.bin")); xl1=new ObjectInputStream(new FileInputStream("D://TextFile//xuliehua.bin")); xl.writeObject(map); System.out.println("写入成功"); //反序列化文件输出到控制台 map1=(Map<String,Student>)xl1.readObject(); Set<String> key=map1.keySet(); Iterator<String> l=key.iterator(); while(l.hasNext()) { String keys=l.next(); map1.get(keys).show(); } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if(xl!=null){ try { xl.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(xl1!=null) { try { xl1.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
测试类
提示:如果不希望Student类某一属性被序列化可使用 transient 修饰
注:最后在提一句:使用序列化操作时,一定要将准备序列化的类或数据声明为可序列化操作!!!!
Java 持久化之 --io流与序列化操作的更多相关文章
- Java 学习笔记 IO流与File操作
可能你只想简单的使用,暂时不想了解太多的知识,那么请看这里,了解一下如何读文件,写文件 读文件示例代码 File file = new File("D:\\test\\t.txt" ...
- java 21 - 13 IO流之序列化和反序列化
序列化流:把对象按照流一样的方式存入文本文件或者在网络中传输.对象 -- 流数据(ObjectOutputStream) 构造方法:ObjectInputStream(InputStream in) ...
- 第53节:Java当中的IO流(上)
Java当中的IO流 在Java中,字符串string可以用来操作文本数据内容,字符串缓冲区是什么呢?其实就是个容器,也是用来存储很多的数据类型的字符串,基本数据类型包装类的出现可以用来解决字符串和基 ...
- Java中的IO流,Input和Output的用法,字节流和字符流的区别
Java中的IO流:就是内存与设备之间的输入和输出操作就成为IO操作,也就是IO流.内存中的数据持久化到设备上-------->输出(Output).把 硬盘上的数据读取到内存中,这种操作 成为 ...
- Java中的IO流(六)
上一篇<Java中的IO流(五)>把流中的打印流PrintStream,PrintWriter,序列流SequenceInputStream以及结合之前所记录的知识点完成了文件的切割与文件 ...
- Java中的IO流(四)
上一篇<Java中的IO流(三)>把IO流中的文件及目录操作的对象File类记录了一下,本篇把本不属性IO流但又和IO流有关系的一个对象作一下记录,此对象本属于集合框架里的一个子集,即Pr ...
- Java中常用IO流之文件流的基本使用姿势
所谓的 IO 即 Input(输入)/Output(输出) ,当软件与外部资源(例如:网络,数据库,磁盘文件)交互的时候,就会用到 IO 操作.而在IO操作中,最常用的一种方式就是流,也被称为IO流. ...
- Java中的IO流之输出流|乐字节
大家好,乐字节小乐又来了.上一篇给大家带来的是:Java中的IO流之输入流|乐字节,本文将继续讲述IO流之输出流. 一.输出流 1.抽象类:OutputStream 和 Writer Output ...
- Java中的IO流之输入流|乐字节
亲爱的乐字节的小伙伴们,小乐又来分享Java技术文章了.上一篇写到了IO流,这篇文章着重 谈谈输入流,再下次再说输出流. 点击回顾上一篇:乐字节Java之file.IO流基础知识和操作步骤 一. 输入 ...
随机推荐
- 关系型数据库工作原理-客户端连接管理器(翻译自Coding-Geek文章)
本文翻译自Coding-Geek文章:< How does a relational database work>.原文链接:http://coding-geek.com/how-data ...
- 为wampserver 添加新版本php支持
1.1. 停止WAMP服务器. 2.下载要安装的PHP版本.下载Window版本的ZIP包啦:http://windows.php.net.解压到 Wamp的安装目录\bin\php\php7.2. ...
- 为什么覆写equals必须要覆写hashCode?
============================================= 原文链接: 为什么覆写equals必须要覆写hashCode? 转载请注明出处! ============= ...
- 【python学习笔记】5.条件、循环和其他语句
[python学习笔记]5.条件.循环和其他语句 print: 用来打印表达式,不管是字符串还是其他类型,都输出以字符串输出:可以通过逗号分隔输出多个表达式 import: 导入模块 impo ...
- js 数组 remove
在写js代码时候,有时需要移除数组的元素,在js数组中没有remove 方法, 不过有splice 方法同样可以用于移除数组元素:(http://www.w3school.com.cn/jsref/j ...
- PHP之防御sql注入攻击的方式
长期以来,web的安全性存在着巨大的争议与挑战.其中,sql注入就是一种常见的一种攻击方法,开发人员普遍的做法就是不停的过滤,转义参数,可是我们php大法天生弱类型的机制,总是让黑客有机可乘,绕过防御 ...
- SIMD---SSE系列及效率对比
SSE(即Streaming SIMD Extension),是对由MMX指令集引进的SIMD模型的扩展.我们知道MMX有两个明显的缺点: 只能操作整数. 不能与浮点数同时运行(MMX使用FPU寄存器 ...
- ~psd面试 求最长回文序列 DP求解
链接:https://www.nowcoder.com/acm/contest/90/D来源:牛客网 掌握未来命运的女神 psd 师兄在拿了朝田诗乃的 buff 后决定去实习. 埃森哲公司注册成立于爱 ...
- Bitmap的加载与缓存
Android系统中图片一般用Bitmap对象表示,它支持png,jpg等常见格式.通常情况下图片的体积都比较大,单个应用允许使用的内存又是有限的,所以我们需要采取一些手段减少内存占用并提高加载速度. ...
- STL --> string类字符串
基本使用方法 一.输入 string s: cin >> s; getline(cin, s) ; //使用默认的'\n'作为终止符 getline(cin, s, '!') ; //以' ...