IO流
1.常用文件操作
1.1创建文件
package createFile;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
public class FileCreate {
@Test
public void createFile01() throws IOException {
String filePath = "D:\\news1.txt";
File file = new File(filePath);
file.createNewFile();
System.out.println("文件1创建成功");
}
@Test
public void createFile02(){
File parentFile = new File("D:\\");
String fileName = "news2.txt";
File file = new File(parentFile, fileName);
try {
file.createNewFile();
System.out.println("文件2创建成功");
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void createFile03(){
String parentPath = "D:\\zxxnotepad\\";
String childpath = "news3.txt";
File file = new File(parentPath,childpath);
try {
file.createNewFile();
System.out.println("文件3创建成功");
} catch (IOException e) {
e.printStackTrace();
}
}
}
1.2获取文件的相关信息
package createFile;
import org.junit.Test;
import java.io.File;
public class FileInformation {
//获取文件的信息
@Test
public void info(){
//先创建文件对象
File file = new File("D:\\news1.txt");
//调用相应方法,得到相应信息
System.out.println("文件名字 " + file.getName());
System.out.println("文件绝对路径 " + file.getAbsolutePath());
System.out.println("文件父级目录 " + file.getParent());
System.out.println("文件大小(字节) " + file.length());
System.out.println("文件是否存在 " + file.exists());
System.out.println("是不是一个文件 " + file.isFile());
System.out.println("是不是一个目录 " + file.isDirectory());
}
}
1.3目录的操作和文件删除
package createFile;
import org.junit.Test;
import java.io.File;
/**
* @author zxx
* @version 1.0
*/
public class Directory {
//判断文件是否存在,如果存在就删除
@Test
public void function1() {
File file = new File("D:\\news1.txt");
if (file.exists()) {
if (file.delete()) {
System.out.println("删除成功");
} else {
System.out.println("删除失败");
}
} else {
System.out.println("文件不存在");
}
}
//判断目录是否存在,若果存在删除,在Java中,目录也被当作文件
@Test
public void function2() {
File file = new File("D:\\test");
if (file.exists()) {
if (file.delete()) {
System.out.println("删除成功");
} else {
System.out.println("删除失败");
}
} else {
System.out.println("目录不存在");
}
}
//判断目录是否存在,若果存在删除,在Java中,目录也被当作文件,不存在则创建
@Test
public void function3() {
File file = new File("D:\\a\\b\\c");
if (file.exists()) {
System.out.println("目录已经存在");
} else {
System.out.println("目录不存在");
if (file.mkdirs()) {
System.out.println("创建成功");
}
}
}
}
2.IO流原理及流的分类
2.1JavaIO流原理
- I/O是Input/Output的缩写,用于处理数据传输,如读写文件,网络通讯等
- Java程序中,对于数据的输入输出以“流(Stream)”的方式进行
- java.io包下提供了各种“流”类和接口,用以获取不同类的数据,并通过方法输入或输出数据
- 输入input:读取外部数据(磁盘、光盘等存储设备上的数据)到程序(内存)中
- 输出output:将程序中(内存)的数据输出到磁盘、光盘等存储设备上
2.2流的分类
-
按操作数据单位不同分为: 字节流(8bit) 、字符流(按字符)
-
按数据流的流向不同分为:输入流、输出流
-
按流的角色不同分为:节点流,处理流(包装流)
-
抽象基类 字节流 字符流 输入流 InputStream Reader 输出流 OutputStream Writer Java的IO流共涉及40多个类,都是从以上4个抽象基类派生的
由这四个类派生出来的子类名称都是以其父类名作为子类名后缀
3.常用的类
3.1InputStream:字节输入流
- FileInputStream:文件输入流
- BufferedInputStream:缓冲字节输入流
- ObjectInputStream:对象字节输入流
package inputStream;
import org.junit.Test;
import java.io.FileInputStream;
import java.io.IOException;
/**
* @author zxx
* @version 1.0
* 演示FileInputStream的使用(字节输入流)
*/
public class FileInputStream_ {
@Test
/**
* 单个字节的读取,效率较低
*/
public void readFile01(){
String filePath = "D:\\news1.txt";
int readData = 0;
FileInputStream fileInputStream = null;
try {
//创建 FileInputStream 对象,用于读取文件
fileInputStream = new FileInputStream(filePath);
//如果文件内容获取结束返回 - 1
while((readData = fileInputStream.read()) != -1){
System.out.println((char)readData);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭文件流,释放资源
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Test
/**
* 使用read(byte[] b)读取文件,提高效率
*/
public void readFile02(){
String filePath = "D:\\news1.txt";
int readLen = 0;
//定义字节数组
byte[] bytes = new byte[11];//一次读取11个字节
FileInputStream fileInputStream = null;
try {
//创建 FileInputStream 对象,用于读取文件
fileInputStream = new FileInputStream(filePath);
//如果文件内容获取结束返回 - 1
while((readLen = fileInputStream.read(bytes)) != -1){
System.out.println(new String(bytes,0,readLen));
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭文件流,释放资源
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3.2OutPutStream:字节输出流
package outPutStream;
import org.junit.Test;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author zxx
* @version 1.0
*
*/
public class FileOutPutStream_ {
/**
* 显示使用FileOutputStream 将数据写到文件中
* 如果文件不存在,则创建该文件
* */
@Test
public void writeFile01() throws IOException {
// 先创建 FileOutputStream 对象
String filePath = "D:\\a.txt";
// 使用 new FileOutputStream(filePath) 创建,会覆盖原来的内容
// 使用 new FileOutputStream(filePath,true) 创建,则会追加到原来内容的后面
FileOutputStream fileOutputStream = new FileOutputStream(filePath,true);
//写入一个字节
fileOutputStream.write('H');
//写入字符串
//str.getBytes() 把字符串转成字节数组
String str = "hello ,world";
fileOutputStream.write(str.getBytes());
//str.getBytes() 把字符串转成字节数组,从第0位写入到第5位
String str1 = "go,go,go,go";
fileOutputStream.write(str1.getBytes(),0,5);
fileOutputStream.close();
}
}
3.3文件Copy
package outPutStream;
import org.junit.Test;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author zxx
* @version 1.0
*/
public class FileCopy {
@Test
public void fileCopy() throws IOException {
String filePath = "D:\\b.txt";
FileOutputStream fileOutputStream = new FileOutputStream(filePath,true);
FileInputStream fileInputStream = new FileInputStream("D:\\a.txt");
byte[] bytes = new byte[11];
int readLen = 0;
//边读边写
while ((readLen = fileInputStream.read(bytes)) != -1) {
fileOutputStream.write(bytes,0,readLen);
}
fileOutputStream.close();
fileInputStream.close();
}
}
3.4FileReader:字符输入流
package reader_;
import org.junit.Test;
import java.io.FileReader;
import java.io.IOException;
/**
* @author zxx
* @version 1.0
*/
public class FileReader_ {
// 单个字符读取
@Test
public void readFile01() throws IOException {
String filePath = "D:\\story.txt";
FileReader fileReader = new FileReader(filePath);
int data = 0;
while ((data = fileReader.read()) != -1) {
System.out.println((char) data);
}
fileReader.close();
}
@Test
public void readFile02() throws IOException {
String filePath = "D:\\story.txt";
FileReader fileReader = new FileReader(filePath);
char[] arr = new char[5];
int readLen = 0;
while ((readLen = fileReader.read(arr))!= -1) {
System.out.print(new String(arr,0,readLen));
}
fileReader.close();
}
}
3.5FileWriter:字符输出流
package writer_;
import org.junit.Test;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
/**
* @author zxx
* @version 1.0
*/
public class FileWriter_ {
@Test
public void fileWriter01() throws IOException {
String filePath = "D:\\note.txt";
File file = new File(filePath);
file.createNewFile();
FileWriter fileWriter = new FileWriter(file,true);
// write(int) 写入单个字符
fileWriter.write('h');
//write(string) 写入字符串
fileWriter.write("xxx");
//write(char[]) 写入字符数组
char[] arr = new char[]{'1','2'};
fileWriter.write(arr);
//write(string,off,len) 字符串的初始位置 + 偏移量
fileWriter.write("我是你爸爸",0,3);
//write(char[]) 字符数组的初始下标 + 偏移量
char[] arr1 = new char[]{'a','b','c'};
fileWriter.write(arr1,1,1);
fileWriter.close();
}
}
4.节点流和处理流
4.1基本介绍
- 节点流可以从一个特定的数据源读写数据,如FileReader、FileWriter
- 处理流(也叫包装流),是“连接”已存在的流(节点流或处理流)之上,微程序提供更为强大的读写功能,也更加灵活,如BufferedReader、BufferedWriter
4.2节点流和处理流的区别和联系
- 节点流时底层流/低级流,直接和数据源相连
- 处理流(包装流)包装节点流,既可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入输出
- 处理流(也叫包装流)对节点流进行包装,使用了修饰器设计模式,不会直接与数据源相连
4.3处理流的功能主要体现在以下两个方面
- 性能的提高:主要以增加缓冲的方式来提高输入输出的效率
- 操作的便捷:处理流提供了一系列便捷的方法来一次输入输出大批量的数据,使用更加灵活方便
- BufferedReader和BufferedWriter属于字符流,是按照字符来读取文件的
- 关闭时,只关闭外层流即可
4.3BufferedReader:字符缓冲输入流
package reader_;
import org.junit.Test;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
/**
* @author zxx
* @version 1.0
* 演示BufferedReader的使用
*/
public class BufferedReader_ {
@Test
public void readFile() throws IOException {
String path = "D:\\story.txt";
//创建 BufferedReader 对象
BufferedReader bufferedReader = new BufferedReader(new FileReader(path));
//按行读取
String line;
while((line = bufferedReader.readLine()) != null){
System.out.println(line);
}
System.out.println(1);
bufferedReader.close();
}
}
4.4BufferedWriter:字符缓冲输出流
package writer_;
import org.junit.Test;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
/**
* @author zxx
* @version 1.0
* 演示BufferedWriter的使用
*/
public class BufferedWriter_ {
@Test
public void fileWriter() throws IOException {
String path = "D:\\hhh.txt";
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(path));
bufferedWriter.write("你好,hhh");
//换行
bufferedWriter.write("\n");
bufferedWriter.newLine();
bufferedWriter.write("嘎嘎嘎");
bufferedWriter.close();
}
}
4.5文件copy(字符)
package writer_;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
public class BufferCopy_ {
public static void main(String[] args) throws Exception {
String srcFilePath = "D:\\story.txt";
String targetFilePath = "D:\\story2.txt";
BufferedReader bufferedReader = new BufferedReader(new FileReader(srcFilePath));
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(targetFilePath));
String line = "";
while((line = bufferedReader.readLine()) != null){
bufferedWriter.write(line);
bufferedWriter.newLine();
}
bufferedReader.close();
bufferedWriter.close();
}
}
4.6BufferInputStream:字节缓冲输入流
4.7BufferOutPutStream:字节缓冲输出流
4.8对象流
用于序列化和反序列化
序列化:保存数据时,保存数据的值和数据类型
反序列化:在恢复数据时,恢复数据的值和数据类型
需要让某个对象支持序列化机制时,则必须让其类是可序列化的,为了让某个类是可序列化的,该类必须实现以下两个接口之一:Serializable(标记接口,没有方法)、Externalizable(有两个方法需要实现,一般不使用)
4.8.1ObjectInputStream :反序列化
package inputStream;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
public class ObjectInputStream_ {
public static void main(String[] args) throws Exception {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d:\\data.dat"));
//反序列化时 需要和 序列化时的顺序一致, 否则会出现异常
System.out.println(ois.readInt());
System.out.println(ois.readBoolean());
System.out.println(ois.readChar());
System.out.println(ois.readDouble());
System.out.println(ois.readUTF());
System.out.println(ois.readObject());
ois.close();
}
}
4.8.2ObjectOutputStream:序列化
package outPutStream;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class ObjectOutPutStream_ {
public static void main(String[] args) throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("d:\\data.txt"));
oos.write(100);
oos.writeBoolean(true);
oos.writeChar('a');
oos.writeDouble(9.5);
oos.writeUTF("zxx");
Dog dog = new Dog(1, "hhh");
oos.writeObject(dog);
oos.close();
System.out.println("数据以序列化形式保存完毕");
}
}
class Dog implements Serializable {
//提高序列化的兼容性
private static final long SerialVersionUID = 1L;
public Dog(int age, String name) {
this.age = age;
this.name = name;
}
private int age;
public String name;
}
-
注意事项
- 读写顺序要一致
- 要求序列化或反序列化对象,需要实现 Serializable 接口
- 序列化的类中建议添加SerialVersionUID,为了提高版本的兼容性
- 序列化对象时,默认将里面所有属性都进行实例化,但static和transient修饰的成员除外
- 序列化对象时,要求里面属性的类型也需要实现序列化接口
- 序列化具备可继承性,也就是说某类实现了序列化后,则它的所有子类也已经默认的实现了序列化
4.9标准输入输出流
package standard;
import java.util.Scanner;
public class InputAndOutput {
public static void main(String[] args) {
// public final static InputStream in = null;
// 编译类型 InputStream
// 运行类型 BufferedInputStream
// 表示标准输入,键盘
System.out.println(System.in.getClass()); //class java.io.BufferedInputStream
// public final static PrintStream out = null;
// 编译类型 PrintStream
// 运行类型 PrintStream
// 表示标准输出 显示器
System.out.println(System.out.getClass());//class java.io.PrintStream
//从键盘接收
Scanner scanner = new Scanner(System.in);
}
}