JAVA IO
文件
-
什么是文件?
文件是保存数据的地方,比如我们经常使用的word文档,txt文件,excel文件等都是文件。文件既可以保存一张图片,也可以保存视频,声音等
-
文件流
文件在程序中是以流的形式来操作的,
流:数据在数据源和程序之间经历的路径
输入流:数据从源到程序的路径
输出流:数据从程序到数据源的路径
常用的文件操作
-
创建文件对象相关构造器和方法
相关方法
//new File(String pathname) //根据路径构建一个File对象 //new File(File parent,String child) //根据父目录文件+子路径构建 //new File(String parent,String child) //根据父目录+子路径构建 //creatNewFile 创建新文件 public class FileCreate { public static void main(String[] args) { FileCreate fileCreate = new FileCreate(); fileCreate.create01(); fileCreate.create02(); fileCreate.creat03(); } //方式1 public void create01(){ String filePath = "D:\\new1.txt"; File file = new File(filePath); try { file.createNewFile(); System.out.println("new1创建成功"); } catch (IOException e) { e.printStackTrace(); } } //方式2 public void create02(){ File parentFile = new File("D:\\"); String fileName = "new2.txt"; File file = new File(parentFile, fileName); try { file.createNewFile(); System.out.println("new2创建成功"); } catch (IOException e) { e.printStackTrace(); } } //方式3 public void creat03(){ String parentPath = "D:\\"; String fileName = "new3.txt"; File file = new File(parentPath, fileName); try { file.createNewFile(); System.out.println("new3创建成功"); } catch (IOException e) { e.printStackTrace(); } } }
-
目录的操作和文件删除
mkdir创建一级目录、mkdirs创建多级目录、delete删除空目录或文件
public class Directory { public static void main(String[] args) { m1(); m2(); } //判断文件是否存在,如果存在就删除 public static void m1(){ String filePath = "D:\\new1.txt"; File file = new File(filePath); if(file.exists()){ if(file.delete()) System.out.println("删除成功"); else System.out.println("删除失败"); }else System.out.println("文件不存在"); } //判断目录是否存在,如果存在就删除,没有就创建 //Java编程中,目录也被当作一种文件 public static void m2(){ String filePath = "D:\\demo\\a\\b"; File file = new File(filePath); if(file.exists()){ if(file.delete()) System.out.println("删除成功"); else System.out.println("删除失败"); }else{ System.out.println("目录不存在"); if ( file.mkdirs()) System.out.println("目录创建成功"); else System.out.println("目录创建失败"); }} }
IO流
-
IO原理
- I/O是Input/Output的缩写,I/O技术是非常实用的技术,可以用来处理数据传输。如读写文件,网络通讯等。
- Java中,对于数据的输入输出操作以“流(stream)”的方式进行
-
IO流的分类
-
按操作数据单位不同分为:字节流(8 bit),字符流(按字符)
-
按数据流的流向不同分为:输入流,输出流
-
按流的角色不同分为:节点流,处理流/包装流
抽象基类 字节流 字符流 输入流 InputStream Reader 输出流 OutputStream Writer java IO流共涉及40多个类,都是从以上4个抽象基类派生的
由这四个基类派生出来的子类名称都是以其父类名作为子类名后缀
-
FileInputStream用法示例
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; public class FileInputStream_ { public static void main(String[] args) { readFile01(); readFile02(); } /** * 用read()方法一次读取一个字节 */ public static void readFile01(){ String filePath = "D:\\new2.txt"; int readData = 0; FileInputStream fileInputStream = null; try { //创建FileInputStream对象用于读取字符 fileInputStream = new FileInputStream(filePath); while((readData = fileInputStream.read()) != -1){ System.out.print((char)readData); } } catch (IOException e) { e.printStackTrace(); } try { fileInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } /** * 用read(byte[] b)方法一次读取多个字节 */ public static void readFile02(){ String filePath = "D:\\new2.txt"; byte[] bytes = new byte[8]; //eight bytes read once FileInputStream fileInputStream = null; int readLen = 0; //创建FileInputStream对象 try { fileInputStream = new FileInputStream(filePath); while ((readLen = fileInputStream.read(bytes)) != -1){ System.out.print(new String(bytes,0,readLen)); } } catch (IOException e) { e.printStackTrace(); } } }
-
FileOutputStream用法示例
import java.io.FileOutputStream; import java.io.IOException; public class FileOutputStream_ { public static void main(String[] args) { writeFile(); } /** * 演示使用FileOutputStream 将数据写到文件里 * 如果文件不存在,就创建文件 */ public static void writeFile(){ String filePath = "D:\\new3.txt"; FileOutputStream fileOutputStream1,fileOutputStream2 = null; try { //1.new FileOutputStream(filePath)创建对象 写入当前内容,会覆盖原来内容 //2.new FileOutputStream(filePath,true)创建对象,写入当前内容会追加到原先内容的后面 fileOutputStream1 = new FileOutputStream(filePath); fileOutputStream2 = new FileOutputStream(filePath,true); //写入一个字节 fileOutputStream1.write('A'); //写入字符串 String str = "hello,world"; fileOutputStream1.write(str.getBytes()); fileOutputStream2.write(str.getBytes()); } catch (IOException e) { e.printStackTrace(); } } }
-
节点流和处理流
- 节点流可以从一个特定的数据源读写数据,如FileReader、FileWriter
- 处理流(包装流)是”连接“在已存在的流之上,为程序提供更强大的读写功能,也更加灵活,如BufferedReader、BufferedWriter
- 节点流是底层流/低级流,直接跟数据源相连接
- 处理流(包装流)包装节点流,既可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入输出
- 处理流对节点流进行包装,使用了修饰器设计模式,不会直接与数据源相连
- BufferedReader和BufferedWriter
演示BufferedReader
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.Reader;
public abstract class Reader_ {//抽象类
public static void main(String[] args) throws Exception {
String filePath = "d:\\new.txt";
BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
//读取
String len;
//按行读取,返回null时文件读取完毕
while ((len = bufferedReader.readLine()) != null) {
System.out.println(len);
}
//关闭流,只需要关闭bufferedReader
bufferedReader.close();
}
}
演示BufferedInputStream和BufferedOutputStream
import java.io.*;
public class BufferedOutputStream_ {
public static void main(String[] args) {
copy();
}
public static void copy(){
//设置源路径和目标路径
String srcPath = "D:\\new.txt";
String destPath = "D:\\new1.txt";
BufferedOutputStream bufferedOutputStream = null;
BufferedInputStream bufferedInputStream = null;
try {
//创建流
bufferedInputStream = new BufferedInputStream(new FileInputStream(srcPath));
bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(destPath));
int readData;
//读取和写入
while((readData = bufferedInputStream.read()) != -1){
bufferedOutputStream.write(readData);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(bufferedInputStream != null) bufferedInputStream.close();
if(bufferedOutputStream != null) bufferedOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
-
对象流-ObjectInputStream和ObjectOutputStream
-
序列化和反序列化
-
序列化就是在保存数据时,保存数据的值和数据类型
-
反序列化就是在恢复数据时,恢复数据类型和数据的值
-
需要让某个类是可序列化的,该类必须实现以下两个接口之一
- Serializable (标记接口,没有方法,推荐)
- Externalizable
ObjectOutputStream用法示例
import java.io.FileOutputStream; import java.io.ObjectOutputStream; import java.io.Serializable; public class ObjectOutPutStream_ { public static void main(String[] args) throws Exception{ //设置序列化后保存文件的路径 String filePath = "D:\\data.dat"; ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath)); //序列化数据到目标文件 oos.writeDouble(1.1); oos.writeInt(26); oos.writeUTF("字符串"); oos.writeObject(new Dog("小黄",3)); //保存一个自定义类的对象 oos.close(); } } //自定义Dog类 class Dog implements Serializable{ String name; int age; public Dog(String name, int age) { this.name = name; this.age = age; } }
-
-
ObjectInputStream用法示例
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.Serializable;
import com.liuxu.io.BufferedOutputStream_.* ; //引入Dog类
public class ObjectInputStream_ {
public static void main(String[] args) throws Exception{
//读取 反序列化
String filePath = "D:\\data.dat";
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
//读取的顺序要和保存的数据一致,不然会出现异常
System.out.println(ois.readDouble());
System.out.println(ois.readInt());
System.out.println(ois.readUTF());
//首先要保证Dog类引入
//如果希望调用Dog对象的方法,需要向下转型
//需要将Dog类的定义放到可以引用的位置
Object dog = ois.readObject();
Dog dog1 = (Dog)dog;
System.out.println(((Dog) dog).age);
System.out.println(dog);
ois.close();
}
}
注意事项
- 序列化和反序列化时读写顺序要一致
- 需要被序列化和反序列化的对象需要实现Serializable接口
- 序列化的类中建议添加SerialVersionUID,来提高版本兼容性
- 序列化对象时默认会序列化所有属性,除了static和transient修饰的成员
- 一个类被序列化,则该类的子类也可以被序列化,序列化具备可继承性
-
转换流InputStreamReader 和 OutStreamWriter
Java默认为UTF-8编码,当文件的编码方式不是UTF-8时,读取时可能会出现乱码,这时就需要转换流来指定编码
InputStreamReader示例
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
public class InputStreamReader_ {
public static void main(String[] args) throws Exception{
String filePath = "D:\\new.txt";
//FileInputStream 转成 InputStreamReader,指定编码GBK
InputStreamReader gbk = new InputStreamReader(new FileInputStream(filePath), "gbk");
BufferedReader reader = new BufferedReader(gbk);
//读取并输出
String s = reader.readLine();
System.out.println(s);
reader.close();
}
}
OutputStreamWriter示例
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.FilterOutputStream;
import java.io.OutputStreamWriter;
public class OutPutStreamWriter_ {
public static void main(String[] args) throws Exception{
String filePath = "D:\\new.txt";
OutputStreamWriter utf8 = new OutputStreamWriter(new FileOutputStream(filePath), "utf-8");
utf8.write("以utf8编码写入");
utf8.close();
}
}
OutputStreamWriter示例
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.FilterOutputStream;
import java.io.OutputStreamWriter;
public class OutPutStreamWriter_ {
public static void main(String[] args) throws Exception{
String filePath = "D:\\new.txt";
OutputStreamWriter utf8 = new OutputStreamWriter(new FileOutputStream(filePath), "utf-8");
utf8.write("以utf8编码写入");
utf8.close();
}
}