java IO

知识点:
字节操作流:OutputStream、InputStream
字符操作流:Reader、Writer
对象序列化:Serializable

File 类:

在整个 IO 包中,最重要的类就是一个 File 类,而且也只有 File 类是唯一与文件本身有关的操作类,与文件本身有关
指的是,文件的创建、删除、重命名、得到路径、创建时间等。

相关方法:
方法或常量名称 类型 描述
1 public static final String separator 常量 表示路径分隔符“\”
2 public static final String pathSeparator 常量 表示路径分隔,表示“;”
3 public File(String pathname) 构造 构造 File 类实例,要传入路径
4 public boolean createNewFile() throws IOException 普通 创建新文件
5 public boolean delete() 普通 删除文件
6 public String getParent() 普通 得到文件的上一级路径
7 public boolean isDirectory() 普通 判断给定的路径是否是文件夹
8 public boolean isFile() 普通 判断给定的路径是否是文件
9 public String[] list() 普通 列出文件夹中的文件
10 public File[] listFiles() 普通 列出文件夹中的所有文件
11 public boolean mkdir() 普通 创建新的文件夹
12 public boolean renameTo(File dest) 普通 为文件重命名
13 public long length() 普通 返回文件大小

File 类的相关操作 例子

1.创建文件 方法:使用 createNewFile()方法完成。

File file = new File("d:\\test.txt");
try {
file.createNewFile(); // 创建文件
} catch (IOException e) {
e.printStackTrace();
}

注:存在路径问题

 windows 下。分隔符是“\”
 linux 下。分隔符是“/”

解决:

File file = new File("d:" + File.separator + "test.txt");

2.删除文件   方法:使用 delete()方法进行文件的删除操作。

File file = new File("d:" + File.separator + "test.txt");
file.delete();// 删除文件

注:

       以上确实可以删除文件,但是此时文件的执行速度较慢,会造成延迟,这一点在开发的时候一定要特别注意,往往
会因为文件有延迟而可能造成开发中出现的问题。
       但是,以上的操作也存在些问题。以上是不管文件是否存在,就直接删除了,至少在删除之前要判断一下文件是否
存在之后再删除,所以使用 exists()方法判断文件是否存在。

File file = new File("d:" + File.separator + "test.txt");
if (file.exists()) { // 文件是否存在
file.delete();// 删除文件

3.判断类型:判断给定的路径是文件还是文件夹。

File file1 = new File("d:" + File.separator + "test.txt"); // 文件路径
File file2 = new File("d:"); // 文件夹路径
System.out.println(file1.isFile());
System.out.println(file2.isDirectory());
System.out.println("文件大小:" + file1.length());
System.out.println("文件路径:" + file1.getPath());
System.out.println("文件路径:" + file1);

4. 列出目录的内容:

如果现在给定了一个文件夹,要求可以将这个文件夹中的内容全部列出,此时,可以使用以下的两种方法:

 第一种方法:public String[] list()
 第二种方法:public File[] listFiles()

File file = new File("d:" + File.separator); // 文件夹路径
String str[] = file.list(); // 列出目录内容
for (int x = 0; x < str.length; x++) {
System.out.println(str[x]);
}

注:此方法列出的只是各个目录或文件的名称。

使用 listFiles()方法

File file = new File("d:" + File.separator); // 文件夹路径
File files[] = file.listFiles(); // 列出
for (int x = 0; x < files.length; x++) {
System.out.println(files[x]);

注:第二种方法列出的是全部的文件的完整路径,这样肯定更加适合操作,所以使用第二种方法比较合理。

输入和输出流

 字节流:主要是操作字节数据(byte),分为 OutputStream,字节输出流、InputStream,字节输入流
 字符流:主要是操作字符数据(char),分为 Writer,字符输出流,Reader,字符输入流

字节输出流:OutputStream:

法名称 类型 描述
1 public void close() throws IOException 普通 关闭
2 public void flush() throws IOException 普通 刷新操作
3 public void write(byte[] b) throws IOException 普通 将一组字节写入到输出流之中
4 public void write(byte[] b,int off,int len) throws IOException 普通 将指定范围的字节数组进行输出
5 public abstract void write(int b) throws IOException 普通 每次写入一个字节,byte  int


但是,以上的类只是一个抽象类,抽象类必须通过子类完成,现在要向文件中输出,使用 FileOutputStrea

方法名称 类型 描述
1
public FileOutputStream(File file) throws
FileNotFoundException
构造 接收 File 类的实例,表示要操作的文件位置。
2
public FileOutputStream(File file,boolean append)
throws FileNotFoundException
构造 接收 File 类实例,并指定是否可以追加

File file = new File("D:" + File.separator + "test.txt"); // 指定要操作的文件
OutputStream out = null; // 定义字节输出流对象
try {
    out = new FileOutputStream(file); // 实例化操作的父类对象
    } catch (FileNotFoundException e) {
    e.printStackTrace();
 }
    String info = "Hello World";// 要打印的信息
    byte b[] = info.getBytes(); // 将字符串变为字节数组
try {
    out.write(b);// 输出内容
} catch (IOException e) {
e.printStackTrace();
    }
try {
    out.close(); // 关闭

注:追加

out = new FileOutputStream(file, true); // 实例化操作的父类对象,可以追加内容

字节输入流:InputStream:

方法名称 类型 描述
1 public void close() throws IOException 普通 关闭
2 public abstract int read() throws IOException 普通 读取每一个字节
3 public int read(byte[] b) throws IOException 普通 向字节数组中读取,同时返回读取的个数
4 public int read(byte[] b,int off,int len) throws IOException 普通 指定读取的范围

InputStream 类本身属于抽象类,肯定需要子类支持,子类从文件中读取肯定是 FileInputStream。

方法名称 类型 描述
1 public FileInputStream(File file) throws FileNotFoundException 构造 通过 File 类实例,创建文件输入流

读取文件:

InputStream input = null; // 字节输入流
try {
    input = new FileInputStream(file);
} catch (FileNotFoundException e) {
    e.printStackTrace();
}
    byte[] b = new byte[1024];// 开辟byte数组空间,读取内容
    int len = 0;
try {
len = input.read(b); // 读取
} catch (IOException e) {
e.printStackTrace();
    }
try {
    input.close();
} catch (IOException e) {
    e.printStackTrace();
}
    System.out.println(new String(b, 0, len));

可以通过 read()方法采用循环读的方式:

byte b[] = new byte[1024];// 开辟byte数组空间,读取内容
int len = 0;
try {
    int temp = 0; // 接收每次读取的内容
    while ((temp = input.read()) != -1) {// 如果不为-1表示没有读到底
    b[len] = (byte) temp; // int --> byte
    len++;

注:以上方法开辟的空间可能很大,没必要开辟那么的空间

File file = new File("D:" + File.separator + "test.txt");// 要读取的文件路径
InputStream input = null; // 字节输入流
try {
    input = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
    byte b[] = new byte[(int) file.length()];// 根据文件大小,开辟byte数组空间
try {
    input.read(b); // 读取
} catch (IOException e) {
    e.printStackTrace();
}
try {
    input.close();
} catch (IOException e) {
    e.printStackTrace();
}
    System.out.println(new String(b));

字符输出流:Writer

方法名称 类型 描述
1 public void write(String str) throws IOException 普通 直接将字符串写入输出
2 public void write(char[] cbuf) throws IOException 普通 输出字符数组
3 public abstract void close() throws IOException 普通 关闭
4 public abstract void flush() throws IOException 普通 刷新

注:与 OutputStream 一样,使用 FileWriter 类完成操作,此类的构造方法如下:

方法名称 类型 描述
1 public FileWriter(File file) throws IOException 构造 根据 File 类构造 FileWriter 实例
2 public FileWriter(File file,boolean append) throws IOException 构造 根据 File 类构造 FileWriter 实例,可以追加内容

使用 Writer 完成文件内容的输出

File file = new File("D:" + File.separator + "test.txt"); // 指定要操作的文件
Writer out = null; // 定义字节输出流对象
out = new FileWriter(file); // 实例化操作的父类对象
String info = "Hello World!!!";// 要打印的信息
out.write(info);// 输出内容
out.close(); // 关闭

字符输入流:Reader

方法名称 类型 描述
1 public int read() throws IOException 普通 读取一个内容
2 public int read(char[] cbuf) throws IOException 普通 读取一组内容,返回读入的大小
3 public abstract void close() throws IOException 普通 关闭

此类,依然需要使用 FileReader 类进行实例化操作,FileReader 类中的构造方法定义如下:

方法名称 类型 描述
1 public FileReader(File file) throws FileNotFoundException 构造 接收 File 类的实例

File file = new File("D:" + File.separator + "test.txt");// 要读取的文件路径
Reader input = null; // 字节输入流
input = new FileReader(file);
char b[] = new char[1024];// 开辟char数组空间,读取内容
int len = input.read(b); // 读取
input.close();
System.out.println(new String(b, 0, len));

字节流和字符流的区别

区别:字节流没有使用到缓冲区,而是直接操作输出的,而字符流使用到了缓冲区,是通过缓冲区操作输出的。

File file = new File("D:" + File.separator + "test.txt"); // 指定要操作的文件
OutputStream out = null; // 定义字节输出流对象
out = new FileOutputStream(file); // 实例化操作的父类对象
String info = "Hello World!!!";// 要打印的信息
byte b[] = info.getBytes(); // 将字符串变为字节数组
out.write(b);// 输出内容
// 本程序没有进行关闭

此时,虽然没有关闭输出流,但是内容依然可以输出,证明,字节操作流是直接与输出本身有关的,那么如果现在
同样的操作使用字符流呢?

File file = new File("D:" + File.separator + "test.txt"); // 指定要操作的文件
Writer out = null; // 定义字节输出流对象
out = new FileWriter(file); // 实例化操作的父类对象
String info = "Hello World!!!";// 要打印的信息
out.write(info);// 输出内容
// 此处没有关闭

此时已经完成了程序,但是程序执行之后发现并没有任何的内容,因为所有的内容都放在缓冲区之中,只有在关闭
的时候才会清空缓冲区,进行输出,如果此时希望可以把内容输出的话,则必须手工调用 flush()方法完成。

File file = new File("D:" + File.separator + "test.txt"); // 指定要操作的文件
Writer out = null; // 定义字节输出流对象
out = new FileWriter(file); // 实例化操作的父类对象
String info = "Hello World!!!";// 要打印的信息
out.write(info);// 输出内容
out.flush();// 强制清空缓冲区
// 此处没有关闭

字节- 字符转换流

 OutputStreamWriter:可以将输出的字符流变为字节流的输出形式
 InputStreamReader:将输入的字节流变为字符流输入形式

打印流:PrintStream

打印流的主要功能是用于输出,在整个 IO 包中打印流分为两种类型:

字节打印流:PrintStream
字符打印流:PrintWriter

注:OutputStream 本身已经提供了很好的输出功能,但是使用 OutputStream 输出其他数据,例如:boolean、char、
float 等就比较麻烦了,所以在 Java 中为了方便输出,提供了专门的打印流。

方法名称 类型 描述
1 public PrintStream(OutputStream out) 构造 接收 OutputStream 类的实例。
2 public PrintStream(File file) throws FileNotFoundException 构造 接收 File 类实例,向文件中输出
3 public PrintStream format(String format, Object... args) 普通 表示格式化输出
4 public void print(数据类型 f) 普通 打印输出,不换行
5 public PrintStream printf(String format,Object... args) 普通 格式化输出
6 public void println(数据类型 f) 普通 打印输出,换行

注:从以上类的定义中可以发现,此类可以完成输出的功能,但是这个类的输出功能比直接使用 OutputStream 输出强,
因为可以输出任意的数据类型。也就是说此类实际上是将 OutputStream 加强了。
在此类的构造方法中,需要接收 OutputStream 类的实例,那么实际上此时就意味着,哪个子类为 PrintStream 实例化,
PrintStream 就具备了向指定位置的输出能力。

File file = new File("D:" + File.separator + "temp.txt");
OutputStream output = new FileOutputStream(file);
PrintStream out = new PrintStream(output);
out.print("hello");
out.print(" world ");
out.println("!!!");
out.print("1 X 1 = " + (1 * 1));
out.println("\n输出完毕");
out.close();

格式化的操作,则必须指定格式化的操作模板

模板标记 描述
1 %s 表示字符串
2 %d 表示整数
3 %n.mf 表示小数,一共的数字长度是 n,其中小数是 m 位
4 %c 表示字符

String name = "张三";
float salary = 800.897f;
int age = 10;
PrintStream out = new PrintStream(new FileOutputStream(new File("d:"
+ File.separator + "temp.txt")));
out.printf("姓名:%s,年龄:%d,工资:%7.2f。", name, age, salary);

对象序列化:

对象序列化就是指将一个对象转化成二进制的 byte 流。

将对象保存在文件上的操作称为对象的序列化操作
将对象从文件之中恢复称为反序列化的操作

Serializable 接口

注:此接口中没有任何的方法定义。与 Cloneable 接口一样,此接口也属于标识接口,表示可以被序列化。
虽然此接口中没有定义任何的方法,但是在操作的时候也不要让所有的类都实现此接口。只能在需要的地方进行实
现,因为现在接口中没有方法,并不表示以后的接口中同样没有方法。

public class Person implements Serializable {
    /**
    * 此常量表示的是一个序列化的版本编号,为的是可以在不同的JDK 版本间进行移植
    */
    private static final long serialVersionUID = 1L;
    private String name;
    private int age;
    public Person(String name, int age) {
    super();
    this.name = name;
    this.age = age;
}

进行序列化操作:ObjectOutputStream

ObjectOutputStream 专门用于对象的输出操作

方法名称 类型 描述
1 public ObjectOutputStream(OutputStream out) throws IOException 构造 接收 OutputStream 实例,进行实例化操作
2 public final void writeObject(Object obj) throws IOException 普通 输出一个对象
3 public void close() throws IOException 普通 关闭

注:发现 ObjectOutputStream 类的使用与 PrintStream 非常类似,根据实例化其子类的不同,输出的位置也不同。
在使用 writeObject()方法的时候,发现使用 Object 进行参数的接收,那么证明所有的对象都可以使用此方法输出,都
会自动发生向上转型的关系。

将 Person 的对象保存在文件之中

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
new File("D:" + File.separator + "person.ser")));
Person per = new Person("张三", 30);
oos.writeObject(per);// 输出
oos.close();// 关闭

注:此时,对象已经被成功的序列化到了文件之中。
但是必须提醒的是,对象不一定只能序列化到文件之中,任何地方都有可能序列化,根据实例化 ObjectOutputStream
类的对象不同,输出的位置也不同。

进行反序列化操作:ObjectInputStream

方法名称 类型 描述
1
public ObjectInputStream(InputStream in) throws

IOException 构造 根据输入流的不同,实例哈 ObjectInputStream 类的
对象
2
public final Object readObject() throws
IOException,ClassNotFoundException
普通 读取对象

写入对象的时候所有的对象都向 Object 进行转型操作,所以读取的时候也使用 Object 进行读取的操作

进行对象的反序列化操作

ObjectInputStream oos = new ObjectInputStream(new FileInputStream(
new File("D:" + File.separator + "person.ser")));
Person p = (Person)oos.readObject() ;
System.out.println(p);

序列化一组对象

在序列化操作中,每次只能序列化一个对象,如果现在要想序列化一组对象该如何操作呢?
此时,可以采用 对象数组的形式,因为对象数组可以向 Object 进行转型操作。

Person per[] = { new Person("张三", 30), new Person("李四", 35),
new Person("王五", 50) };
ser(per); // 序列化一组对象
Person p[] = (Person[]) dser(); // 反序列化
for (int x = 0; x < p.length; x++) {
    System.out.println(p[x]) ;
}
}

public static void ser(Object obj) throws Exception { // 所有异常抛出
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
    new File("D:" + File.separator + "person.ser")));
    oos.writeObject(obj);// 输出
    oos.close();// 关闭
}
public static Object dser() throws Exception { // 所有异常抛出
    ObjectInputStream oos = new ObjectInputStream(new FileInputStream(
    new File("D:" + File.separator + "person.ser")));
    Object obj = oos.readObject();
    return obj;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值