在java.io包里面File类是唯一 一个与文件本身有关的程序处理类,但是File只能够操作文件本身而不能够操作文件的内容,或者说在实际的开发之中IO操作的核心意义在于:输入与输出操作。而对于程序而言,输入与输出可能来自于不同的环境,例如:通过电脑连接服务器上进行浏览的时候,实际上此时客户端发出了一个信息,而后服务器接收到此信息之后进行回应处理。

对于服务器或者是客户端而言实际上传递的就是一种数据流的处理形式,而所谓的数据流指的就是字节数据。而对于这种流的处理形式在java.io包里面提供有两类支持:

·字节处理流:OutputStream(输出字节流)、InputStream(输入字节流);

·字符处理流:Writer(输出字符流)、Reader(输入字符流);

所有的流操作都应该采用如下统一的步骤进行,下面以文件处理的流程为例:

·如果现在要进行的是文件的读写操作,则一定要通过File类找到一个文件路径;

·通过字节流或字符流的子类为父类对象实例化;

·利用字节流或字符流中的方法实现数据的输入与输出操作;

·流的操作属于资源操作,资源操作必须进行关闭处理;

1. 字节输出流:OutputStream

字节的数据是以byte类型为主实现的操作,在进行字节内容输出的时候可以使用OutputStream类完成,这个类的基本定义如下:

public abstract class OutputStream extends Object implements Closeable, Flushable

  首先可以发现这个类实现了两个接口,于是基本的对应关系如下:

Closeable:

Flushable:

public interface Closeable extends AutoCloseable {public void close​() throws Exception;}

public interface Flushable{public void flush​() throws IOException;}

OutputStream类定义的是一个公共的输出操作标准,而在这个操作标准里面一共定义有三个内容输出的方法。

No

方法名称

类型

描述

01

public abstract void write​(int b) throws IOException

普通

输出单个字节数据

02

public void write​(byte[] b) throws IOException

普通

输出一组字节数据

03

public void write​(byte[] b,int off,int len) throws IOException

普通

输出部分字节数据

但是需要注意的一个核心问题在于:OutputStream类毕竟是一个抽象类,而这个抽象类如果要想获得实例化对象,按照传统的认识应该通过子类实例的向上转完成,如果说现在要进行的是文件处理操作,则可以使用FileOutputStream子类:

因为最终都需要发生向上转型的处理关系,所以对于此时的FileOutputStream子类核心的关注点就可以放在构造方法:

·【覆盖】构造方法:public FileOutputStream​(File file) throws FileNotFoundException;

·【追加】构造方法:public FileOutputStream​(File file,boolean append) throws FileNotFoundException;

范例:使用OutputStream类实现内容的输出

 import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class JavaAPIDemo {
public static void main(String[] args) throws Exception {
File file = new File("D:" + File.separator + "hello" +
File.separator + "mldn.txt"); // 1、指定要操作的文件的路径
if (!file.getParentFile().exists()) { // 文件不存在
file.getParentFile().mkdirs() ; // 创建父目录
}
OutputStream output = new FileOutputStream(file) ; // 2、通过子类实例化
String str = "www.mldn.cn" ; // 要输出的文件内容
output.write(str.getBytes()); // 3、将字符串变为字节数组并输出
output.close(); // 4、关闭资源
}
}

JavaAPIDemo

本程序是采用了最为标准的形式实现了输出的操作处理,并且在整体的处理之中,只是创建了文件的父目录,但是并没有创建文件,而在执行后会发现文件可以自动帮助用户创建。另外需要提醒的是,由于OutputStream子类也属于AutoCloseable接口子类,所以对于close()方法也可以简化使用。

范例:自动关闭处理

 import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class JavaAPIDemo {
public static void main(String[] args) throws Exception {
File file = new File("D:" + File.separator + "hello" + File.separator + "pluto.txt"); // 1、指定要操作的文件的路径
if (!file.getParentFile().exists()) { // 文件不存在
file.getParentFile().mkdirs(); // 创建父目录
}
try (OutputStream output = new FileOutputStream(file, true)) {//true表示追加数据
String str = "www.cnblogs.com\r\n"; // 要输出的文件内容
output.write(str.getBytes()); // 3、将字符串变为字节数组并输出
} catch (IOException e) {
e.printStackTrace();
}
}
}

JavaAPIDemo

是否使用自动的关闭取决于项目的整体结构,另外还需要提醒的是,整个的程序里面最终是输出了一组的字节数据,但是千万不要忘记了,OutputStream类之中定义的输出方法一共有三个。


2. 字节输入流:InputStream

与OutputStream类对应的一个流就是字节输入流,InputStream类主要实现的就是字节数据读取,该类定义如下:

public abstract class InputStream extends Object implements Closeable

  在InputStream类里面定义有如下的几个核心方法:

No

方法名称

类型

描述

01

public abstract int read​()

throws IOException

普通

读取单个字节数据,如果现在已经读取到底,则返回-1

02

public int read​(byte[] b) throws IOException

普通

读取一组字节数据,返回的是读取的个数,如果没有数据已经读取到底则返回-1

03

public int read​(byte[] b,int off,int len) throws IOException

普通

读取一组字节数据(只占数组的部分)

  

InputStream类属于一个抽象类,这时应该依靠它的子类来实例化对象,如果要从文件读取一定使用FileInputStream子类,对于子类而言只关心父类对象实例化。

  构造方法:public FileInputStream​(File file) throws FileNotFoundException;

 import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class JavaAPIDemo {
public static void main(String[] args) throws Exception {
File file = new File("D:" + File.separator + "hello" + File.separator + "mldn.txt");
InputStream input = new FileInputStream(file) ;
byte data [] = new byte [1024] ; // 开辟一个缓冲区读取数据
int len = input.read(data) ; // 读取数据,数据全部保存在字节数组之中,返回读取个数,如果mldn.txt文件中的长度大于1024则只会读取到1024字节长度的信息
System.out.println("【" + new String(data, 0, len) + "】");
input.close();
}
}

JavaAPIDemo

对于字节输入流里面最为麻烦的问题就在于:使用read()方法读取的时候只能够以字节数组为主进行接收。

特别需要注意的是从JDK1.9开始在InputStream类里面增加了一个新的方法:public byte[] readAllBytes​() throws IOException;

 import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class JavaAPIDemo {
public static void main(String[] args) throws Exception {
File file = new File("D:" + File.separator + "hello" + File.separator + "mldn.txt");
InputStream input = new FileInputStream(file) ;
byte data [] = input.readAllBytes() ; // 读取全部数据
System.out.println("【" + new String(data) + "】");
input.close();
}
}

JavaAPIDemo

如果现在要读取的内容很大很大的时候,那么这种读取直接使程序崩溃。如果要使用尽量不要超过10KB。


3. 字符输出流:Writer

使用OutputStream字节输出流进行数据输出的时候使用的都是字节类型的数据,而很多的情况下字符串的输出是比较方便的,所以对于java.io包而言,在JDK1.1的时候又推出了字符输出流:Writer,这个类的定义如下:

public abstract class Writer  extends Object implements Appendable, Closeable, Flushable

  

在Writer类里面提供有许多的输出操作方法,重点来看两个:

·输出字符数组:public void write​(char[] cbuf) throws IOException;

·输出字符串:public void write​(String str) throws IOException;

范例:使用Writer输出

 import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
public class JavaAPIDemo {
public static void main(String[] args) throws Exception {
File file = new File("D:" + File.separator + "hello" + File.separator + "mldn.txt");
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs(); // 父目录必须存在
}
Writer out = new FileWriter(file) ;
String str = "www.mldn.cn" ;
out.write(str);
out.close();
}
}

JavaAPIDemo

JavaAPIDemo

使用Writer输出的最大优势在于可以直接利用字符串完成。Writer是字符流,字符处理的优势在于中文数据上。


4. 字符输入流:Reader

Reader是实现字符输入流的一种类型,其本身属于一个抽象类,这个类的定义如下:

public abstract class Reader extends Object implements Readable, Closeable

  

Reader类里面并没有像Writer类一样提供有整个字符串的输入处理操作,只能够利用字符数据来实现接收:

·接收数据:public int read​(char[] cbuf) throws IOException;

范例:实现数据读取

 import java.io.File;
import java.io.FileReader;
import java.io.Reader;
public class JavaAPIDemo {
public static void main(String[] args) throws Exception {
File file = new File("D:" + File.separator + "hello" + File.separator + "mldn.txt");
if (file.exists()) { // 文件存在则进行读取
Reader in = new FileReader(file) ;
char data[] = new char[1024];
int len = in.read(data) ;
System.out.println("读取内容:" + new String(data,0,len));
in.close();
}
}
}

JavaAPIDemo

字符流读取的时候只能够按照数组的形式来实现处理操作。


5. 字节流与字符流的区别

现在通过一系列的分析已经可以清楚字节流与字符流的基本操作了,但是对于这两类流依然是存在有区别的,重点来分析一下输出的处理操作。在使用OutputStream和Writer输出的最后发现都使用了close()方法进行了关闭处理。

在使用OutputStream类输出的时候如果没有使用close()方法关闭输出流发现内容依然可以实现正常的输出,但是如果在使用Writer的时候没有使用close()方法关闭输出流,那么这个时候内容将无法进行输出,因为Writer使用到了缓冲区,当使用了close()方法的时候实际上会出现有强制刷新缓冲区的情况,所以这个时候会将内容进行输出,如果没有关闭,那么将无法进行输出操作,所以此时如果在不关闭的情况下要想将全部的内容输出可以使用flush()方法强制清空。

范例:使用Writer并强制性清空

 import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
public class JavaAPIDemo {
public static void main(String[] args) throws Exception {
File file = new File("D:" + File.separator + "hello" + File.separator + "mldn.txt");
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs(); // 父目录必须存在
}
Writer out = new FileWriter(file) ;
String str = "www.mldn.cn" ;
out.write(str);
out.flush(); // 强制性刷新
}
}

JavaAPIDemo

问题:可以修改代码使out.flush()存在和不存在的区别?查看这两者有什么区别?

注意:以上例子中的out流不可以关闭,否则会自动flush()便达不到我们想要的结果

字节流在进行处理的时候并不会使用到缓冲区,而字符流会使用到缓冲区。另外使用缓冲区的字符流更加适合于进行中文数据的处理,所以在日后的程序开发之中,如果要涉及到包含有中文信息的输出一般都会使用字符流处理,但是从另外一方面来讲,字节流和字符流的基本处理形式是相似的,由于IO很多情况下都是进行数据的传输使用(二进制)所以本次的讲解将以字节流为主。

Java IO编程——字符流与字节流的更多相关文章

  1. Java IO: 其他字符流(下)

    作者: Jakob Jenkov 译者: 李璟(jlee381344197@gmail.com) 本小节会简要概括Java IO中的PushbackReader,LineNumberReader,St ...

  2. java学习之字符流与字节流的转换

    package com.io; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundExce ...

  3. java多线程的字符流与字节流

    字节流: package com.wz.thread.stream;import java.io.PipedOutputStream;/** * 字节输入流 * @author Administrat ...

  4. Java IO(四--字符流基本使用

    在上一节,介绍了字节流的基本使用,本节介绍一下字符流的使用 Reader: public abstract class Reader implements Readable, Closeable { ...

  5. java IO之 字符流 (字符流 = 字节流 + 编码表) 装饰器模式

    字符流 计算机并不区分二进制文件与文本文件.所有的文件都是以二进制形式来存储的,因此, 从本质上说,所有的文件都是二进制文件.所以字符流是建立在字节流之上的,它能够提供字符 层次的编码和解码.列如,在 ...

  6. [Java IO]03_字符流

    Java程序中,一个字符等于两个字节. Reader 和 Writer 两个就是专门用于操作字符流的类. Writer Writer是一个字符流的抽象类.  它的定义如下: public abstra ...

  7. Java IO之字符流和文件

    前面的博文介绍了字节流,那字符流又是什么流?从字面意思上看,字节流是面向字节的流,字符流是针对unicode编码的字符流,字符的单位一般比字节大,字节可以处理任何数据类型,通常在处理文本文件内容时,字 ...

  8. Java 网络编程 字符流的发送与接收 自定义数据边界

    在网络编程中,客户端调用了flush方法,就会将缓存在字符流中的文本发送给服务器,服务器该怎样判断客户端发送的文本已经结束了呢? 我们先看一个例子: 客户端: import java.io.IOExc ...

  9. Java——文件操作字符流和字节流的区别

    转:http://blog.csdn.net/joephoenix/articles/2283165.aspx java的IO流分两种流 字节流 InputStream OutputStream 字符 ...

随机推荐

  1. 利用Python进行数据分析:【IPython】

    一.IPython基础功能 1.IPython是交互式的Python命令行2.安装与使用 #安装:pip install ipython #使用:ipython与Python解释器的使用方法一致 注: ...

  2. 部份css样式详解(附实际应用)

    本文的所有实例均基于博客园的页面定制. 所有表格内容来自W3CSchool. 页面背景(background) 博客开通之后,很多人最先做的事情一定是改页面的背景,换成一张图片或者换上一个自己喜欢的颜 ...

  3. Linux 远程登录命令telnet

    一.telnet简介: telnet命令通常用来远程登录.telnet程序是基于TELNET协议的远程登录客户端程序.Telnet协议是TCP/IP协议族中的一员,是Internet远程登陆服务的标准 ...

  4. 12-DOM相关案例

    12-关于DOM操作的相关案例   1.模态框案例 需求: 打开网页时有一个普通的按钮,点击当前按钮显示一个背景图,中心并弹出一个弹出框,点击X的时候会关闭当前的模态框 代码如下: <!DOCT ...

  5. String 用法 简单API

    明天天梯赛选拔,怕不是STl忘到姥姥家去了,赶紧复习一下 构造str string s = "fuckyouRMA"; string s1(s, 2); de(s1); strin ...

  6. WebGL简易教程(六):第一个三维示例(使用模型视图投影变换)

    目录 1. 概述 2. 示例:绘制多个三角形 2.1. Triangle_MVPMatrix.html 2.2. Triangle_MVPMatrix.js 2.2.1. 数据加入Z值 2.2.2. ...

  7. 记一次linux Docker网络故障排除经历

    背景: 之前做了一个项目,需要在容器内访问宿主机提供的Redis 服务(这是一个比较常见的应用场景哈), 常规方案: ①   主机网络(docker run --network=host): 完全应用 ...

  8. 无意间做了个 web 版的 JVM 监控端(前后端分离 React+Spring Boot)

    之前写了JConsole.VisualVM 依赖的 JMX 技术,然后放出了一个用纯 JMX 实现的 web 版本的 JConsole 的截图,今天源码来了. 本来就是为了更多的了解 JMX,第一步就 ...

  9. nrm的安装与使用

    nrm的作用:提供了一些最常用的NPM包镜像地址,能够让我们快速的切换安装包时候的服务器地址:,我们依旧使用的事npm的命令,只是镜像地址变了 什么是镜像:原来包刚一开始是只存在于国外的NPM服务器, ...

  10. 树莓派3B/3B+ 清华镜像系统和安装中文输入法Fcitx及Google拼音输入法

    你还在为树莓派无法安装中文输入法而到处找教程吗? 你还在为树莓派每次下载都要远隔重洋获取资源,龟速下载而烦恼吗? 为了解决这个问题,在这篇树莓派教程中,我将手把手叫你怎样安装 清华镜像系统和中文输入法 ...