Java 基础-IO、stream 流、文件操作
输入输出流的分类
在 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 流、文件操作的更多相关文章
- Java基础-IO流对象之字节流(Stream)
Java基础-IO流对象之字节流(Stream) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在前面我分享的笔记中,我们一直都是在操作文件或者文件夹,并没有给文件中写任何数据.现 ...
- Java基础-IO流对象之随机访问文件(RandomAccessFile)
Java基础-IO流对象之随机访问文件(RandomAccessFile) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.RandomAccessFile简介 此类的实例支持对 ...
- Java基础-IO流对象之内存操作流(ByteArrayOutputStream与ByteArrayInputStream)
Java基础-IO流对象之内存操作流(ByteArrayOutputStream与ByteArrayInputStream) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.内存 ...
- Java基础IO流(二)字节流小案例
JAVA基础IO流(一)https://www.cnblogs.com/deepSleeping/p/9693601.html ①读取指定文件内容,按照16进制输出到控制台 其中,Integer.to ...
- Java基础-IO流对象之序列化(ObjectOutputStream)与反序列化(ObjectInputStream)
Java基础-IO流对象之序列化(ObjectOutputStream)与反序列化(ObjectInputStream) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.对象的序 ...
- Java基础-IO流对象之字符缓冲流(BufferedWriter与BufferedReader)
Java基础-IO流对象之字符缓冲流(BufferedWriter与BufferedReader) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.字符缓冲流 字符缓冲流根据流的 ...
- Java基础-IO流对象之字节缓冲流(BufferedOutputStream与BufferedInputStream)
Java基础-IO流对象之字节缓冲流(BufferedOutputStream与BufferedInputStream) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在我们学习字 ...
- Java基础-IO流对象之转换流(InputStreamReader与OutoutStreamWriter)
Java基础-IO流对象之转换流(InputStreamReader与OutoutStreamWriter) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.转换流概述 我们之前 ...
- Java基础-IO流对象之File类
Java基础-IO流对象之File类 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.IO技术概述 回想之前写过的程序,数据都是在内存中,一旦程序运行结束,这些数据都没有了,等下 ...
- 《Java基础——IO流》
Java基础--IO流 一.字节流: 1.输入流 (InputStream) 规则: 此处用于读取txt文件中的内容. 代码: import java.io.*; public c ...
随机推荐
- SSM框架返回json数据
常见错误:No converter found for return value of type: class .................. 原因分析:这是因为springmvc默认是没有对象 ...
- [转载]关于晶振ppm
写得不错,小白的我学习了 原文地址:关于晶振ppm作者:thomaswangbj XXppm就是说频率的误差=(xx/百万)*振荡器的标称频率 eg1:120ppm,27M的晶振,频率的误差 = 12 ...
- STM32 常用词汇释义
1.AF——Alternate function 复用功能: 2.NVIC——Nested Vectored Interrupt Controller 内嵌向量中断控制器 3.ISER[8]— ...
- vb中typename函数
适用于获得一个变量的类型名称的, 比如 A 是一个字符串变量,那么 TypeName(A)=String
- 实现自己的BeanFactory、AOP以及声明式事务
实现自己的BeanFactory 在使用spring时,我们很少用& ...
- 10年前文章_嵌入开发使用的服务器配置 tftp ,http,nfs
tftp server 安装 dnsmasq, 在目录 /etc/dnsmasq.d 下生成包含如下内容的配置文件 tftp.conf enable-tftptftp-root=/tftpboot ...
- dd命令注意:dd:unrecognized operand 'if'
如果是 idd if=boot.bin 在等号两边不要有空格
- bzoj4764 弹飞大爷 LCT
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4764 题解 如果 \(a_i > 0\) 的话,那么就是 bzoj2002 的原题.直接 ...
- Ldap 从入门到放弃(一)
OpenLDAP 2.4版本 快速入门 本文内容是自己通过官网文档.网络和相关书籍学习和理解并整理成文档,其中有错误或者疑问请在文章下方留言. 一.Introduction to OpenLDAP D ...
- 【leetcode】848. Shifting Letters
题目如下: 解题思路:本题首先要很快速的计算出任意一个字符shift后会变成哪个字符,其实也很简单,让shift = shift % 26,接下来再做计算.第二部是求出每个字符要shift的次数.可以 ...