Java流的分类,一般可按以下方式分:

  1. 按方向分,分为输入流,输出流。
  2. 按类型分,分为字节流和字符流。

    2.1字节流是通过字节来读取数据

    2.2字符流是通过字符来读取数据
  3. 按操作方式分,分为节点流和过滤流。

    3.1 可以直接创建的流称为节点流,比如输入流,输出流

    3.2 过滤流可以装饰节点流,让流的功能变得更加强大,过滤流采用装饰者模式,对输入流进行包装。比如说BufferedInputStream,BufferedOutputStream,DataInputStream,DataOutputStream都是过滤流。
  4. 转换流。

废话不多说,看代码:

使用字节流读取文件内容:

    public void test1(){
File file = new File("F:\\hello.txt");
FileInputStream fis = null;
try {
//创建一个文件输入流
fis = new FileInputStream(file);
//创建一个字节数组用来存储读取的信息
byte[] buf = new byte[1024];
//len表示读取的长度
int len = 0;
//只要len大于-1说明读取到元素,可对元素直接进行操作
while((len=fis.read(buf))>-1){
//通过控制台输出程序,需要指明输出的长度
System.out.write(buf,0,len);
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if (fis!=null) {
//操作完成之后关闭流
fis.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

如何通过操作字节流来实现简单的文件拷贝呢?使用未经包装的输入输出流来拷贝文件,看代码:

    public void test2(){
long startTime = new Date().getTime();
File file = new File("F:\\mysql-installer-community-5.6.22.0.msi");
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream(file);
fos = new FileOutputStream("F:\\1.msi");
byte[] buf = new byte[1024];
int len = 0;
while((len=fis.read(buf))!=-1){
fos.write(buf, 0, len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(fis!=null) fis.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(fos!=null) fos.close();
} catch (IOException e) {
e.printStackTrace();
}
} long endTime = new Date().getTime();
//查看效率
System.out.println((endTime-startTime)/1000);
}

最后的输出结果为2,也就是说拷贝一个接近300M的文件需要两秒钟。

再看看经过BufferedInputStream和BufferedOutputStream包装后的相同文件的拷贝,代码如下:

    public void test3(){
long startTime = new Date().getTime();
File file = new File("F:\\mysql-installer-community-5.6.22.0.msi");
FileInputStream fis = null;
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
fis = new FileInputStream(file);
//将fis包装起来
bis = new BufferedInputStream(fis);
//将输出流包装
bos = new BufferedOutputStream(new FileOutputStream("F:\\2.msi"));
byte[] buf = new byte[1024];
int len = 0;
while((len=bis.read(buf))!=-1){
bos.write(buf, 0, len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
//关闭流之后会自动flush
try {
if(bis!=null) bis.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(bos!=null) bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
long endTime = new Date().getTime();
System.out.println((endTime-startTime)/1000);
}

这里的输出为0,也就是说相同的文件拷贝,包装后的流效率会大大提高,原先需要两秒才能完成的拷贝,现在1秒都不到。

再看DataInputStream和DataOutputStream,这两个依然是将InputStream流包装,包装完成之后可以用它写基本类型数据以及字符型数据。

    public void test4(){
FileOutputStream fos = null;
DataOutputStream dos = null;
DataInputStream dis = null;
try {
fos = new FileOutputStream("F:\\2.txt");
dos = new DataOutputStream(fos);
/**
* 每写一个Int类型数据,相当于写入四个字节数据,占四个字节,long是八个字节
* 依次类推
*/
dos.writeInt(1111);
dos.writeInt(2222);
dos.writeInt(3333);
dis = new DataInputStream(new FileInputStream("F:\\2.txt"));
/**
* 每执行一次readInt(),相当于读取四个字节数据,读取其他数据依次类推
*/
System.out.println(dis.readInt());
System.out.println(dis.readInt());
System.out.println(dis.readInt());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(dos!=null) dos.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(dis!=null) dis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

再看看包装后的字符流输入与输出:

    public void test5(){
BufferedReader br = null;
PrintWriter out = null;
try {
br = new BufferedReader(new FileReader("F:\\hello.txt"));
out = new PrintWriter(new BufferedWriter(new FileWriter("F:\\11.txt")));
String str = null;
while((str=br.readLine())!= null){
System.out.println(str);
out.println(str);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(br!=null) br.close();
} catch (IOException e) {
e.printStackTrace();
}
if(out!=null) out.close();
}
}

字节流和字符流之间的转换,可以使用

字符流 =InputStreamReader(字节流)

把从控制台输入的文本内容转存到文本当中:

    public void test6() {
BufferedReader br = null;
PrintWriter out = null;
try {
br = new BufferedReader(new InputStreamReader(System.in));
out = new PrintWriter(new BufferedWriter(new FileWriter(
"F:\\222.txt")));
String str = null;
while ((str = br.readLine()) != null) {
if (str.trim().equals("exit")) {
break;
}
System.out.println(str);
out.println(str);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null)
br.close();
} catch (IOException e) {
e.printStackTrace();
}
if (out != null)
out.close();
}
}

把一个对象写入到文件中:

    public void writeObject(){
User user = new User("zhangsan","123");
user.setMoney(200);
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream("F:\\object.dat"));
oos.writeObject(user);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(oos!=null) oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

User.java

import java.io.Serializable;

public class User implements Serializable{

    private String username;
private String password; //添加了transient属性的字段不会被存储
private transient int money; public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
public User() {
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}

从文件中读取一个对象:

    public void readObject(){
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream("F:\\object.dat"));
User u = (User) ois.readObject();
System.out.println(u.getUsername()+","+u.getPassword()+","+u.getMoney());
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}

输出结果是:

由于给money字段添加了transient属性,所以money字段并不会被存储,当然也就读取不到。如果在User.java中删除transient,那么输出结果就是:

这个时候money就可被顺利的读取出来。

Java IO学习笔记的更多相关文章

  1. Java IO学习笔记:概念与原理

    Java IO学习笔记:概念与原理   一.概念   Java中对文件的操作是以流的方式进行的.流是Java内存中的一组有序数据序列.Java将数据从源(文件.内存.键盘.网络)读入到内存 中,形成了 ...

  2. Java IO学习笔记总结

    Java IO学习笔记总结 前言 前面的八篇文章详细的讲述了Java IO的操作方法,文章列表如下 基本的文件操作 字符流和字节流的操作 InputStreamReader和OutputStreamW ...

  3. Java IO学习笔记三

    Java IO学习笔记三 在整个IO包中,实际上就是分为字节流和字符流,但是除了这两个流之外,还存在了一组字节流-字符流的转换类. OutputStreamWriter:是Writer的子类,将输出的 ...

  4. Java IO学习笔记二

    Java IO学习笔记二 流的概念 在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成. 程序中的输入输 ...

  5. Java IO学习笔记一

    Java IO学习笔记一 File File是文件和目录路径名的抽象表示形式,总的来说就是java创建删除文件目录的一个类库,但是作用不仅仅于此,详细见官方文档 构造函数 File(File pare ...

  6. Java IO学习笔记一:为什么带Buffer的比不带Buffer的快

    作者:Grey 原文地址:Java IO学习笔记一:为什么带Buffer的比不带Buffer的快 Java中为什么BufferedReader,BufferedWriter要比FileReader 和 ...

  7. Java IO学习笔记二:DirectByteBuffer与HeapByteBuffer

    作者:Grey 原文地址:Java IO学习笔记二:DirectByteBuffer与HeapByteBuffer ByteBuffer.allocate()与ByteBuffer.allocateD ...

  8. Java IO学习笔记三:MMAP与RandomAccessFile

    作者:Grey 原文地址:Java IO学习笔记三:MMAP与RandomAccessFile 关于RandomAccessFile 相较于前面提到的BufferedReader/Writer和Fil ...

  9. Java IO学习笔记四:Socket基础

    作者:Grey 原文地址:Java IO学习笔记四:Socket基础 准备两个Linux实例(安装好jdk1.8),我准备的两个实例的ip地址分别为: io1实例:192.168.205.138 io ...

  10. Java IO学习笔记六:NIO到多路复用

    作者:Grey 原文地址:Java IO学习笔记六:NIO到多路复用 虽然NIO性能上比BIO要好,参考:Java IO学习笔记五:BIO到NIO 但是NIO也有问题,NIO服务端的示例代码中往往会包 ...

随机推荐

  1. perl + 匹配前导模式一次或者多次

    Vsftp:/data01/mysqllog/binlog# cat a2.pl $_="aaaa@[2]sasas"; if ($_ =~/.*?(\@\[[0-9]+\]).* ...

  2. Oracle EBS R12 WIP Component Issue&Return Process

    oracleassemblytransactionscomponentsjobsreference 目录(?)[-] 定义BOM 定义Routing 定义WIP Discrete Job 发料 Mat ...

  3. linux 失败无连接 检查电缆吗

    将BOOTPROTO=dhcp改成 BOOTPROTO=static 改成手动获取IP的模式 原因: 虚拟机中的Linux目前是默认设成的自动获取IP设置,但你的网络中没有DHCP服务,所以会显示“正 ...

  4. word 中Sentences、Paragraph等含义和用法

    word 中有Words,Characters,Sentences.Paragraph,Sections 具体含义如下表达式             含义   返回的对象 Words(index)  ...

  5. 理解SVG坐标系和变换:视窗,viewBox和preserveAspectRatio

    SVG元素不像HTML元素一样由CSS盒模型管理.这使得我们可以更加灵活定位和变换这些元素-也许一眼看上去不太直观.然而,一旦你理解了SVG坐标系和变换,操纵SVG会非常简单并且很有意义.本篇文章中我 ...

  6. Class.forName()数据库驱动

    在学习jdbc中,用到Class.forName(驱动);,当时学习的时候知道Class.forName就是加载一个类到虚拟机,在加载一个类的时候,这个类的信息会被放到一个方法区,一个CLass 在J ...

  7. HDU 4135 Co-prime

    思路:直接用求(b,1)范围内互质的数,(a-1,1)范围内互质的数.再求反 就是敲一下容斥模板 #include<cstdio> #include<cstring> #inc ...

  8. Android 多线程 异步加载

    Android 应用中需要显示网络图片时,图片的加载过程较为耗时,因此加载过程使用线程池进行管理, 同时使用本地缓存保存图片(当来回滚动ListView时,调用缓存的图片),这样加载和显示图片较为友好 ...

  9. ubuntu下git安装及连接github

    1.安装 sudo apt-get install git git-core git-gui git-doc git-svn git-cvs gitweb gitk git-email git-dae ...

  10. Storm系列(二)系统结构及重要概念

    在Storm的集群里面有两种节点:控制节点和工作节点,控制节点上面运行Nimbus进程,Nimbus负责在集群里面分配计算任务,并且监控状态.每一个工作节点上面运行Supervisor进程,Super ...