java学习day16~17--IO流

Input 输入     Output输出

一.文件(File可以用来代表不存在的目录或文件,可以创建)

     java.io.File   它是对应着实际的文件或者目录

     New File(String 文件路径)

     可以用/或者\\作为文件分隔符,不过为了通用可以使用File.separator获取不同操作系统的分隔符

文件的常用方法

    isFile();   判断是否是一个文件

    isDirectory();  判断文件是否是一个目录

    mkdir();   创建一个不存在的目录

    mkdirs();  创建多级目录

    exists();  用来判断一个文件是否存在

    listFiles();   得到一个目录下的所有子目录和文件

    delete();  理解删除文件

    deleteOnExit();   程序运行结束后删除文件

    renameTo();   重命名和移动

    getAbsoluteFile();   获得文件的绝对路径

二.IO流

Input  输入流: 从文件读取内容,文件对我就是输入流

Output   输出流:向文件中写入内容,文件对我就是输出流

InputStream  抽象类 –> FileInputStream  问价输入流

OutputStream  抽象类 ->FileOutputStream  文件输出流

字节流
    InputStream
        (*) FileInputStream  从文件读取字节
        (*) BufferedInputStream 加入缓冲功能,提高文件的读取效率
        ByteArrayInputStream 从字节数组变成输入流
    OutputStream
        (*) FileOutputStream 向文件写入字节
        (*) BufferedOutputStream 加入缓冲功能, 提高文件的写入效率
        ByteArrayOutputStream 把流的内容写入字节数组
        PrintStream 实际上就是 System.out

字符流
    Reader 
        (*) InputStreamReader 转换字节流为字符流
        (*) BufferedReader 功能增强,以行为单位读取数据 (装饰器模式)
        FileReader  是InputStreamReader子类,将字符编码固定为操作系统的默认编码,不能手工改动
    Writer
        (*) OutputStreamWriter 转换字节流为字符流
        (*) PrintWriter 以行为单位写入数据
            write 当成字符写入
            print  print就是将参数转为字符串后写入
        FileWriter 是OutputStreamWriter的子类,也是固定了字符编码

文件的读取

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;

//测试文件输入流,读取外部文件内容
public class FileInputStreamTest1 {
    public static void main(String[] args) throws IOException {
        //打开文件
        File f = new File("F:\\学习练习\\javasePrac\\西部开源\\IO流\\src\\day16\\abc.txt");
        //创建文件输入流对象
        FileInputStream fis = new FileInputStream(f);
//        方式一:一个字节一个字节的读取
//        while(true) {
//            int r = fis.read();
//            if(-1 == r) {   //当文件读到尾时,跳出循环
//                break;
//            }
//
//            System.out.print((char) r + " ");
//        }

//      方式二:将读入的内容转为数组,然后输出
        while(true) {
            byte[] by = new byte[100];
            int r = fis.read(by);
            if(-1 == r) {
                break;
            }
            System.out.println(Arrays.toString(by));
        }
    }
}

文件的写入

1.创建输出流

FileOutputStream  fos  = new  FileOutputStream(“文件名”);

2.向输出流中写入数据

fos.write(97);;

3.关闭输出流

fos.close();

文件的复制

import java.io.*;

public class Test
{ 
	public static void main(String[] args) throws Exception {
		FileInputStream fis = new FileInputStream("1.txt");
        FileOutputStream fos = new FileOutputStream("3.txt");

        while(true) {
            byte[] buf = new byte[1024];
            int len = fis.read(buf);
            if(len == -1) {
                break;
            }
            fos.write(buf, 0, len); // 实际读到len个字节,就写入len个字节
        }

        fis.close();
        fos.close();
	}
}

2.用Files的copy方法,参数1是被拷贝的文件,参数2 是拷贝后的文件

三.字符流

以字符为单位处理流的内容

Reader 字符输出流, InputStreamReader

Writer 字符输出流  OutputStreamWriter

  1. 先创建字节流文件
  2. 将字节流文件转为字符流
  3. 读取(注意转成char类型)
  4. 关闭,只需要关闭外层的流即可,内部会帮我们关掉内层的
import java.io.*;
import java.util.*;

public class Test
{
	public static void main(String[] args) throws IOException {
		// 1. 将字节流转换为字符流
		FileInputStream fis = new FileInputStream("1.txt");
		// 注意:实际文件编码要与读取时的文件编码一致
		InputStreamReader reader = new InputStreamReader(fis, "utf-8");

		// 2. 读取
		/*while(true) {
			int c = reader.read();
			if(c == - 1) {
				break;
			}
			System.out.println((char)c);
		}*/
		while(true) {
			char[] buf = new char[1024];
			int len = reader.read(buf);
			if(len == -1) {
				break;
			}
			System.out.println(Arrays.toString(buf));
		}

		// 3. 关闭, 只需要关闭外层的流, 内部会帮我们关掉内层的流
		reader.close();
	}
}

BufferedReader是在InputStreamReader的基础上以行为单位处理字符流,两者之间是平级关系,父类都是Reader(装饰者模式)

import java.io.*;
import java.util.*;

public class Test
{
	public static void main(String[] args) throws IOException {
		FileInputStream fis = new FileInputStream("1.txt");
		InputStreamReader reader = new InputStreamReader(fis, "utf-8");
		BufferedReader reader2 = new BufferedReader(reader);

		/*System.out.println(reader2.readLine()); // 以行为单位读取数据
		System.out.println(reader2.readLine()); // 以行为单位读取数据
		System.out.println(reader2.readLine()); // 以行为单位读取数据*/

		while(true) {
			String line = reader2.readLine();
			if(line == null) {
				break;
			}
			System.out.println(line);
		}

		reader2.close();
	}
}

装饰者模式:

       装饰者与被装饰者需要有一个共同的父类

       装饰者和被装饰者之间体现的是组合的关系,而不是继承的关系,目的是为了更加灵活

       装饰者会对被装饰者做功能上的增强

四.java中的序列化和反序列化

序列化

将对象中的信息永久保存

1.将对象信息存入数据库

2.java中提供的序列化方式来永久保存数据

import java.io.*;

//如果没有实现Serializable接口,会出现NotSerializableException异常
class Student implements Serializable{

    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

public class Test 
{
	public static void main(String[] args) throws Exception {
		Student student = new Student();
		student.setId(1);
		student.setName("张三");

		// 序列化就是将对象变为输出字节流
		ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("d:\\student.obj"));
		os.writeObject(student);
		os.close();
	}
}

注意:

要求对象中的所有属性也都是可以序列化

如果某个属性不想序列化,可以在属性上加"transient"关键字

反序列化

把字节内容读取进来,还原为java对象
ObjectInputStream用来读取字节内容,还原(反序列化)为java对象

import java.io.*;

class Student implements Serializable{

    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

public class Test 
{
	public static void main(String[] args) throws Exception {
		ObjectInputStream is = new ObjectInputStream(new FileInputStream("d:\\student.obj"));
        Student s = (Student)is.readObject();
        System.out.println(s.getId());
        System.out.println(s.getName());
        System.out.println(s.getAddress());
	}
}

除了可以写入和读取对象以外,还可以写入和读取基本类型(int,long,boolean...) ,读取和写入的顺序要保持一致
如果不一致,出现EOFException
如果没有更多内容,也会出现EOFException
建议在写入时最后一个对象使用null,这样读取时就可以根据null来判断是否读取完毕

猜你喜欢

转载自blog.csdn.net/szy2333/article/details/81531531