Java IO流
1.流的分类
- 按操作数据单位不分为:字节流(8 bit)二进制文件 字符流(按字符)文本文件
- 按数据流的流向不同分为:输入流(读取) 输出流(写入)
- 按流的角色的不同分为:节点流 处理流/包装流
抽象基类 | 字节流 | 字符流 |
---|---|---|
输入流 | InputStream | Reader |
输出流 | OutputStream | Writer |
-
Java的IO流的类 都是从以上4个抽象基类派生的
-
由着4个类派生出来的子类名称都是以其父类名作为子类名后缀
2.常用的类
- InputStream:字节输入流
- InputStream抽象类是所有类字节输入流的超类
FileInputStream:文件输入流
package hspedu.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class FileInputStream_ {
public static void main(String[] args) {
readFile01();
readFile02();
}
/*演示FileInputStream (字节输入流 文件-->程序)
* 单个字节的读取 效率比较低
* ->使用read(byte[] b) */
static public void readFile01(){
String filePath="D:\\Java\\hspedu\\hello.txt";
int readData=0;
FileInputStream fileInputStream = null;
try {
/*创建FileInputStream对象 用于读取文件*/
fileInputStream = new FileInputStream(filePath);
/*从该输入流读取一个字节的数据 如果没有输入可用 此方法将阻止
* 如果返回-1 表示读取完毕*/
while ((readData=fileInputStream.read())!=-1){
System.out.print((char)readData);//转成char显示
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
//一定要关闭文件流 释放资源
try {
fileInputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
/*使用read(byte[] b) 读取文件 提高效率
* */
static public void readFile02(){
String filePath="D:\\Java\\hspedu\\hello.txt";
/*字节数组*/
byte[] buf=new byte[8];//一次读取8个字节
int readLen=0;
FileInputStream fileInputStream = null;
try {
/*创建FileInputStream对象 用于读取文件*/
fileInputStream = new FileInputStream(filePath);
/*从该输入流读取最多b.length字节的数据到字节数组 如果没有输入可用 此方法将阻止
* 如果返回-1 表示读取完毕
* 如果读取正常 返回实际读取的字节数*/
while ((readLen=fileInputStream.read(buf))!=-1){
System.out.print(new String(buf,0,readLen));//转成char显示
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
//一定要关闭文件流 释放资源
try {
fileInputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
- BufferedInputStream:缓冲字节输入流
- ObjectInputStream:对象字节输入流
- OutputStream:字节输出流
FileOutputStream
package hspedu.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStream01 {
public static void main(String[] args) {
writeFile();
}
/*演示使用FileOutputStream 将数据写入文件
* 如果文件不存在 则创建该文件*/
static public void writeFile(){
/*创建FileOutputStream对象*/
String filePath="D:\\Java\\hspedu\\a.txt";
FileOutputStream fileOutputStream=null;
try {
/*1.new FileOutputStream(filePath) 创建方式 当写入内容时 会覆盖原来的内容
* 2.new FileOutputStream(filePath,true) 创建方式 当写入内容时 会追加到文件后面*/
fileOutputStream=new FileOutputStream(filePath,true);
/*1.写入一个字节*/
// fileOutputStream.write('H');
/*2.写入多个字符串*/
/* String str="hello,world";
*//*str.getBytes() 可以把 字符串->字节数组*//*
fileOutputStream.write(str.getBytes());*/
/*3.写入字符串指定范围的数据
* write(byte[] b,int off,int len) 将len字节从位于off 指定字节数组*/
String str="hello,world";
fileOutputStream.write(str.getBytes(),0,str.length());
System.out.println("写入成功");
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
fileOutputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
- 使用FileInputStream和FileOutputStream完成文件拷贝
package hspedu.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileCopy {
public static void main(String[] args) {
/*完成 文件拷贝 将""D:\GoogleDownload\1.jpg"" 拷贝到D:\Java\hspedu */
/*1.创建文件的输入流 将文件读入到程序
* 2.创建文件的输出流 将读取到的文件数据 写入到指定的文件*/
String srcFilePath = "D:\\GoogleDownload\\1.jpg";
String destFilePath="D:\\Java\\hspedu\\2.jpg";
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try {
fileInputStream = new FileInputStream(srcFilePath);
fileOutputStream=new FileOutputStream(destFilePath);
/*定义一个字节数组 提高读取效果*/
byte[] buf=new byte[1024];
int readLen;
while ((readLen=fileInputStream.read(buf))!=-1){
/*读取到后就写入文件 通过fileOutputStream 边读边写*/
fileOutputStream.write(buf,0,readLen);
}
System.out.println("拷贝成功");
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
/*关流 释放资源*/
try {
if (fileInputStream != null) {
fileInputStream.close();
}
if (fileOutputStream != null) {
fileOutputStream.close();
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
}
FileReader
- 相关方法
- new FileReader(File/String)
- read:每次获取单个字符 返回该字符 如果到文件末尾 返回-1
- read(char[ ]):批量读取多个字符到数组 返回读取到的字符数 如果到文件末尾 返回-1
- new String(char[]):将char[]转换成String
- new String(char[],off,len):将char[]的指定部分转化成String
- 样例代码:
package hspedu.File;
import java.io.FileReader;
import java.io.IOException;
public class FileReader01_ {
public static void main(String[] args) {
// readFile01();
readFile02();
}
/*单个字符读取*/
static public void readFile01() {
String FilePath = "D:\\Java\\hspedu\\story.txt";
FileReader fileReader = null;
int data;
/*1.创建fileReader对象*/
try {
fileReader = new FileReader(FilePath);
/*循环读取 使用read 单个字符读取*/
while ((data = fileReader.read()) != -1) {
System.out.print((char) data);
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
if (fileReader != null) {
fileReader.close();
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
/*字符数组读取*/
static public void readFile02() {
String FilePath = "D:\\Java\\hspedu\\story.txt";
FileReader fileReader = null;
int readLen=0;
char[] buf=new char[8];
/*1.创建fileReader对象*/
try {
fileReader = new FileReader(FilePath);
/*循环读取 使用read(buf) 返回的是实际读取到的字符数
* 返回-1 说明文件结束*/
while ((readLen = fileReader.read(buf)) != -1) {
System.out.print(new String(buf,0,readLen));
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
if (fileReader != null) {
fileReader.close();
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
}
FileWriter 继承于Writer
- 相关方法
- new FileWriter(File/String):覆盖模式 相当于流的指针在首端
FileWriter
类的构造函数会在打开文件时自动创建文件。当你使用new FileWriter(FilePath)
创建FileWriter
对象时,如果指定的文件不存在,Java会尝试创建该文件。因此,即使在代码中没有显式地创建文件的操作,执行程序后文件也会被创建。
- new FileWriter(File/String,true):追加模式 相当于流的指针在尾端
- write(int):写入单个字符
- write(char[]):写入指定数组
- write(char[],off,len):写入指定数组的指定部分
- write(string):写入整个字符串
- write(string,off,len):写入字符串的指定部分
- String类:toCharArray:将String转换成char[]
- new FileWriter(File/String):覆盖模式 相当于流的指针在首端
FileWriter使用后 必须要关闭(close)或刷新(flush) 否则写入不到指定的文件
- 样例代码:
package hspedu.File;
import java.io.FileWriter;
import java.io.IOException;
public class FileWriter_ {
public static void main(String[] args) {
String FilePath = "D:\\Java\\hspedu\\note.txt";
/*创建FileWriter对象*/
FileWriter fileWriter = null;
char[] chars={'a','b','c'};
try {
fileWriter = new FileWriter(FilePath);//覆盖模式
//1.write(int):写入单个字符
fileWriter.write('H');
//2.write(char[]):写入指定数组
fileWriter.write(chars);
//3.write(char[],off,len):写入指定数组的指定部分(指定部分的len表示5个字符)
fileWriter.write("双刀流天下第一".toCharArray(),0,5);
//4.write(string):写入整个字符串
fileWriter.write("你好双刀流!!!");
//5.write(string,off,len):写入字符串的指定部分*/
fileWriter.write("双刀流天下第一",0,2);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
/*==FileWriter使用后 必须要关闭(close)或刷新(flush) 否则写入不到指定的文件==*/
try {
if(fileWriter!=null){
fileWriter.close();
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
System.out.println("程序结束!");
}
}
3.节点流和处理流
-
处理流BufferedReader和BufferedWriter
-
BufferedReader和BufferedWriter属于字符流 是按照字符来读取数据得到
-
关闭时处理流 只需要关闭外层流
-
BufferedReader 字符流
package hspedu.File;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
/*更高效*/
public class BufferedReader_ {
public static void main(String[] args) throws IOException {
String FilePath="D:\\Java\\hspedu\\story.txt";
/*创建bufferedReader*/
/*因为 FileReader 是 Reader 的子类,可以直接传递给 BufferedReader 的构造方法作为参数*/
BufferedReader bufferedReader = new BufferedReader(new FileReader(FilePath));
/*读取*/
String line;//按行读取
while ((line=bufferedReader.readLine())!=null){
System.out.println(line);
}
/*关流 关外层流(BufferedReader) 底层会自动关闭节点流*/
bufferedReader.close();
}
}
- **BufferedWriter **字符流
package hspedu.File;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class BufferedWriter_ {
public static void main(String[] args) throws IOException {
String FilePath="D:\\Java\\hspedu\\ok.txt";
/*创建BufferedWriter对象*/
/*覆盖方式写入*/
// BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(FilePath));
/*追加方式写入*/
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(FilePath,true));
bufferedWriter.write("Hello syhsyh");
/*插入换行*/
bufferedWriter.newLine();
// bufferedWriter.write("\n");
bufferedWriter.write("Hello syhsyh");
/*关闭外层流即可 底层自动关闭new FileWriter(FilePath)*/
bufferedWriter.close();
}
}
- BufferedReader和BufferedWriter 进行文本/字符文件的拷贝
package hspedu.File;
import java.io.*;
public class BufferedCopy_ {
public static void main(String[] args) {
/*BufferedReader和BufferedWriter 操作的是字符文件
* 不可操作 二进制文件(声音 视频 word) 可能会导致文件损坏*/
String srcFilePath="D:\\Java\\hspedu\\story.txt";
String destFilePath="D:\\Java\\hspedu\\b.txt";
BufferedReader br=null;
BufferedWriter bw=null;
String line;
try {
br=new BufferedReader(new FileReader(srcFilePath));
bw=new BufferedWriter(new FileWriter(destFilePath));
while ((line=br.readLine())!=null){
bw.write(line);
bw.newLine();
}
System.out.println("完成");
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
try {
assert br != null;
br.close();
assert bw != null;
bw.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
}
- BufferedInputStream 字节流
- BufferedOutputStream 字节流
- 使用BufferedInputStream和BufferedOutputStream进行二进制文件的拷贝
package hspedu.File;
import java.io.*;
/*使用BufferedInputStream和BufferedOutputStream进行二进制文件的拷贝*/
public class BufferedCopy02_ {
public static void main(String[] args) {
/*BufferedInputStream和BufferedOutputStream既可以操作文本文件 也可以操作二进制文件*/
String srcFilePath="D:\\Java\\hspedu\\2.jpg";
String destFilePath="D:\\Java\\hspedu\\3.jpg";
/*创建对象*/
BufferedInputStream bis=null;
BufferedOutputStream bos=null;
try {
/*因为FileInputStream继承了InputStream*/
bis=new BufferedInputStream(new FileInputStream(srcFilePath));
bos=new BufferedOutputStream(new FileOutputStream(destFilePath));
/*循环读取文件 写入destFilePath*/
byte[] buff=new byte[1024];
int readLen;
while((readLen= bis.read(buff))!=-1){
bos.write(buff,0,readLen);
}
System.out.println("完成");
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
/*关流*/
try {
if(bis!=null) {
bis.close();
}
if(bos!=null) {
bos.close();
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
}
- 对象处理流
- 推荐实现Serializable(中文:可序列化的)接口
- ObjectOutputStream
- 提供序列化功能
- ObjectInPutStram
- 提供反序列化功能