Java之IO流详解
IO流
Input/Output 完成输入/输出
应用程序运行时——数据在内存中 ←→ 把数据写入硬盘(磁带) 内存中的数据不可持久保存的
输入:从外部存储器(硬盘、磁带、U盘)把数据读入内存。
输出:从内存中把数据写入外部存储区(硬盘、磁带、U盘)中,这样就可以保证:即使程序退出了,数据依然不会丢失。
File — 代表磁盘上的文件或目录。
● listRoots() :列出磁盘上所有的根目录
● exists:判断是否存在
● mkdir:创建目录
● listFiles():列出当前目录下所有的文件和子目录
● listFiles(FileFilter filter) :列出当前目录下符合指定条件的文件和子目录
● File[] listFiles(FilenameFilter filter) :列出当前目录下符合指定条件的文件和子目录
列出某个磁盘所有的文件 —— 这就要用到递归
--------------------->>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<-----------------------
IO流 File的特征:只能访问磁盘上的文件和目录 它无法访问磁盘上的内容 如果要访问文件的内容,必须使用IO流。
--------------------->>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<-----------------------
流的分类:
按流的方向来分(从程序所在的内存的角度来看):
—输入流:把外部输入读入当前程序所在内。
—输出流:把当前程序所在内存的数据输出到外部
按流处理得数据来分:
— 字节流:它处理数据单元是字节(8bit),适应性广、功能强大。
— 字符流:它处理的数据单元是字符。通常来说它主要处理文本文件, 它在处理文本文件时,比字节流更方便。
按流的角色来分:
— 节点流:直接和一个IO的物理节点(磁盘上的文件、网络)关联。
— 包装流(处理流):以节点为基础,包装之后得到的流。都继承FilterXxx等基类。
流的概念模型
输入流:负责把外部的数据、读入到程序所在的内存。
缓存流
外部存储器的速度比内存速度要慢,外部存储器的读写与内存的读写并不同步!!
——通过缓存就可以解决这种不同步的问题
反正你把流用完了,别调用了flush(把缓存中的内容刷入实际的节点)方法 调用close()也可以
——系统会在关闭之前,自动刷缓存。
IO流一共涉及到40多个类
字节流 字符流
InputStream OutputStream Reader Writer(抽象)根基类不会拿来使用
FileInputStream FileOutputStream FileReader FileWriter(访问文件)
ByteArrayInputStream ByteArrayOutputStream CharArrayReader CharArrayWriter(数组)
PipedInputStream PipedOutputStream PipedReader PipedWriter(访问管道)
-->(两个进程之间通信的时候)
SringReader StringWriter(访问字符串)
BufferInputStream BufferOutputStream BufferReader BufferWriter(缓存)
--> 性能得到提升
FilterInputStream FilterOutputStream FilterReader FilterWriter(过滤、抽象)
PrintStream PrintWriter(打印)
InputStreamReader OutputSteramWriter(转换) DataInputStream DataOutStream (特殊)
所有以InputStream结尾的都是【字节输入流】
所有以OutputStream结尾的都是【字节输出流】
所有以Reader结尾的都是【字符输入流】
所有以Writer结尾的都是【字节输出流】
-------------------------------->>>>>>>>>>>>>><<<<<<<<<<<<<<<<-------------------------------------------------
节点流直接与IO节点关联
——IO节点很多:键盘、网络、文件、磁带....
把节点流包装成过滤流:消除节点流的差异:
而且PrintStream的
PrintStream ps = new PrintStream(fos);//fos为文件
ps.println("我有一个房子");
ps == System.out 都属于PrintStream的属性
过滤流,建立在节点流的基础之上。
过滤流的好处:
— 消除底层节点之间的差异
— 使用过滤流的方法执行IO更加便捷
FileOutPutStream → PrintStream
FileWiter → PrintWiter
如果已经知道要读的内容是字符内容,就可以按如下的方式转换
InputStream → InputStreamReader → BufferedReader
FileInputStream fis = new InputStreamReader("ReadFile.java");
InputStreamReader reader = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(reader);
换为一行:
BufferedReader br = new BufferedReader(
new InputStreamReader(
new InputStreamReader("ReadFile.java")));
-------------------------------->>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<----------------------------------------
DataInputStream与DataOutputStream
它们是两个特殊的流
——它们并不是节点流,是过滤流(建立在已有IO的基础之上)
—— 它们只要增加一些特定的方法来读取特定的数据。
重定向标准输入输出:
System.in — 标准输入。通常代表键盘
System.out — 标准输出。通常代表屏幕
System.setOut() —— 可以将标准重定向到另一个输出流
System.setIn() —— 可以将标准重定向到另一个输入流
System.setOut(new PrintSteam("out.txt")) ; 可以将输出的内容直接放入文件...
System.setIn(new FileInputStreamSteam("out.txt")) ; 可以从文件读取内容并输出
Java虚拟机读取其他进程的数据:
Java如何启动其他进程:Runtime实例.exec()
该方法的返回值是一个Process对象
Process — 代表一个进程
进程就是运行中的应用程序。
{
Runtime runtime = Rintime getRuntime();
//启动javac应用程序返回
Process proc = runtime.exec("java.exe");
//要得到javac应用程序输出的内容,此处应该用输入流?还是输出流
//对javac来说,是输出;但对于我们应用程序来说,用输入流
InuputStreamReader reader = new InuputStreamReader (proc.getErrorStream());
BuffereReader br = new BuffereReader(reader); String line =null;
System.out.println("编译出错,错误信息如下"); //控制BufferedReader每次读取一行
while((line = br.readLine()) != null) {
System.out.println(line);
}
}
StringWriter sw = new StringWriter();
sw.Writer(line);
RandomAccessFile — 随机(任意)访问
Random — 想访问文件的那个点,就访问文件的哪个点(任意)。
特征:A。即可读,又可写、还可追加。------> 【相当于DataInputStream与DataOutputStream】合体 RandomAccessFile它不会覆盖原有的文件内容。 B。只能访问文件!!这就是它的局限性。 创建RandomAccessFile,需要指定读(r)、写(rw)模式。 体现它的“random【任意】”性的方法是:
● seek(long pos) — 用于把记录指针移动到任意位置,想要访问哪个点就访问哪个点 一开始,它的记录指针位于文件的开始位置。
使用RandomAccessFile来追加文件内容:1.把记录指针移动到最后; 2.执行输出即可
使用RandomAccessFile来插入文件内容:1.把记录指针移动到指定位置; 2.从当前位置到文件结尾的内容,先读取、并保存 3.输出要插入的内容。4.输出之前保存的内容。
IO体系------>>>
------------------------------------->>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<-------------------------------------------
Java传统IO的基本体系:
字节输入流 字节输出流 字符输入流 字符输出流
InputSteam OutputStream Reader Writer
访问文件 FileXxx
访问数组 ByteArrayXxx CharArrayXxx
访问管道 PipedXxx
访问字符串 StringXxx
过滤流 FileterInputStream FileterOutputStream FileterReader FilterWriter
缓冲流 BufferedXxx
打印流 PrintStream PrintWriter
转换流 InputStreamReader OutputStreamWriter
特殊流 DataInputStream DataOutputStream
ObjectInputStream ObjectOutputStream
RandomAccessFile — 1.它只能访问文件。相当于DataInputStream和DataOutputStream组合
2.任意,由seek(int pos)。
------------------------------------->>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<-------------------------------------------
序列化 java对象(内存) ←→ 二进制流
目的: A。在有些时候,需要把对象存储到外部存储中持久保持
B。在有些时候,需要把对象通过网络传输。
......
● 可序列化的对象,Java要求可序列化的类实现下面两个接口的任意之一:
— Serializable:接口只是一个标记性的接口,实现该接口无需实现任何方法。
— Externalizable 实现该接口要实现方法。
● 序列化的IO流:
ObjectInputStream — 负责从二进制流“恢复”对象。readObject
ObjectOutputStream — 负责把对象保存到二进制中。writeObiect
● 引用变量的序列化机制
A。引用变量所引用的对象的所有属性的类都应该是可序列化的。
B。序列化的底层机制:
(1)每序列化一个对象,都会给为该对象设置一个编号
(2)如果程序第一次序列化某个对象。系统会真的将该对象序列化、并输出。
(3)如果要序列化的对象是之前已经序列化的。此时系统只输出一个编号。 这种序列化机制,就是为了保存磁盘里的二进制与内存中的对象是对应的。
● transient — 修饰符。
用于修饰实例成员变量。(不能与static同时使用!)
transient 用于执行被修饰的Field不会被序列化。
static修饰的是类变量 — 序列化机制负责序列化实例。
static修饰的类变量存储在类信息中,并不是在存储在对象里 ——因此static修饰的类变量不会被序列化!
为什么要用transient?
对于一些敏感信息,比如银行卡帐号、密码,就不应该被序列化出来,此时就可以通过transinet来修饰这些属性。
● 完全自定义的序列化
对于一些敏感信息,可以使用transient来阻止它们进行序列化。
但将一些属性完全阻止在序列化之外,有时候也并不完善。
此时可以借助与“定制序列化”,
自定义序列化机制,为序列化类增加如下两个方法:
--> 系统会调用这两个方法完成实际的序列化
private void writeObject(java.io.ObjectOutputStream out)
throws IOException
{
out.writeUTF(account);//自然也可以做更复杂的加密
out.writeUTF(new StringBuilder(password).reverse().toString)
} private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException
{
//恢复的顺序要与之前写入的顺序保持一致
this.account = in.readUTF();
this.password = new StringBuilder(in.readUTF().reverse().toString());
}
● 版本号
当我们的类经常使用时,有时候系统无法确定“反序列化”的class文件是否还正确。
建议显示为“可序列化”指定一个版本号。
/*即使你不指定,系统也默认一个版本号,但不稳定*/
seralver.exe — 专门用于查看该类的版本号
seralver — show:显示图形化界面
seralver 完整的类名:显示制定的类的版本号
定义版本号:十分简单: static final long serialVersionUID = 50L;
—— 自定义的版本号的好处:更稳定。 只有当我们修改了类定义时,可由程序员显示地控制改变版本号。
Java 7 传统的Java里,只有一个File类,即代表文件,又代表目录。
=== Arrays Object 、Collections 、Paths 、Files ====
Path — 接口,专门代表了一个平台无关的路径。
Paths — 工具类。所有的方法都是static的。
Files — 操作文件的工具类。 提供了大量的方法来操作文件。
------------------------------------->>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<-------------------------------------------
Java之IO流详解的更多相关文章
- JAVA中IO流详解
IO流:数据传输是需要通道的,而IO流就是数据传输的通道. IO流可以形象的比喻为运送货物的传输带. IO流的分类: ①根据操作的数据类型的不同可以分为 :字节流与字符流. ②根据数据的流向分为:输入 ...
- java之IO流详解(一)
IO流的分类: A:流向 输入流 读取数据 输出流 写出数据 B:数据类型 字节流 字节输入流 InputStream 字节输出流 OutputStream 字符流 字符输入流 Reader 字 ...
- java之IO流详解(二)
好了,昨天讲了字节流,现在我们就来讲字符流吧... 字符流可以这样理解,字符流 = 字节流 + 编码表,目的是为了更好的操作中文字符(注:字符流只可以可以操作字符类型的文件,不能操作影音图像文件,要操 ...
- 基于JavaSE阶段的IO流详解
1.IO流基本概述 在Java语言中定义了许多针对不同的传输方式,最基本的就是输入输出流(俗称IO流),IO流是属于java.io包下的内容,在JavaSE阶段主要学下图所示的: 其中从图中可知,所有 ...
- Java io流详解四
转载地址:http://www.cnblogs.com/rollenholt/archive/2011/09/11/2173787.html 写在前面:本文章基本覆盖了java IO的全部内容,jav ...
- java IO流详解
流的概念和作用 学习Java IO,不得不提到的就是JavaIO流. 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...
- Java io流详解二
原文地址https://www.cnblogs.com/xll1025/p/6418766.html 一.IO流概述 概述: IO流简单来说就是Input和Output流,IO流主要是用来处理设备之间 ...
- Java io流详解一
原文地址http://www.cnblogs.com/xdp-gacl/p/3634409.html java基础学习总结——流 一.JAVA流式输入/输出原理
- 《Java基础知识》Java IO流详解
Java IO概念 1. 用于设备之间的数据传输. 2. Java 将操作数据流的功能封装到了IO包中. 3. 数据流流向分:输入流和输出流,操作对象为文件. 4. 流按照操作数据分:字节流(通用)和 ...
随机推荐
- Unity UI 基础【译】
https://unity3d.com/cn/learn/tutorials/topics/best-practices/fundamentals-unity-ui?playlist=30089 理解 ...
- select效果联动
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <hea ...
- Native App和Web App 的差异
开发者们都知道在高端智能手机系统中有两种应用程序:一种是基于本地(操作系统)运行的APP:一种是基于高端机的浏览器运行的WebApp,本文将主要讲解后者. WebApp与Native App有何区别呢 ...
- Set ,List,ArrayList,LinkedList,Vectory,HashMap,Hashtable,HashSet,TreeSet,TreeSet
Set与List区别: 两者都是接口,并继承Collection接口:List有序,允许重复:Set无序,不能重复: ArrayList与LinkList区别: ArrayList是动态数组,查询效率 ...
- php头像上传预览
php头像上传带预览: 说道上传图片,大家并不陌生,不过,在以后开发的项目中,可能并不会让你使用提交刷新页面式的上传图片,比如上传头像,按照常理,肯定是在相册选择照片之后,确认上传,而肯定不会通过fo ...
- VS2015如何新建C++或者C语言版的lib文件
当我们不想公开我们的代码的时候,可以把我们的代码封装成静态数据连接库,即lib文件.下面介绍下如何生成lib文件. 以VS2015为例,一种是C++版的lib文件,一种是C语言版的lib文件. 一.按 ...
- POJ1850-Code 递推数学
题目链接:http://poj.org/problem?id=1850 题目大意: 按照字典序对升序排列组成的字母进行编号,给出一个长度不超过10的串,求出它的编号是多少?如果无法进行编号则输出0. ...
- [刷题]Codeforces 785D - Anton and School - 2
Description As you probably know, Anton goes to school. One of the school subjects that Anton studie ...
- 用Docker在一台笔记本电脑上搭建一个具有10个节点7种角色的Hadoop集群(上)-快速上手Docker
如果想在一台电脑上搭建一个多节点的Hadoop集群,传统的方式是使用多个虚拟机.但这种方式占用的资源比较多,一台笔记本能同时运行的虚拟机的数量是很有限的.这个时候我们可以使用Docker.Docker ...
- 工厂模式(Factory)和抽象工厂模式(Abstract Factory)
一.工厂模式(Factory):通过让子类决定该创建的对象是什么,来达到将对象创建的过程封装的目的,工厂方法让类的实例化推迟到子类 (1)涉及角色:抽象产品,具体产品,抽象创建者,具体创建者. ...