1. 流分为字节流和字符流
2. 字节流下面常用的又有数据流和对象流
3. 字符流下面常用的又有缓存流

文件对象
文件和文件夹都用File表示
//file path : 文件的绝对路径或相对路径File file=new File("file path");
注:文件路径可能不存在
File的常用方法自行查阅API
什么是流(Stream),流就是一系列的数据
当不同的介质之间有数据交互的时候,JAVA就使用流来实现。
数据源可以是文件,还可以是数据库,网络甚至是其他的程序
比如读取文件的数据到程序中,站在程序的角度来看,就叫做输入流
输入流: InputStream
输出流:OutputStream
3.1、字节流,关闭流的方式
以字节的形式读取和写入数据
所有的数据存放在计算机中都是以数字的形式存放的。 所以字母就需要转换为数字才能够存放。
比如A就对应的数字65,a对应的数字97. 不同的字母和符号对应不同的数字,就是一张码表。
ASCII是这样的一种码表。 字包含简单的英文字母,符号,数字等等。 不包含中文,德文,俄语等复杂的。

3.1.1、输入字节流
InputStream是字节输入流,同时也是抽象类,只提供方法的生命,不提供方法的实现。
FileInputStream是InputStream的子类以FIleInputStream为例进行文件读取:
package stream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class TestStream {
public static void main(String[] args) {
try {
//准备文件lol.txt其中的内容是AB,对应的ASCII分别是65 66
File f =new File("d:/lol.txt");
//创建基于文件的输入流
FileInputStream fis =new FileInputStream(f);
//创建字节数组,其长度就是文件的长度
byte[] all =new byte[(int) f.length()];
//以字节流的形式读取文件所有内容
fis.read(all);
for (byte b : all) {
//打印出来是65 66
System.out.println(b);
}
//每次使用完流,都应该进行关闭
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
3.1.2、输出字节流
OutputStream是字节输出流,同时也是抽象类,只提供方法声明,不提供方法的具体实现。
FileOutputStream 是OutputStream子类,以FileOutputStream 为例向文件写出数据
注: 如果文件d:/lol2.txt不存在,写出操作会自动创建该文件。
但是如果是文件 d:/xyz/lol2.txt,而目录xyz又不存在,会抛出异常
package stream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class TestStream {
public static void main(String[] args) {
try {
// 准备文件lol2.txt其中的内容是空的
File f = new File("d:/lol2.txt");
// 准备长度是2的字节数组,用88,89初始化,其对应的字符分别是X,Y
byte data[] = { 88, 89 };
// 创建基于文件的输出流
FileOutputStream fos = new FileOutputStream(f);
// 把数据写入到输出流
fos.write(data);
// 关闭输出流
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
3.1.3、在try中关闭
在try的作用域里关闭文件输入流,在前面的示例中都是使用这种方式,这样做有一个弊端;
如果文件不存在,或者读取的时候出现问题而抛出异常,那么就不会执行这一行关闭流的代码,存在巨大的资源占用隐患。 不推荐使用
package stream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class TestStream {
public static void main(String[] args) {
try {
File f = new File("d:/lol.txt");
FileInputStream fis = new FileInputStream(f);
byte[] all = new byte[(int) f.length()];
fis.read(all);
for (byte b : all) {
System.out.println(b);
}
// 在try 里关闭流
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3.1.4、在finally中关闭
这是标准的关闭流的方式
1. 首先把流的引用声明在try的外面,如果声明在try里面,其作用域无法抵达finally.
2. 在finally关闭之前,要先判断该引用是否为空
3. 关闭的时候,需要再一次进行try catch处理
这是标准的严谨的关闭流的方式,但是看上去很繁琐,所以写不重要的或者测试代码的时候,都会采用上面的有隐患try的方式,因为不麻烦~
package stream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class TestStream {
public static void main(String[] args) {
File f = new File("d:/lol.txt");
FileInputStream fis = null;
try {
fis = new FileInputStream(f);
byte[] all = new byte[(int) f.length()];
fis.read(all);
for (byte b : all) {
System.out.println(b);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 在finally 里关闭流
if (null != fis)
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
3.1.5、使用try()的方式
把流定义在try()里,try,catch或者finally结束的时候,会自动关闭
这种编写代码的方式叫做 try-with-resources, 这是从JDK7开始支持的技术
所有的流,都实现了一个接口叫做 AutoCloseable,任何类实现了这个接口,都可以在try()中进行实例化。 并且在try, catch, finally结束的时候自动关闭,回收相关资源。
package stream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class TestStream {
public static void main(String[] args) {
File f = new File("d:/lol.txt");
//把流定义在try()里,try,catch或者finally结束的时候,会自动关闭
try (FileInputStream fis = new FileInputStream(f)) {
byte[] all = new byte[(int) f.length()];
fis.read(all);
for (byte b : all) {
System.out.println(b);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
综合实例




3.2、字符流,中文编码问题
Reader是字符输入流
Writer是字符输出流
专门用于字符形式读取和写入数据
3.2.1、使用字符流读取文件
FileReader是Reader子类,以FileReader为例进行文件读取
package stream;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class TestStream {
public static void main(String[] args) {
// 准备文件lol.txt其中的内容是AB
File f = new File("d:/lol.txt");
// 创建基于文件的Reader
try (FileReader fr = new FileReader(f)) {
// 创建字符数组,其长度就是文件的长度
char[] all = new char[(int) f.length()];
// 以字符流的形式读取文件所有内容
fr.read(all);
for (char b : all) {
// 打印出来是A B
System.out.println(b);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
3.2.2、使用字符流把字符串写到文件
FileWriter是Writer的子类,以FileWriter为例把字符串写到文件
package stream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class TestStream {
public static void main(String[] args) {
// 准备文件lol2.txt
File f = new File("d:/lol2.txt");
// 创建基于文件的Writer
try (FileWriter fr = new FileWriter(f)) {
// 以字符流的形式把数据写入到文件中
String data="abcdefg1234567890";
char[] cs = data.toCharArray();
fr.write(cs);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
3.2.3、常见编码
工作后经常接触的编码方式有如下几种:
ISO-8859-1 ASCII 数字和西欧字母
GBK GB2312 BIG5 中文
UNICODE (统一码,万国码)

其中
ISO-8859-1 包含 ASCII
GB2312 是简体中文,BIG5是繁体中文,GBK同时包含简体和繁体以及日文。
UNICODE 包括了所有的文字,无论中文,英文,藏文,法文,世界所有的文字都包含其中
3.2.4、UNICODE和UTF
UNICODE因为要存放所有的数据,所以完全按照UNICODE的方式来存储数据,就会有很大的浪费
在这种情况下,就出现了UNICODE的各种减肥子编码,比如UTF-8对数字和字符就使用一个字节,而对汉字就使用3个字节,从而达到了减肥还能保证健康的效果

3.2.5、Java采用的Unicode
写在.java源代码中的汉字,在执行之后,都会变成JVM中的字符。
而这些中文字符采用的编码方式,都是使用UNICODE.
3.3、缓存流
以介质是硬盘为例,字节流和字符流的弊端:
在每一次读写的时候,都会访问硬盘。 如果读写的频率比较高的时候,其性能表现不佳。

为了解决以上弊端,采用缓存流。
缓存流在读取的时候,会一次性读较多的数据到缓存中,以后每一次的读取,都是在缓存中访问,直到缓存中的数据读取完毕,再到硬盘中区读取。

就好比吃饭,不用缓存就是每吃一口都到锅里去铲。用缓存就是先把饭盛到碗里,碗里的吃完了,再到锅里去铲

缓存流在写入数据的时候,会先把数据写入到缓存区,直到缓存区达到一定的量,才把这些数据,一起写入到硬盘中去。按照这种操作模式,就不会像字节流,字符流那样每写一个字节都访问硬盘,从而减少了IO操作
3.3.1、使用缓存流读取数据
缓存字符输入流 BufferedReader 可以一次读取一行数据
package stream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class TestStream {
public static void main(String[] args) {
// 准备文件lol.txt其中的内容是
// garen kill teemo
// teemo revive after 1 minutes
// teemo try to garen, but killed again
File f = new File("d:/lol.txt");
// 创建文件字符流
// 缓存流必须建立在一个存在的流的基础上
try (
FileReader fr = new FileReader(f);
BufferedReader br = new BufferedReader(fr);
)
{
while (true) {
// 一次读一行
String line = br.readLine();
if (null == line)
break;
System.out.println(line);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
3.3.2、使用缓存流写出数据
PrintWriter 缓存字符输出流, 可以一次写出一行数据
package stream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class TestStream {
public static void main(String[] args) {
// 向文件lol2.txt中写入三行语句
File f = new File("d:/lol2.txt");
try (
// 创建文件字符流
FileWriter fw = new FileWriter(f);
// 缓存流必须建立在一个存在的流的基础上
PrintWriter pw = new PrintWriter(fw);
) {
pw.println("garen kill teemo");
pw.println("teemo revive after 1 minutes");
pw.println("teemo try to garen, but killed again");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
3.3.3、flush
有的时候,需要立即把数据写入到硬盘,而不是等缓存满了才写出去。 这时候就需要用到flush
package stream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class TestStream {
public static void main(String[] args) {
//向文件lol2.txt中写入三行语句
File f =new File("d:/lol2.txt");
//创建文件字符流
//缓存流必须建立在一个存在的流的基础上
try(FileWriter fr = new FileWriter(f);PrintWriter pw = new PrintWriter(fr);) {
pw.println("garen kill teemo");
//强制把缓存中的数据写入硬盘,无论缓存是否已满
pw.flush();
pw.println("teemo revive after 1 minutes");
pw.flush();
pw.println("teemo try to garen, but killed again");
pw.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

【Java中级】(三)IO的更多相关文章

  1. Java中的IO流(三)

    上一篇<Java中的IO流(二)>把学习Java的字符流以及转换流作了一下记录,从本篇开始将把IO流中对文件或文件夹操作的对象File类的学习进行一下记录. 一,File类的构造函数及字段 ...

  2. Java EE : 三、图解Session(会话)

    目录 Java EE : 一.图解Http协议 Java EE : 二.图解 Cookie(小甜饼) Java EE : 三.图解Session(会话) 概述 一.Session由来 二.Sessio ...

  3. JAVA第三周作业(从键盘输入若干数求和)

    JAVA第三周作业(从键盘输入若干数求和) 在新的一周,我学习了JAVA的IO编程.下面的代码实现了从键盘输入若干数求和的目标.import java.util.Scanner; public cla ...

  4. java中的io系统详解 - ilibaba的专栏 - 博客频道 - CSDN.NET

    java中的io系统详解 - ilibaba的专栏 - 博客频道 - CSDN.NET 亲,“社区之星”已经一周岁了!      社区福利快来领取免费参加MDCC大会机会哦    Tag功能介绍—我们 ...

  5. java中的IO操作总结

    一.InputStream重用技巧(利用ByteArrayOutputStream) 对同一个InputStream对象进行使用多次. 比如,客户端从服务器获取数据 ,利用HttpURLConnect ...

  6. java学习一目了然——IO

    java学习一目了然--IO IO是java学习当中很重要的一部分.IO流实现数据的上传下载,即读写数据,包括输入和输出流,输入流指的是将数据以字符或字节形式从外部媒介比如文件.数据库等读取到内存中所 ...

  7. Java进阶(三十二) HttpClient使用详解

    Java进阶(三十二) HttpClient使用详解 Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性(具体区别,日后我们 ...

  8. Java进阶(三十一) Web服务调用

    Java进阶(三十一) Web服务调用 前言 有朋友问了一个问题:如何调用已知的音乐服务接口,服务文档如下: https://www.evernote.com/shard/s744/sh/c37cd5 ...

  9. java开发知识IO知识之输入输出流以及文件

    目录 java开发知识IO知识之输入输出流以及文件 一丶流概述 二丶输入流讲解 InputStream类. 1. 输入流以及类层次结构 2.文件操作.使用输入流读取 三丶输出流 OutputStrea ...

  10. 第54节:Java当中的IO流(中)

    Java当中的IO流(中) 删除目录 // 简书作者:达叔小生 import java.io.File; public class Demo{ public static void main(Stri ...

随机推荐

  1. QT---Winsocket获取网关(Gateway) 主机IP等信息

      基于WinPcap库做开发,需要利用到局域网的默认网关地址和Mac地址,但是WinPcap实现获取网关IP地址没有很好的思路,可以知道的是网关的接收和发出的数据包数量一般是比局域网内的各主机要多的 ...

  2. ADMethodsAccountManagement 一些简单注释添加

    using System; using System.Collections; using System.Text; using System.DirectoryServices.AccountMan ...

  3. vue补充

    一.安装vue-cli脚手架 1.淘宝镜像下载 用淘宝的国内服务器来向国外的服务器请求,我们向淘宝请求,而不是由我们直接向国外的服务器请求,会大大提升请求速度,使用时,将所有的npm命令换成cnpm即 ...

  4. Web框架之Django重要组件(Django中间件、csrf跨站请求伪造)

    Web框架之Django_09 重要组件(Django中间件.csrf跨站请求伪造)   摘要 Django中间件 csrf跨站请求伪造 一.Django中间件: 什么是中间件? 官方的说法:中间件是 ...

  5. Linux下多网卡绑定bond及模式介绍

    [介绍] 网卡bond一般主要用于网络吞吐量很大,以及对于网络稳定性要求较高的场景. 主要是通过将多个物理网卡绑定到一个逻辑网卡上,实现了本地网卡的冗余,带宽扩容以及负载均衡. Linux下一共有七种 ...

  6. 使用docker部署zabbix

    1 官方地址 官方写的很详细并且是中文的,一步步按照操作就可以 https://www.zabbix.com/documentation/3.4/zh/manual/installation/cont ...

  7. lower_bound 和 upper_bound 功能和用法

    以前用这两个函数的时候,简单看了几句别人的博客,记住了大概,用的时候每用一次就弄混一次,相当难受,今天对照着这两个函数的源码和自己的尝试发现:其实这两个函数只能用于 "升序" 序列 ...

  8. 美化Div的边框

    CSS修饰Div边框 大部分时候,Div的边框真的做的太丑了,如果不用很多样式来修饰的话,它永远都是那么的突兀.作为一个后端开发,前端菜鸡,在没有设计和前端开发自己独自做项目的时候常常会遇到Div边框 ...

  9. MySQL 全文索引实现简单版搜索引擎

    目录 前言 使用 三种类型的全文搜索方式 相关参数 测试innodb引擎使用全文索引 准备 使用默认方式创建全文索引 使用ngram分词解析器创建全文索引 结论 前言 只有Innodb和myisam存 ...

  10. RocketMQ与MYSQL事务消息整合

    1.基础理论知识篇“两阶段提交”如果你了解可以跳过这段,当然如果你想深入了解你可以购买相关书籍或去搜索相关资料阅读 两阶段提交分为 正常提交和异常提交或异常回滚 上面是正常提交的示意图,协调者发起预提 ...