java.io 包下需要掌握的流有 16 个,本篇内容包括:java.io包下需要掌握的流、Java IO 案例。
java.io 包下需要掌握的流有 16 个:
# 文件专属:
# 转换流:(将字节流转换成字符流)
# 缓冲流专属:
# 数据流专属:
# 标准输出流:
# 对象专属流:
import java.io.FileInputStream;
import java.io.IOException;
/**
* java.io.FileInputStream
* 1) 文件字节输入流、万能的、任何类型的文件都可以采用这个流来读
* 2) 字节的方式,完成输入(读)的操作(磁盘 ---> 内存)
* public int read() throws IOException
* 该方法缺点:一次读取一个字节byte,这样内存和硬盘交互太频繁,时间都耗费在交互上面了
*/
public class FileInputStreamTest01 {
public static void main(String[] args) {
FileInputStream fis = null;
try {
//创建文件字节输入流对象
fis = new FileInputStream("/Users/lizhengi/test/iodemo/temp.txt");
//开始读
int readData = 0;
while ((readData = fis.read()) != -1) {
System.out.print(readData + " ");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//在finally语句块中确保流一定关闭
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
文件中:abcdefg 输出的:97 98 99 100 101 102 103
import java.io.FileInputStream;
import java.io.IOException;
/**
* public int read(byte[] b) throws IOException
* 该方法一次最多读取 b.length 个字节
* 减少内存和硬盘之间的交互,提高程序的执行效率
*/
public class FileInputStreamTest02 {
public static void main(String[] args) {
FileInputStream fis = null;
try {
//创建文件字节输入流对象
fis = new FileInputStream("/Users/lizhengi/test/iodemo/temp.txt");
//开始读,采用byte数组
byte[] bytes = new byte[4];
int readCount = 0;
while ((readCount = fis.read(bytes)) != -1) {
System.out.print(new String(bytes, 0, readCount));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
文件中:abcdefg 输出的:abcdefg
import java.io.FileInputStream;
import java.io.IOException;
/**
* public int available() throws IOException
* 返回此输入流中可以读取(或跳过)的剩余字节数量
* <p>
* public long skip(long n) throws IOException
* 跳过输入流中的n个字节的数据不读
*/
public class FileInputStreamTest03 {
public static void main(String[] args) {
FileInputStream fis = null;
try {
//创建文件字节输入流对象
fis = new FileInputStream("/Users/lizhengi/test/iodemo/temp.txt");
//available()方法 获取该文件中的总字节数量(此时还未读文件,所以数量为全部字节数),存入byte数组中
//该方式不是读大文件,因为byte数组不能太大
byte[] bytes = new byte[fis.available()];
System.out.println("读之前文件中还可以读取的字节数量: " + fis.available());
int readCount = fis.read(bytes);
System.out.println(new String(bytes));
System.out.println("读之后文件中还可以读取的字节数量: " + fis.available());
//skip(long n)方法 跳过几个字节不读
// fis.skip(3);
// System.out.println(fis.read());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
文件中::abcdefg 输出的: 读之前文件中还可以读取的字节数量: 8 abcdefg 读之后文件中还可以读取的字节数量: 0
import java.io.FileOutputStream;
import java.io.IOException;
/**
* java.io.FileOuputStream
* 1) 文件字节输出流,负责写
* 2) 从内存 ---> 硬盘
*/
public class FileOutputStreamTest01 {
public static void main(String[] args) {
FileOutputStream fos = null;
try {
//创建文件字节输出流对象,文件不存在时会自动新建
//该方法会先将原文件清空,然后重新写入,谨慎使用!!!
//fos=new FileOutputStream("F:/myfile.txt");
//下面这种方法在文件末尾追加写入,不会清空原文件内容
fos = new FileOutputStream("/Users/lizhengi/test/iodemo/demo.txt", true);
//开始写
byte[] bytes = {97, 98, 99, 100};
fos.write(bytes);
//写完之后,最后一定记得刷新
fos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
文件中:abcd
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 使用 FileInputStream 和 FileOutputStream 完成对文件的复制
*/
public class CopyTest01 {
public static void main(String[] args) {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
//创建一个文件输入流对象
fis = new FileInputStream("/Users/lizhengi/test/iodemo/temp.txt");
//创建一个文件输出流对象
fos = new FileOutputStream("/Users/lizhengi/test/iodemo/demo.txt");
//核心:一边读,一边写
byte[] bytes = new byte[1024]; //1024B=1KB (一次最多读1KB)
int readCount = 0;
while ((readCount = fis.read(bytes)) != -1) {
fos.write(bytes, 0, readCount);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis == null) {
try {
assert false;
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos == null) {
try {
assert false;
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
输入文件中:abcd 输出文件中:abcd
import java.io.FileReader;
import java.io.IOException;
/**
* java.io.FileReader
* 文件字符输入流,只能读取普通文本
* 读取普通文本时,比较方便快捷
* 能用记事本编辑的都是普通文本文件
*/
public class FileReaderTest {
public static void main(String[] args) {
FileReader reader = null;
try {
//创建文件字符输入流对象
reader = new FileReader("/Users/lizhengi/test/iodemo/temp.txt");
//开始读,字节对应的是byte数组,字符对应的是char数组
char[] chars = new char[4]; //一次读取4个字符
int readCount = 0;
while ((readCount = reader.read(chars)) != -1) {
System.out.print(new String(chars, 0, readCount));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
文件中:abcdefg 输出的:abcdefg
import java.io.FileWriter;
import java.io.IOException;
/**
* java.io.FileWriter
* 文件字符输出流,负责写
* 只能输出普通文本
* 能用记事本编辑的都是普通文本文件
*/
public class FileWriterTest {
public static void main(String[] args) {
FileWriter writer = null;
try {
//创建文件字符输出流对象
writer = new FileWriter("/Users/lizhengi/test/iodemo/temp.txt");
//开始写
char[] chars = {'我', '是', '中', '国', '人'};
writer.write(chars);
writer.write(chars, 2, 3);
writer.write("Java");
//刷新
writer.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
文件中:我是中国人中国人Java
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
/**
* 使用 FileReader 和 FileWriter 完成对文件的复制,只能拷贝普通文本文件
* 能用记事本编辑的都是普通文本文件
*/
public class CopyTest02 {
public static void main(String[] args) {
FileReader reader = null;
FileWriter writer = null;
try {
//读
reader = new FileReader("/Users/lizhengi/test/iodemo/temp.txt");
//写
writer = new FileWriter("/Users/lizhengi/test/iodemo/demo.txt");
//一边读一边写
char[] chars = new char[512]; //一次读取512字节(0.5KB)
int readCount = 0;
while ((readCount = reader.read(chars)) != -1) {
writer.write(chars, 0, readCount);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
输入文件中:我是中国人中国人Java 输出文件中:我是中国人中国人Java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
/**
* java.io.BufferedReader
* 带有缓冲区的字符输入流
* 使用带缓冲区的流的时候不需要自定义byte数组、char数组
**/
public class BufferedReaderTest01 {
public static void main(String[] args) {
BufferedReader br = null;
try {
//当一个流的构造方法中需要另一个流的时候,内部被传进来的流叫做 节点流
//外部负责包装的流叫做 包装流
//也就是说此时,FileReader是节点流,BufferedReader是包装流
br = new BufferedReader(new FileReader("/Users/lizhengi/test/iodemo/temp.txt"));
//循环读,一次读一行
String s = null;
while ((s = br.readLine()) != null) {
System.out.println(s);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭的时候只需要关闭包装流即可,而里面的节点流会自动关闭(详情见源代码)
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
文件中: 我是中国人 中国人 Java 输出的: 我是中国人 中国人 Java
import java.io.*;
public class BufferedReaderTest02 {
public static void main(String[] args) throws IOException {
//最内部是 一个文件字节 输入流
//中间的是 一个字节流转字符流 的输入流
//最外部是 一个缓冲字符 输入流 (也就是实现了字节流 ---> 字符流)
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("/Users/lizhengi/test/iodemo/temp.txt")));
//开始读
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
//只需关闭最外部的包装流即可
br.close();
}
}
文件中: 我是中国人 中国人 Java 输出的: 我是中国人 中国人 Java
import java.io.*;
public class BufferedWriterTest01 {
public static void main(String[] args) throws IOException {
//创建一个缓冲字符输出流
//BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("/Users/lizhengi/test/iodemo/demo.txt")));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("/Users/lizhengi/test/iodemo/demo.txt", true)));
//开始写
bw.write("Hello World!!!");
bw.write("\n");
bw.write("Java I/O流");
bw.write("\n");
//刷新
bw.flush();
//关闭最外部的包装流
bw.close();
}
}
文件中: Hello World!!! Java I/O流
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* java.io.DataOutputStream 数据专属的字节输出流
* 这个流可以将数据连同数据的类型一并写入文件(该文件不是普通的文本文件,无法用记事本打开)
*/
public class DataOutputStreamTest {
public static void main(String[] args) throws IOException {
//创建数据专属的字节输出流
DataOutputStream dos=new DataOutputStream(new FileOutputStream("/Users/lizhengi/test/iodemo/data"));
//写数据
byte b=100;
short s=200;
int i=300;
long j=400;
float f=0.5F;
double d=3.14;
boolean flag=false;
char a='我';
dos.writeByte(b);
dos.writeShort(s);
dos.writeInt(i);
dos.writeLong(j);
dos.writeFloat(f);
dos.writeDouble(d);
dos.writeBoolean(flag);
dos.writeChar(a);
//刷新
dos.flush();
//关闭
dos.close();
}
}
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
/**
* java.io.DataInputStream 数据专属的字节输入流
* DataOutputStream 写的文件只能使用 DataInputStream 来读,同时读的顺序必须和写的顺序一样
*/
public class DataInputStreamTest {
public static void main(String[] args) throws IOException {
//创建数据专属的字节输入流
DataInputStream dis=new DataInputStream(new FileInputStream("/Users/lizhengi/test/iodemo/data"));
//开始读
byte b=dis.readByte();
short s=dis.readShort();
int i=dis.readInt();
long j=dis.readLong();
float f=dis.readFloat();
double d=dis.readDouble();
boolean flag=dis.readBoolean();
char a=dis.readChar();
System.out.println(b);
System.out.println(s);
System.out.println(i);
System.out.println(j);
System.out.println(f);
System.out.println(d);
System.out.println(flag);
System.out.println(a);
//关闭
dis.close();
}
}
输出的: 100 200 300 400 0.5 3.14 false 我
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
/**
* java.io.PrintStream
* 标准字节输出流,默认直接输出到控制台
*/
public class PrintStreamTest {
public static void main(String[] args) throws FileNotFoundException {
System.out.println("Hello World!!!");
//创建一个标准字节输出流对象
PrintStream ps = System.out;
ps.println("Java I/O流");
ps.println("Java 666");
ps.println(123);
//标准输出流不需要手动调用close方法关闭
//修改标准字节输出流的输出方向,输出到 log 文件
PrintStream printStrea m= new PrintStream(new FileOutputStream("/Users/lizhengi/test/iodemo/log"));
System.setOut(printStream);
//再次输出,将不会输出到控制台
System.out.println("Java I/O流");
System.out.println("Java 666");
System.out.println(999);
}
}
输出的: Hello World!!! Java I/O流 Java 666 123 文件中: Java I/O流 Java 666 999
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;
/**
* I/O流和Properties的联合使用
* 设计理念:以后经常改变的数据,可以单独写道一个文件中,使用程序动态读取
* 将来只需要修改这个文件的内容,Java代码不需要修改,不需要重新编译,服务器也不需要重启,就可以拿到动态的数据
* <p>
* 类似于以上机制的文件被称为配置文件,其中的格式为
* key1=value1
* key2=value2 (key重复的情况下,value会自动覆盖)
* 的时候,我们把这种配置文件称为属性配置文件,例如:jdbc.properties
* Java中有规范要求,属性配置文件需要以 .properties 结尾,但这不是必须的
* Properties类是Java中专门存放属性配置文件的一个类
*/
public class IoPropertiesTest {
public static void main(String[] args) throws IOException {
//Properties是一个Map集合,继承了Hashtable,其key和value都是String类型
//这里打算将一个文件中的数据加载到Properties对象中
//新建一个文件字符输入流对象
FileReader reader = new FileReader("/Users/lizhengi/test/iodemo/userinfo.txt");
//创建一个Properties集合
Properties properties = new Properties();
//调用Properties对象的load方法,将文件中的数据加载到Properties集合中
properties.load(reader);
//通过文件中的key获取对应的value
String username = properties.getProperty("username");
String password = properties.getProperty("password");
System.out.println(username);
System.out.println(password);
}
}
文件中: username=root password=12345678 key=value 输出的: root 12345678
import java.io.File;
public class FileTest01 {
public static void main(String[] args) {
File file = new File("/Users/lizhengi/test/iodemo/");
//获取当前目录下的所有子文件
File[] files = file.listFiles();
for (File file1 : files) {
//获取所有子文件的绝对路径
//System.out.println(file1.getAbsolutePath());
//获取所有子文件的文件名
System.out.println(file1.getName());
}
}
}
输出的: demo.txt .userinfo.txt.swp temp.txt log userinfo.txt data