输入输出流的分类

java.io 包中,包含了输入输出操作所需的类。

I/O 流可以安装不同的标准分类:

  • 按照流的方向分类:

    • 输入流:将信息从代码外部输入代码
    • 输出流:将代码得到的数据输出到文件、网络、内存等地方
  • 按照流的分工分类:
    • 节点流:访问磁盘、网络等获取数据的流,可以直接实例化
    • 处理流:对信息进行加工转换的流,需要基于节点流实例化
  • 按处理数据的类型分类:
    • 面向字符的流:处理字符数据,自动实现 Java 内部格式(16 bit char 类型)与外部格式(UTF-8 等)的转换。基类是 Reader 和 Writer
    • 面向字节的流:处理一般数据,基类是 InputStream 和 OutputStream

输入输出流

字符流

字符输入流 Reader

所有的字符输入流都继承自 Reader 类。

常用的字符输入流有:BufferedReader、InputStreamReader、FilterReader、StringReader、PipedReader、CharArrayReader。

字符输出流 Writer

所有的字符输出流都继承自 Writer 类。

常用的字符输出流有:BufferedWriter、OutputStreamWriter、FilterWriter、StringWriter、PipedWriter、CharArrayWriter。

字节流

字节输入流 InputStream

所有的字节输入流都继承自 Writer 类。

常用的字节输入流有:FileInputStream、FilterInputStream(子类 BufferedInputStream)、ByteArrayInputStream。

字节输出流 OutputStream

所有的字节输出流都继承自 Writer 类。

常用的字节输出流有:FileOutputStream、FilterOutputStream(子类 BufferedOutputStream)、ByteArrayOutputStream。

常用的输入输出流

FileInputStream 和 FileOutputStream

这两个类用于按字节读写文件。

FileInputStream 从文件读取字节数据

可以用用字符串类型的文件名或文件对象创建 FileInputStream 类的对象。

  • 使用字符串类型的文件名创建输入流对象读取文件:
InputStream f = new FileInputStream("C:/java/hello");
  • 使用文件对象来创建输入流对象读取文件。首先得使用 File() 方法来创建一个文件对象:
File f = new File("C:/java/hello");
InputStream out = new FileInputStream(f);

FileInputStream 对象的常用方法:

方法名 描述
public void close() throws IOException{} 关闭此文件输入流并释放与此流有关的所有系统资源
protected void finalize()throws IOException {} 清除与该文件的连接。确保在不再引用文件输入流时调用其 close 方法
public int read()throws IOException{} 从 InputStream 对象读取一个字节的数据。返回为整数值。如果已经到结尾则返回-1。
public int read(byte[] r) throws IOException{} 从输入流读取r.length长度的字节。返回读取的字节数。如果是文件结尾则返回-1。
public int available() throws IOException{} 返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取的字节数。返回一个整数值。

FileOutputStream 向文件写字节数据

如果文件不存在,FileOutputStream 会先创建文件。

  • 使用字符串类型的文件名来创建一个输出流对象:
OutputStream f = new FileOutputStream("C:/java/hello")
  • 使用一个文件对象来创建一个输出流来写文件。我们首先得使用File()方法来创建一个文件对象:
File f = new File("C:/java/hello");
OutputStream f = new FileOutputStream(f);

FileOutputStream 对象的常用方法:

方法名 描述
public void close() throws IOException{} 关闭此文件输入流并释放与此流有关的所有系统资源。抛出IOException异常。
protected void finalize()throws IOException {} 这个方法清除与该文件的连接。确保在不再引用文件输入流时调用其 close 方法。抛出IOException异常。
public void write(int w)throws IOException{} 把指定的字节写到输出流中。注意一次只能写一字节
public void write(byte[] w) 把指定数组中w.length长度的字节写到OutputStream中。

示例


import java.io.*; public class StreamTest {
public static void main(String[] args) {
try {
byte [] arr = {'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r'};
OutputStream os = new FileOutputStream("test.txt");
for (byte i : arr) {
os.write(i); // 写一个字节到文件
}
os.write(arr); // 写字节数组到文件
os.close(); File f = new File("test.txt");
InputStream is = new FileInputStream(f);
System.out.println(is.read()); // 显示 104
byte [] arr2 = new byte[10];
is.read(arr2);
for (byte i : arr2) {
System.out.print((char)i);
}
is.close();
is = new FileInputStream(f);
int size = is.available(); for (int i = 0; i < size; i++) {
System.out.print((char)(is.read()));
}
} catch (IOException e) {
System.out.println(e);
}
}
}

上面程序的输出为:

104
ello worhehello worhello wor

文件 test.txt 内容为:

hello worhello wor

OutputStreamWriter 和 InputStreamReader

这两个类用于转换字节流和字符流。

OutputStreamWriter

OutputStreamWriter 是将字符流转为字节流的桥梁,可以用指定的编码将字符编码为字节。可以在构造方法中指定字符集,或者默认用操作系统字符集。

使用字符串类型的文件名来创建一个输出流对象:

OutputStreamWriter osw = new OutputStreamWriter(OutputStream out, CharsetEncoder enc)

OutputStreamWriter 对象的常用方法:

方法名 描述
void close() 关闭流,关闭之前会自动清空
void flush() 清空流
String getEncoding() 返回当前流的字符编码
void write(char[] cbuf, int off, int len) 写入字符数组的一部分
void write(int c) 写入一个字符
void write(String str, int off, int len) 写入字符串的一部分

InputStreamReader

将字节流转为字符流。读取字节并按照指定的字符集解码为字符。

InputStreamReader(InputStream in, Charset cs)

FileOutputStream 对象的常用方法:

方法名 描述
void close() 关闭流并释放相关的系统资源
String getEncoding() 返回当前流使用的字符集编码
int read() 读一个字符
int read(char[] cbuf, int offset, int length) 将字符读到数组的指定部分
boolean ready() 表示当前流是否就绪,可以随时读数据

示例

import java.io.*;

public class StreamTrans {
public static void main(String[] args) throws IOException {
InputStream is = new FileInputStream("test.txt");
InputStreamReader isr = new InputStreamReader(is);
char[] arr = new char[10];
isr.read(arr);
System.out.println(arr);
isr.close();
}
}

FileReader 和 FileWriter

用于按字符读写文件。跟 FileInputStream 和 FileOutputStream 类似。

BufferedReader 和 BufferedWriter

这两个类可以为 I/O 操作提供缓冲区,实现单个字符、数组和字符串的读写。

BufferedReader

继承自 Reader。

比 FileReader 类多了个 readLine() 方法,可以一次读取完整的一行(跨平台)。

BufferedWriter

BufferedWriter 有个跨平台的 newLine() 方法,可以在各个平台实现统一的换行效果。

示例

import java.io.*;

public class BufferedTest {
public static void main(String[] args) {
try {
BufferedWriter bw = new BufferedWriter(new FileWriter("test.txt"));
bw.newLine();
bw.write("hehe");
bw.newLine();
bw.write("hehe");
bw.flush();
BufferedReader br = new BufferedReader(new FileReader("test.txt"));
String line = br.readLine();
while (line != null) {
System.out.println(line);
line = br.readLine();
}
} catch (IOException e) {
System.out.println(e);
}
}
}

输出:


hehe
hehe

DataOutputStream 和 DataInputStream

这两个类具有写各种基本数据类型的方法,且各种类型可以跨平台。另外,可以用 size() 方法统计写入的字节数。

DataOutputStream

常用方法:

方法 描述
void flush() Flushes this data output stream.
int size() 返回当前计数器的值,目前已经写入这个流的字节数
void write(byte[] b, int off, int len) 从指定的字节数组 off 偏移处,写 len 个字节到输出流
void write(int b) 写入指定的字节(参数 b 的低8位)到输出流
void writeBoolean(boolean v) 将布尔数据作为1字节的值写到输出流
void writeByte(int v) 将字节数据作为1字节的值写到输出流
void writeBytes(String s) 将字符串作为字节序列写到输出流
void writeChar(int v) 将字符数据作为2字节的值写到输出流,高位在前
void writeChars(String s) 将字符串作为字符序列写到输出流
void writeDouble(double v) 通过 Double 类中的 doubleToLongBits 方法将double类型参数转为long 类型后,将其完整的8字节写入输出流,高字节在前
void writeFloat(float v)
void writeInt(int v)
void writeLong(long v)
void writeShort(int v)
void writeUTF(String str)

DataInputStream

可以按照指定的类型读取数据。

示例

import java.io.*;

public class DataStream {
public static void main(String[] args) throws IOException {
DataOutputStream dos = new DataOutputStream(new FileOutputStream("test.txt"));
dos.writeInt(666);
dos.writeBoolean(false);
dos.writeChars("hello world");
dos.flush();
System.out.println(dos.size()); // 总字节数
DataInputStream dis = new DataInputStream(new FileInputStream("test.txt"));
System.out.println(dis.readInt()); // 读整型数据
System.out.println(dis.readBoolean());
System.out.println(dis.readByte());
}
}

标准输入输出流

System 类的静态成员变量,包括:

  • System.in:InputStream 类型的标准输入流,默认是键盘
  • System.out:PrintStream 类型的标准输出流,默认是显示器
  • System.err:PrintStream 类型的标准错误输出流,默认也是输出到显示器

按类型输入输出数据

  • printf 方法格式化输出,其中多了 %n 这个平台无关的换行标志
  • Scanner 类从标准输入流获取指定类型的输入,支持 nextLine()、nextByte() 等方法:
Scanner s = new Scanner(System.in);
int i = s.nextInt();

标准输入输出流重定向

可以将标准流重定向到文件,这样在使用标准输出流时,实际使用的就是文件了。

InputStream in = new BufferedInputStream(new FileInputStream("test.txt"));
OutputStream out = new BufferedOutputStream(new FileOutputStream("out.txt"));
System.setIn(in);
System.setOut(out);
System.setErr(out);

File 类

File 类提供了文件的相关操作,包括:

  • 创建、删除、重命名文件
  • 判断文件是否存在
  • 判断文件的读写权限
  • 设置和查询文件的最新修改时间
import java.io.*;

public class FileTest {
public static void main(String[] args) {
File f = new File("test.txt");
if (f.exists()) { // 判断文件或目录是否存在
f.delete(); // 删除文件或目录
} else {
try {
f.createNewFile(); // 创建文件
} catch (Exception e) {
System.out.println(e);
}
}
}
}

对象序列化

如果需要在程序结束时保存对象的信息,可以将对象序列化后保存到磁盘上。前提是对象已经实现了 Serializable 接口:

  • ObjectOutputStream 可以用 writeObject 方法把对象写入磁盘
  • ObjectInputStream 可以用 readObject 方法把对象读入程序

对于序列化时不想保存的属性,可以加 transient 修饰。另外 static 类型的变量,不属于任何一个对象,所以也不会序列化。

RandomAccessFile 类

Java 把输入输出都当做字节流处理,所以对随机的文件读写支持的不太好。

  • 可跳转到文件的任意位置读写
  • RandomAccessFile 类实现了 DataInput 和 DataOutput 接口,可以使用普通读写方法

Java 基础-IO、stream 流、文件操作的更多相关文章

  1. Java基础-IO流对象之字节流(Stream)

    Java基础-IO流对象之字节流(Stream) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在前面我分享的笔记中,我们一直都是在操作文件或者文件夹,并没有给文件中写任何数据.现 ...

  2. Java基础-IO流对象之随机访问文件(RandomAccessFile)

    Java基础-IO流对象之随机访问文件(RandomAccessFile) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.RandomAccessFile简介 此类的实例支持对 ...

  3. Java基础-IO流对象之内存操作流(ByteArrayOutputStream与ByteArrayInputStream)

    Java基础-IO流对象之内存操作流(ByteArrayOutputStream与ByteArrayInputStream) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.内存 ...

  4. Java基础IO流(二)字节流小案例

    JAVA基础IO流(一)https://www.cnblogs.com/deepSleeping/p/9693601.html ①读取指定文件内容,按照16进制输出到控制台 其中,Integer.to ...

  5. Java基础-IO流对象之序列化(ObjectOutputStream)与反序列化(ObjectInputStream)

    Java基础-IO流对象之序列化(ObjectOutputStream)与反序列化(ObjectInputStream) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.对象的序 ...

  6. Java基础-IO流对象之字符缓冲流(BufferedWriter与BufferedReader)

    Java基础-IO流对象之字符缓冲流(BufferedWriter与BufferedReader) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.字符缓冲流 字符缓冲流根据流的 ...

  7. Java基础-IO流对象之字节缓冲流(BufferedOutputStream与BufferedInputStream)

    Java基础-IO流对象之字节缓冲流(BufferedOutputStream与BufferedInputStream) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在我们学习字 ...

  8. Java基础-IO流对象之转换流(InputStreamReader与OutoutStreamWriter)

    Java基础-IO流对象之转换流(InputStreamReader与OutoutStreamWriter) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.转换流概述 我们之前 ...

  9. Java基础-IO流对象之File类

    Java基础-IO流对象之File类 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.IO技术概述 回想之前写过的程序,数据都是在内存中,一旦程序运行结束,这些数据都没有了,等下 ...

  10. 《Java基础——IO流》

    Java基础--IO流       一.字节流:   1.输入流 (InputStream) 规则: 此处用于读取txt文件中的内容.   代码: import java.io.*; public c ...

随机推荐

  1. gp指标信息

    RSI: 相对强弱指数,RSI的原理简单来说是以数字计算的方法求出买卖双方的力量对比 强弱指标理论认为,任何市价的大涨或大跌,均在0-100之间变动,根据常态分配 认为RSI值多在30-70之间变动, ...

  2. iOS之Run Loop详解

    转自标哥的技术博客(www.henishuo.com) 前言 做了一年多的IOS开发,对IOS和Objective-C深层次的了解还十分有限,大多还停留在会用API的级别,这是件挺可悲的事情.想学好一 ...

  3. 自定义UICollectionViewLayout

    UICollectionView在iOS6中第一次被介绍,也是UIKit视图类中的一颗新星.它和UITableView共享API设计,但也在UITableView上做了一些扩展.UICollectio ...

  4. mysql使用MRG_MyISAM(MERGE)实现水平分表

    在MySQL中数据的优化尤其是大数据量的优化是一门很大的学问,当然其它数据库也是如此,即使你不是DBA,做为一名程序员掌握一些基本的优化信息,也可以让你在自己的程序开发中受益匪浅.当然数据库的优化有很 ...

  5. mysql的innodb 引擎 表锁与行锁

    innodb 引擎 行锁与表锁 行锁与表锁是基于索引来说的(且索引要生效) 不带索引 (表锁)要全表扫描 1. 执行select @@autocommit; 查看结果 0是不自动提交事务,1是自动提交 ...

  6. 牛客练习赛33 E tokitsukaze and Similar String (字符串哈希hash)

    链接:https://ac.nowcoder.com/acm/contest/308/E 来源:牛客网 tokitsukaze and Similar String 时间限制:C/C++ 2秒,其他语 ...

  7. POJ 3741 Raid (平面最近点对)

    $ POJ~3741~Raid $ (平面最近点对) $ solution: $ 有两种点,现在求最近的平面点对.这是一道分治板子,但是当时还是想了很久,明明知道有最近平面点对,但还是觉得有点不对劲. ...

  8. hadoop2.7伪分布式搭建

    0.配置主机名 hostnamectl set-hostname spark1 1.上传hadoop-2.7.1.tar.gz文件并解压 tar -xvf hadoop-2.7.1.tar.gz 2. ...

  9. vs code添加到鼠标右键

    首先在页面上新建个文本文件,然后改名和后缀为 add.reg 然后把下面的代码放到里面去,修改路径,然后直接运行就可以了 (路径就是vscode安装的目录) Windows Registry Edit ...

  10. noi 1700 + 1756 八皇后问题 x

    1700:八皇后问题 总时间限制:  10000ms 内存限制:  65536kB 描述 在国际象棋棋盘上放置八个皇后,要求每两个皇后之间不能直接吃掉对方. 输入 无输入. 输出 按给定顺序和格式输出 ...