文件与IO流(未完成)

一、文件

只能对文件进行创建 删除等操作,不能读和写文件

(一)文件的常用构造器

File(String pathname):根据文件路径构造File对象 

File(String parent, String child):根据父路径和子路径构造File对象

File(File parent, String child):根据父File对象和子路径构造File对象

D盘 afile 文件夹下的 file1.txt

   (二)文件属性

public class FileDemo03 {
    public static void main(String[] args) {
        File file = new File("D:/afile/file1.txt");
        System.out.println("文件名:" + file.getName());
        System.out.println("绝对路径:" + file.getAbsolutePath());
        System.out.println("父目录:"+file.getParent());
        System.out.println("路径"+file.getPath());
        System.out.println("是否存在:" + file.isFile());
        System.out.println("是否是一个文件夹"+file.isDirectory());
        System.out.println("该文件是一个隐藏文件"+file.isHidden());
        System.out.println("是一个可读文件吗?:"+file.canRead());
        System.out.println("是一个可写文件吗?:"+file.canWrite());
        System.out.println("是一个可执行文件吗?:"+file.canExecute());//可执行一定是可读文件,可写一定可读
        System.out.println("最后一次修改时间:"+file.lastModified());
        System.out.println("文件的大小"+file.length());

    }
}

结果 

  (三)文件的查询

相关方法

String[] list() : 返回指定文件夹里的子文件和子目录的名字

File[] listFiles() : 返回指定文件夹里的子文件和子目录的File类型

1.  用一个字符数组接收 得到的是每一个文件名

2.  用文件数组接收 得到的是每一个文件或者文件夹的根路径

用文件数组接收后 可以通过getName()方法 获得每一个文件或者文件夹的名字

3.  用过滤器 过滤出来想要的

过滤出以 “  .txt  " 结尾的

  (四) 创建文件夹和文件

1. mkdir  创建单层文件夹

在D盘里创建aafile文件夹

public class Demo01 {
    public static void main(String[] args) {
        File file = new File("D:/aafile");
        if (!file.exists()) {
            file.mkdir();
            System.out.println("文件夹创建成功!");
        }

    }
}

2.  mkdirs : 创建多层文件夹 

在D盘里创建bafile文件夹,bafile文件夹里面包含jjj文件夹

public class Demo01 {
    public static void main(String[] args) {
        File file = new File("D:/bafile/jjj");
        if (!file.exists()) {
            file.mkdirs();
            System.out.println("文件夹创建成功!");
        }

    }
}

3. 创建文件

在D盘下的aafile文件夹下创建 file,txt 文件

public class Demo02 {
    public static void main(String[] args) throws IOException {
        File file = new File("D:/aafile/file.txt");
        if(!file.exists()){
            file.createNewFile();
        }

    }
}

结果:

     (五) 文件的删除

public class Demo04 {
    public static void main(String[] args) {
        File file = new File("D:\\afile");
        if(file.exists()){
           boolean b = file.delete();
            System.out.println("是否删除成功:"+ b);
        }
    }
}

结果

结果解析

删除文件夹时候  文件的delete方法只能删除空文件夹 

当文件夹里没有文件时候会删除成功

如果想要删除非空的文件夹 可以使用递归删除

获取到文件夹的子文件夹然后进行删除

public class Demo04 {
    public static void main(String[] args) {
        File file = new File("D:/afile/dir11");
        deleteFile(file);
    }
    public static void deleteFile(File file){
        if(file.exists()){
            boolean flag = file.delete();
            if(!flag){
                File[] fileList = file.listFiles();
                for(File files :fileList){
                    //删除每一个文件夹的子文件
                    deleteFile(files);
                }
                deleteFile(file);
            }
            //删除每个文件夹
        }else{
            throw new RuntimeException("文件不存在");
        }
    }
}

删除后

二、IO流

(一)简介

在编程时候 除了自定义一些数据之外,我们可能还想要用外部的信息,例如

如果想要读取磁盘上的文件或者往磁盘里的文件写东西时,就要用到IO流

外部信息 可以是文件 磁盘 网络 显示器等

IO流 : Input  Output Stream

Input : 把外部信息读入到程序中 指数据流入程序

Output:  向外部信息中写入数据,指数据从程序流出

注意: 

IO流一旦被创建就会打开,所以当我们不在使用时要将流关闭,通过调用close()方法显示的关闭

流,如果流对象没有被引用那么垃圾回收机制也会隐式的将它关闭

(二)分类

按照数据的流向

输入流

输出流

按照处理数据的单位分

字节流

字符流

按照流的功能

节点流(低级流):

处理流(高级流):也就是有缓冲区

 字节流

1. 文件流

FileOutputStream 文件输出流

是OutputStream的一个子类型

是一个低级流(节点流),用来连接文件和程序。将数据从程序写入到文件中

不会帮我们创建 不存在的文件夹,但是会帮我们创建不存在的文件

原来不存在 file6.txt 文件 

public class FileOutputFile{
    public static void main(String[] args) {
        FileOutputStream fos = null;
        File file = new File("D:/afile/file6.txt");
        try{
            fos = new FileOutputStream(file,true);
            String str = "  hieheihei!";
            byte[] bytes = str.getBytes();
            fos.write(bytes);
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

1.   FileOutputStream(String pathname):创建文件输出流,将数据写入到指定文件中,会将原来的覆盖掉

public class FileOutputFile {
    public static void main(String[] args) {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream("D:/afile/file1.txt");
            String str = "Hello hahahaha!";
            byte[] bytes = str.getBytes();
            fos.write(bytes);
        } catch (IOException e) {
          e.printStackTrace();
        }finally {
            try {
                fos.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

2.  FileOutputStream(String pathname,  boolean append): 有追加效果

public  class FileOutputFile {
    public static void main(String[] args) {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream("D:/afile/file1.txt",true);
            String str = "   heiheihei!";
            byte[] bytes = str.getBytes();
            fos.write(bytes);
        } catch (IOException e) {
          e.printStackTrace();
        }finally {
            try {
                fos.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

3.  FileOutputStream(File file):创建文件输出流,将数据写入到指定文件中,会将文件中原有的覆盖掉

public class FileOutputFile{
    public static void main(String[] args) {
        FileOutputStream fos = null;
        File file = new File("D:/afile/file1.txt");
        try{
            fos = new FileOutputStream(file);
            String str = "hello hi nihao";
            byte[] bytes = str.getBytes();
            fos.write(bytes,0,4);
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

4. FileOutputStream(File file,boolean append) : 有追加效果

public class FileOutputFile{
    public static void main(String[] args) {
        FileOutputStream fos = null;
        File file = new File("D:/afile/file1.txt");
        try{
            fos = new FileOutputStream(file,true);
            String str = " hi nihao";
            byte[] bytes = str.getBytes();
            fos.write(bytes);
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

FileInputStram:文件输入流 读入数据

1. 是InputStram抽象类的子类型

2. 是一个低级流,用于连接文件和程序

3. 常用构造器    FileInputStream(File file):

    FileInputStream(String Pathname)

构造器

new FileInputStream(String pathname)

方法:

read()  读取一个字节

public class FileInputFile1 {
    public static void main(String[] args) {
        FileInputStream fis = null;
        try{
            fis = new FileInputStream("D:/afile/file1.txt");
            //读取一个字节
            int ch = fis.read();
            System.out.println((char)ch);
        }catch(IOException e){
            e.printStackTrace();
        }finally{
            try {
                fis.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

构造器 : 

new FileInputStream(File file)

一次性读取全部

方法   

read(Byte[]  byte, int off.int len)

byte:字节数组  off 字节数组的起始下标 读取的长度

public class FileInputFile1 {
    public static void main(String[] args) {
        FileInputStream fis = null;
        File file = new File("D:/afile/file1.txt");
        try{
            fis = new FileInputStream(file);
            //将读取的内容存入字节数组中,数组满了一次性读出
            byte[] bytes = new byte[10];
            int flag = -1;
            while((flag =fis.read(bytes)) != -1){
                String str = new String(bytes,0,flag);
                System.out.println(str);
            }
        }catch(IOException e){
            e.printStackTrace();
        }finally{
            try {
                fis.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

2. 缓冲流 

  字节缓冲输出流 : BufferOutputStream

1. 内部维护了一个字节数组作为缓冲区(缓存) 默认值是8KB

2. 当我们写数据时,是先写到缓存区中的,并不是写到磁盘上,当缓存满的情况下,再一次性将数据写到磁盘。 从而减少了与磁盘的交互次数,提高了写出效率

 注意:缓冲区满了 会将缓冲区中的数据 一次性写到磁盘中,

              关闭流会将 缓冲区中的数据强制清空,

              也就是即使没有满也会将缓冲区中的数据写入到磁盘中

               如果没有关闭流就不会将没有满的缓冲区中的数据写入到磁盘中

3. 最后一次写缓存后,有可能没有写满,我们可以调用flush方法,将其强制写入磁盘中

4. 构造器 : BufferedOutputStream(OutputStream out)                                           BufferedOutputStream(OutputStream out, int size): size自定义缓冲区的大小

1.

构造器 :BufferedOutputStream(OutputStream out,int size)     

方法:    write(byte[] bytes)

注意,我们可以自定义缓冲区的大小,但是当一次性写时候,如果超出了缓冲区的范围,会不用缓冲区

eg:

public class OutputTest {
    public static void main(String[] args) throws Exception {
        BufferedOutputStream bos = null;
        try {
            File file = new File("D:/afile/a2.txt");
            bos = new BufferedOutputStream(new FileOutputStream(file), 5);
            bos.write("hell".getBytes());
            bos.write(18);
        } finally {
           // bos.close();
        }
    }
}

结果:

解析: 因为size的单位是字节,所以当没有关闭流时,缓冲区没有写满,不会被写入到文件中


public class OutputTest {
    public static void main(String[] args) throws Exception {
        BufferedOutputStream bos = null;
        try {
            File file = new File("D:/afile/a2.txt");
            bos = new BufferedOutputStream(new FileOutputStream(file), 5);
            bos.write("hellohhworld".getBytes());
            bos.write(18);
        } finally {
           // bos.close();
        }
    }
}

结果;

解析:当一次性写入的超出了缓冲区的大小,就不用缓冲区了,所以可以写进去

public class OutputTest {
    public static void main(String[] args) throws Exception {
        BufferedOutputStream bos = null;
        try {
            File file = new File("D:/afile/a2.txt");
            bos = new BufferedOutputStream(new FileOutputStream(file), 5);
            bos.write("hello".getBytes());
            bos.write("hel".getBytes());
            bos.write(18);
        } finally {
           // bos.close();
        }
    }
}

结果: 

解析: hello写入时缓冲区满了写入到文件中,但是hel写入缓冲区没有满,所以在没有哦关闭流的情况下不会写入文件中。

一次性写进去没有超出缓冲区的大小,继续用缓冲区,流没有关闭 缓冲区没有满,不会写入文件中。

2.     构造器 ;BufferedOutputStream(OutputStream out)   

        方法 : write( byte[ ])

public class Buffered {
    public static void main(String[] args) throws Exception{
        BufferedOutputStream bos = null;
        try{
            File file = new File("D:/afile/a2.txt");
            bos = new BufferedOutputStream(new FileOutputStream(file));
            bos.write("Hello World!".getBytes());
        }finally{
            bos.close();
        }
    }
}

3.     构造器 ;BufferedOutputStream(OutputStream out)   

        方法:  write( byte[ ] bytes , int off, int len)  off字节数组的起始位置,len是想要写进文件的长度

public class Buffered {
    public static void main(String[] args) throws Exception{
        BufferedOutputStream bos = null;
        try{
            File file = new File("D:/afile/a2.txt");
            bos = new BufferedOutputStream(new FileOutputStream(file));
            bos.write("Hello World!".getBytes(),0,3);
        }finally{
            bos.close();
        }
    }
}

 字符缓冲输入流:
 1.  是一个高级流,内部维护一个缓冲区 默认是8KB
 2.  读取文件中的数据时,一次性尽可能读取到缓冲区大小的字节
 3.   read方法从缓冲区中获取数据,当缓冲区的数据全部获取完,会再次从磁盘上读取数据存入到缓冲区
  4.  常用构造器
  BufferedInputStream(InputStream in)
 BufferedInputStream(InputStream in, int size)

  5.  方法

      int read( byte[ ] bytes, int off, int len )

      int read( byte[ ] bytes)

size的作用
       性能优化:通过调整缓冲区的大小,可以在一定程度上控制性能和内存使用的平衡。较大的缓冲区可以减少对底层输出流的写入次数,从而提高性能,但会增加内存的使用。相反,较小的缓冲区可以减少内存的使用,但可能会降低性能,因为需要更频繁地写入底层输出流。
       特定场景:在某些特定的应用场景中,你可能需要根据实际情况来调整缓冲区的大小。例如,如果你知道你将要写入的数据量非常小,那么使用一个较小的缓冲区可能是一个好主意,因为它可以减少内存的使用。相反,如果你正在处理大量的数据,并且希望尽可能提高写入性能,那么使用较大的缓冲区可能更合适.
         Bufferedoutputstream 中的 size参数用于指定缓冲区的大小,以便控制性能和内存使用的平衡。通过总的来说,调整这个参数,你可以根据你的应用需求来优化性能。然而,需要注意的是,并不是缓冲区越大就一定越好,因为过大的缓冲区会增加内存的使用,并可能导致内存不足的问题。因此,在设置缓冲区大小时,需要根据实际情况进行权衡

1.  构造器  BufferedInputStream(InputStream in)

     方法  read(byte [ ] ,int off, int len)

public class InputTest {
    public static void main(String[] args) throws Exception{
        BufferedInputStream bis = null;
        try {
            File file = new File("D:/afile/a2.txt");
            bis = new BufferedInputStream(new FileInputStream(file));
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = bis.read(buffer))!= -1) {
                System.out.println(new String(buffer, 0, len));
            }
        } finally {
            bis.close();
        }
    }
}

字符缓冲输出流

    该缓冲输出流内部维护着一个缓冲区,每当我们向该流写数据时,都会先将数据存储缓冲区,当缓冲区已满时,缓冲流会将数据一次性全部写出

   使用该流虽然可以提高写出效率,但是缺乏即时性,此时我们可以使用flush方法,清空缓冲区,强制写出。

构造器

BufferedOutputStream(OutputStream out)

BufferedOutputStream(OutputStream out, int size)

1.  BufferedOutputStream(OutputStream out)

public class OutputTest {
    public static void main(String[] args) throws Exception {
        BufferedOutputStream bos = null;
        try {
            File file = new File("D:/afile/a2.txt");
            bos = new BufferedOutputStream(new FileOutputStream(file));

            bos.write("hello".getBytes());
            bos.write("hel".getBytes());
            bos.write(18);
        } finally {
            //bos.close();
        }
    }
}

解析:缓冲区没有满时候,不关闭流不会写入到文件中

  2.    BufferedOutputStream(OutputStream out, int size)

public class OutputTest {
    public static void main(String[] args) throws Exception {
        BufferedOutputStream bos = null;
        try {
            File file = new File("D:/afile/a2.txt");
            bos = new BufferedOutputStream(new FileOutputStream(file),5);

            bos.write("hello".getBytes());
            bos.write("hel".getBytes());
            bos.write(18);
        } finally {
           // bos.close();
        }
    }
}

解析:不关闭流缓冲区满了才会写入文件

  3.    调用flush方法 即使没有关闭流 缓冲区没有满也会强制写入文件中

public class OutputTest {
    public static void main(String[] args) throws Exception {
        BufferedOutputStream bos = null;
        try {
            File file = new File("D:/afile/a2.txt");
            bos = new BufferedOutputStream(new FileOutputStream(file),5);

            bos.write("hello".getBytes());
            bos.write("hel".getBytes());
            bos.write(18);
            bos.flush();
        } finally {
           // bos.close();
        }
    }
}

3. 数据流

DataOutputStream

      该流是FilterOutputStream的子类,扩展了一些功能,提供了一些可以直接写出基本数据    类型的方法

       构造方法  DataOutputStream(OutputStream os)

public class DataOutputStreamDemo01 {
    public static void main(String[] args) {

        try( DataOutputStream dos = new DataOutputStream(
                new FileOutputStream("D:/afile/a2.txt"))){
            dos.writeInt(10);//4字节
            dos.writeDouble(2.34);//8字节
            dos.writeBoolean(true);//1字节
            dos.writeUTF("你是最棒的");//15字节 注意:每写一次UTF的字符串都会使用两个字节来记录字符串的 长度
            dos.flush();
        }catch(IOException e){
            e.printStackTrace();
        }
    }
}

DataInputStream

     该流提供了一些可以直接读取基本数据类型的方法

     构造方法   DataInputStream(InputStream is)

public class InputTest {
    public static void main(String[] args) {
        File file = new File("D:/afile/a.txt");
        DataInputStream dis = null;
        try {
            dis = new DataInputStream(new FileInputStream(file));
            byte[] bytes = new byte[1024];
            int len =dis.read(bytes);
            String str = new String(bytes,0,len);
            System.out.println(str);

        } catch (Exception e) {
            throw new RuntimeException(e);
        }finally {
            try {
                dis.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

    }
4. 对象流

对象是存在于内存中的,有的时候我们需要将对象保存到硬盘上,又有时我们需要将对象传输到另一台计算机上等等这些的操作。

此时,我们需要将对象转换成一个字节序列,这个过程我们称之为序列化

构造器: ObjectOutputStream(OutputStream os)

方法 :void writeObject(Object obj);

相反,我们将一个字节序列转换成对应的对象,这个过程我们称之为反序列化

构造器: ObjectInputStream(InputStream is)

方法 ; Object readObject();

  小贴士:字节数组就是字节序列的意思
public class Test {
    public static void main(String[] args) throws Exception {
        Teacher teacher = new Teacher("张三", 25, "北京", "好h人");
        ObjectOutputStream oos = null;
        ObjectInputStream ois = null;
        try{
            //序列化
            oos = new ObjectOutputStream(
                    new BufferedOutputStream(
                            new FileOutputStream("teacher.s")));
            oos.writeObject(teacher);
            //反序列化
            oos.flush();
            oos.writeObject(teacher);
            ois = new ObjectInputStream(
                    new BufferedInputStream(
                            new FileInputStream("teacher.s")));
            Object obj =  ois.readObject();
            System.out.println(obj);
            Thread.sleep(1000);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            oos.close();
            ois.close();
        }
    }
}
class Teacher implements Serializable,Comparable<Teacher> {
    private static final int serialVersionUID = 1;
    private String name;
    private int age;
    private String address;
    // transient关键字修饰的字段不会被序列化
    private transient String remark;
    public Teacher() {
    }
    public Teacher(String name, int age, String address, String remark) {
        this.name = name;
        this.age = age;
        this.address = address;
        this.remark = remark;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Teacher teacher = (Teacher) o;
        return age == teacher.age && Objects.equals(name, teacher.name) && Objects.equals(address, teacher.address) && Objects.equals(remark, teacher.remark);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age, address, remark);
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                ", remark='" + remark + '\'' +
                '}';
    }

    @Override
    public int compareTo(Teacher o) {
        return this.age - o.age;
    }
}

 transient 关键字

1. 用于修饰成员变量

2. 当序列化时,某一个属性的信息不需要保存或者传输,也就是不是非常重要的信息, 那么就可以加上transient关键字进行修饰,该属性不会被序列化。

序列号:

  自定义的类型 如果想要将其对象进行存储或者传输那么这个类必须要实现一个接口
    这个接口就是Serializable
  该接口里面什么都没有,就是一个规范

  serailVersionUID:序列化的版本号
  1.  在序列化时,系统会默认给该类提供一个版本号,当反序列化时就会检查该类的版本号与对象的版本号是否一致,
      如果一致就可以反序列化,不一致 反序列化失败,报一个异常,版本号不兼容

      注意:系统提供的版本号可能会发生变化,不同的时间点可能不同
  2.  为了避免上述情况发生 应该主动为类型提供一个固定的版本号
      这样序列化时 和反序列化时用的都是同一个版本号,就不会报版本号兼容
public class OutputStreamDemo01 {
    public static void main(String[] args) throws Exception {

        //创建一个学生
        Student s1 = new Student("小明", 20, '男');
        Student s2 = new Student("小工",34, '女');
        //使用对象输出流将学生写出到文件中
        ObjectOutputStream oos = null;
        ObjectInputStream ois = null;
        try{
            oos = new ObjectOutputStream(
                    new BufferedOutputStream(
                    //流的构造器的相对路径相对的是Project文件夹, ./表示project文件夹,就是项目文件夹
                     new FileOutputStream("./student.s",true),4096));
            oos.writeObject(s1);
            oos.writeObject(s2);
            oos.flush();
            ois = new ObjectInputStream(
                    new BufferedInputStream(
                            new FileInputStream("./student.s"),4096));

            Object obj = ois.readObject();
            System.out.println(obj);
            obj = ois.readObject();
            System.out.println(obj);
            obj = ois.readObject();
            System.out.println(obj);
            obj = ois.readObject();
            System.out.println(obj);
        }catch(IOException e){
            e.printStackTrace();
        }finally {
            try {
                oos.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}


class Student implements  Comparable<Student>,Serializable{
//    public static final long serialVersionUID = 2100000000L;
    private String name;
    private int age;
    private char gender;

    public Student() {
    }
    public Student(String name, int age, char gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public char getGender() {
        return gender;
    }

    public void setGender(char gender) {
        this.gender = gender;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age && gender == student.gender && Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age, gender);
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender=" + gender +
                '}';
    }

    @Override
    public int compareTo(Student o) {
        return this.age - o.age;
    }
}

字符流
    1. 简介

Reader是字符输入流的父类,抽象类;Writer是字符输出流的父类,抽象类。字符流是以字符(char)为单位读写数据的,一次处理一个unicode。字符流的底层仍然是基本的字节流

    2. 转换流

基本的字符流称为转换流,在编写代码时候 默认使用的是UTF-8,字母1个字节,汉字3个字节

转换输出流 OutPutStreamWriter,使用该流可以设置字符集,并按照指定的字符集将字符转成字节后通过该流写出

常用构造器

OutputStreamWriter(OutputStream out,String charsetName)

OutputStreamWriter(OutputStream out)

常用方法

void  write(int c)
void  write(String str)
void  write(char[ ] chars)
void  write(String str,int off, int len)
void  write(char[ ] chars, int off, int len)


public class WriterTest {
    public static void main(String[] args) throws Exception {
        OutputStreamWriter osw = null;
        try{
             osw = new OutputStreamWriter(
                    new FileOutputStream("test07/char.txt"),"GBK");
             osw.write("你好,中国!");
        }finally {
            osw.close();
        }
    }
}

转换读入流 InPutStreamWriter,使用该流可以设置字符集,并按照指定的字符集从流中按照该编码将字节数据转换为字符并读取

常用构造器

InputStreamWriter(OutputStream out,String charsetName)

InputStreamWriter(OutputStream out)

当写入时候设置了字符集

如果读入时没有设置字符集 默认是UTF-8 ,就会读出来乱码

public class ReaderTset {
    public static void main(String[] args) throws Exception {
        InputStreamReader isr = null;
        try{
            isr = new InputStreamReader(
                    new FileInputStream("test07/char.txt"));
            char[] buf = new char[1024];
            int len = 0;
            while((len = isr.read(buf) )!= -1){
                System.out.println(new String(buf,0,len));
            }
        }finally {
            isr.close();
        }
    }
}

如果设置和写入时一样的字符集编码,就可以正确读入数据


public class ReaderTest {
    public static void main(String[] args) throws Exception {
        InputStreamReader isr = null;
        try{
            isr = new InputStreamReader(
                    new FileInputStream("./test07/char.txt"),"GBK");
            char[] chars = new char[1024];
            int len = -1;
            while((len = isr.read(chars))!=-1){
                System.out.println(new String(chars,0,len));
            }
        }finally {
            isr.close();
        }
    }
}

3. 缓冲字符流

PrintWriter 自动行刷新的缓冲字符输出流

当使用了自动行刷新,那么每写一行,然后再行末添加换行符,强制写出去

调用println方法。

常用构造器:

PrintWirter(File file)
PrintWriter(String filename)
PrintWriter(OutputStream out)
PrintWriter(OutputStream out,boolean autoFlush)
PrintWriter(Writer writer)
PrintWriter(Writer writer,boolean autoFlush)

public class PrintWriterTest {
    public static void main(String[] args) throws Exception {
        PrintWriter pw = null;
        try{
            pw = new PrintWriter(
                    new OutputStreamWriter(
                            new FileOutputStream("test07/char.txt")),true);
            pw.write("你好,世界!");
            pw.write(20);//
            char[] c = {'a', 'b', 'c'};
            pw.write(c);//写入一个char数组
            pw.write("中国最棒", 1, 3);
            pw.write(c, 0, 2);
            pw.print("你好全世界");
        }finally{
           // pw.close();
        }

当没有写流的关闭时,缓冲区没有满不会写入文件

但是  当使用了println() 方法写入文件时候,会强制写进去(boolean autoFlush的位置要写 true)

public class PrintWriterTest {
    public static void main(String[] args) throws Exception {
        PrintWriter pw = null;
        try{
            pw = new PrintWriter(
                    new OutputStreamWriter(
                            new FileOutputStream("test07/char.txt")),true);
            pw.write("你好,世界!");
            pw.write(20);//
            char[] c = {'a', 'b', 'c'};
            pw.write(c);//写入一个char数组
            pw.write("中国最棒", 1, 3);
            pw.write(c, 0, 2);
            pw.println("你好,世界!");
            pw.print("你好全世界");
            pw.flush();
        }finally{
           // pw.close();
        }
    }
}

 

BufferedReader 字符缓冲读入流

 1. 内部提供了一个缓冲区,尽可能一次性读取存满缓存区

 2. 程序员读取方法,从缓存区中获取数据,当获取到末尾时候,缓存区再次从文件中尽可能一次性读满数据

 3. BuffererReader(Reader reader)

 4. 常用方法readLine(): 读取一行数据,只读取到换行符,但是返回的数据不含换行符 

read(char[] chars);

read(char[ ] chars, int off, int len)

public class BufferedReaderTest {
    public static void main(String[] args) throws Exception {
        BufferedReader br = null;
        try{
            br = new BufferedReader(
                    new InputStreamReader(
                            new FileInputStream("test07/char.txt")));
            char c = (char)br.read();//只读取一个字符
            System.out.println(c);
            char[] c2 = new char[10];

            //将读出来的数据放入c2字符数组中 然后输出
            String str = "";
            str = br.readLine();//读取一行
            System.out.println("readLine()方法读出来的:"+str);
            int len = -1;
            while((len = br.read(c2))!=-1){
                System.out.println("剩下的所有:"+new String(c2,0,len));//读取剩下所有的
            }
        }finally{
            br.close();
        }
    }
}
4. 文件字符流

FileWriter  文件输出流

相当于OutputStreamWriter 和 OutputStream合起来的功能

构造器

FileWriter(File file)
FileWriter(File file,boolean append)
FileWriter(String filepath)
FileWriter(String filepath,boolean append)

继承了OutputStreamWriter等父类的方法,内部也维护着一个缓存区,需要手动调用flush方法进行刷新。

FileWriter(String filepath,boolean append)

public class FileWriterTest {
    public static void main(String[] args) throws Exception {
        FileWriter fw = null;
        try{
            fw = new FileWriter("test07/char.txt", true);
            fw.write("This is a cat");
            fw.write("This is a dog");
        }finally{
            fw.close();
        }
    }
}

 上述代码执行两次后

FileWriter(File file) 

public class FileWriterTest {
    public static void main(String[] args) throws Exception {
        FileWriter fw = null;
        try{
            fw = new FileWriter("test07/char.txt");
            fw.write("This is a cat");
            fw.write("This is a dog");
        }finally{
            fw.close();
        }
    }
}

解析:因为append处没有写true,默认是false,所以之前的

This is a catThis is a dogThis is a catThis is a dog 会被覆盖掉

FileReader 文件输入流

相当于InputStreamReader和FileInputStream合起来的功能,但是不能设置字符集

FileReader(File file)
FileReader(String filepath)

继承了InputStreamReader等父类的方法,内部也维护着一个缓存区,可以提高读取效率。

public class FileReaderTest {
    public static void main(String[] args) throws Exception {
        FileReader fr = null;
        File file = new File("test07/char.txt");
        try {
            fr = new FileReader(file);
            char c = (char) fr.read();
            System.out.println(c);
        }finally {
            fr.close();
        }
    }
}
5. 其他流

  System : 系统类 里面封装了一些本地方法和静态属性

静态属性
-PrintStream out: 标准输出流: 默认目的地是控制台 console

-PrintStream err: 标准错误输出流 默认目的地是控制台 console

-InputStream in: 标准输入流 默认数据源是控制台 console

System.out  返回一个标准输出流

System.in 返回一个标准输入流

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值