11 io

  • java.io.File类的shiyong
    java.io.File类:文件和目录路径名的抽象表示形式,与平台无关
    File 能新建、删除、重命名文件和目录,但 File 不能访问文件内容本身。如果需要访问文件内容本身,则需要使用输入/输出流。
    在UNIX中,此字段为‘/’,在Windows中,为‘\’


    关闭流的时候,本着先进后出的原则依次关闭

  • IO原理及流的分类

  • 流的分类

文件流

FileInputStream  /  FileOutputStream  /  FileReader  /  FileWriter

文件字节输入流

public class Test3 {
    public static void main(String[] args){
        try{
            FileInputStream in = new FileInputStream("home/ying/test.txt");

            byte[] b= new byte[10];

            int len = 0;

            while((len = in.read(b)) != -1){
                System.out.println(new String(b, 0, len));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

文件字节输出流

FileOutputStream out = new FileOutputStream("/home/ying/data/code/candidate/configs/test.txt");
        String str = "fafadfff";
        out.write(str.getBytes());
        out.flush();
        out.close();

文件字节流可以用来操作字符的文档,可以操作其他任何类型文件,字节流使用的是二进制。

  • 文件字符输入流
FileReader reader = new FileReader("/home/ying/data/code/candidate/configs/as1border1.cfg");
        char[] chs = new char[50];
        int len;
        while((len = reader.read(chs)) != -1){
      System.out.println(new String(chs, 0, len));
        }
        reader.close();
  • 文件字符输出流
    只适合内容是字符的文件
        FileWriter writer = new FileWriter(outPath);
        writer.write(text);//写数据到内存
        writer.flush();//把内存的数据刷到硬盘
        writer.close();
    }

在写入一个文件时,如果目录下有同名文件将被覆盖。
在读取文件时,必须保证该文件已存在,否则出异常。

缓冲流

文件处理流,是计算机和硬盘之间发生的io操作,基于硬盘的读写相对比较慢,速度受到硬盘读写速度的制约。
为了提高数据读写的速度,Java API提供了带缓冲功能的流类,在使用这些流类时,会创建一个内部缓冲区数组,即缓冲流是基于内存的。在内存中做io操作,比基于硬盘快75000多倍
BufferedInputStream / BufferedOutputStream /
BufferedReader / BufferedWriter

  • 缓冲字节输出流
FileOutputStream out = new FileOutputStream("/home/ying/data/code/candidate/configs/tt.txt");
        BufferedOutputStream bo = new BufferedOutputStream(out);
        String s = "HelloWorld";
        bo.write(s.getBytes());//写到内存中
        bo.flush();
        bo.close();
        out.close();
  • 缓冲字符输入流
public static void testBufferedReader() throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("/home/ying/data/code/candidate/configs/as1border1.cfg"));
        char[] ch = new char[20];
        int len;
        while ((len = br.read(ch)) != -1){
      System.out.println(new String(ch, 0, len));
        }
        br.close();
    }

转换流

  1. txt和JAVA文件一般有三种编码格式
    ISO8859-1 西欧编码,是纯粹的英文编码,不适应汉字
    GBK和UTF-8,适用于中文和英文
    但是对于中文,更一般的使用UTF-8编码
  2. 需要转换的情景:
    字节流中的数据都是字符,转成字符流更加高效
    InputStreamReader / OutputStreamWriter
public static void testInputStreamReader() throws Exception{
        FileInputStream fi = new FileInputStream("/home/ying/data/code/candidate/configs/tt.txt");

        InputStreamReader in = new InputStreamReader(fi, "UTF-8");//参数一是字节流,参数二是编码

        char[] ch = new char[10];

        int lent;

        while((lent = in.read(ch)) != -1){
      System.out.println(new String(ch, 0, lent));
        }

        in.close();
        fi.close();
    }
public static void testOutputStreamWriter() throws Exception{
        FileOutputStream fo = new FileOutputStream("/home/ying/data/code/candidate/configs/tt1.txt");

        OutputStreamWriter out = new OutputStreamWriter(fo, "UTF-8");

        out.write("你好");
        out.flush();
        out.close();
        fo.close();
    }

标准输入/输出流
System.in和System.out分别代表了系统标准的输入和输出设备
System.in的类型是InputStream
System.out的类型是PrintStream,其是OutputStream的子类FilterOutputStream 的子类

打印流(了解),sout

PrintStream / PrintWriter

数据流(了解)

用于读取和写出基本数据类型的数据
用数据输出流写到文件中的基本数据类型的数据是乱码的,不能辨认,需要用数据输入流读取,但是要保证用和当时写入的类型一致的方法读取,即写的时候是writeDouble(),读的时候需要用readDouble()
DataInputStream / DataOutputStream

public static void testDataOutputStream() throws Exception{
        DataOutputStream out = new DataOutputStream(new FileOutputStream("/home/ying/data/code/candidate/configs/tt2.txt"));
        out.writeBoolean(true);
        out.writeDouble(3.1415926);
        out.flush();
        out.close();
        DataInputStream in = new DataInputStream(new FileInputStream("/home/ying/data/code/candidate/configs/tt2.txt"));
        System.out.println(in.read());
        System.out.println(in.read());
        in.close();
    }

对象流 ----涉及序列化、反序列化

用于存储和读取对象的处理流。它的强大之处就是可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来。
序列化(Serialize):用ObjectOutputStream类将一个Java对象写入IO流中
反序列化(Deserialize):用ObjectInputStream类从IO流中恢复该Java对象
ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量, 序列化针对的是对象的属性,不针对类的属性

  1. 序列化的好处在于可将任何实现了Serializable接口的对象转化为字节数据,使其在保存和传输时可被还原
  2. 凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量:
    private static final long serialVersionUID;
    serialVersionUID用来表明类的不同版本间的兼容性
  3. 显示定义serialVersionUID的用途
    希望类的不同版本对序列化兼容,因此需确保类的不同版本具有相同的serialVersionUID
    不希望类的不同版本对序列化兼容,因此需确保类的不同版本具有不同的serialVersionUID
  4. 强调:如果某个类的字段不是基本数据类型或 String 类型,而是另一个引用类型,那么这个引用类型必须是可序列化的,否则拥有该类型的 Field 的类也不能序列化
  5. 反序列后接收的类一定是,类名,包名,类结构等等都要一致。
  • ObjectInputStream / ObjectOutputStream
public static void testSerialize() throws Exception{
    //定义对象的输出流,把对象的序列化之后的流存储到文件中
    ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("/home/ying/data/code/candidate/configs/tt3.txt"));
    Person1 person1 = new Person1();
    person1.name = "画画";
    person1.age = 11;
    out.writeObject(person1);
    out.flush();
    out.close();
  }

  public static void testDeserialize() throws Exception{
    //对象的反序列化
    ObjectInputStream in = new ObjectInputStream(new FileInputStream("/home/ying/data/code/candidate/configs/tt3.txt"));
    Person1 person1 = (Person1) in.readObject();
    in.close();
    System.out.println(person1.age);
    System.out.println(person1.name);
  }

随机存取文件流,

类支持 “随机访问” 的方式,程序可以直接跳到文件的任意 地方来读、写文件

  • 支持只访问文件的部分内容
  • 可以向已存在的文件后追加内容
    可以读取指定行的数据,也可以往指定的某一行写数据
  • RandomAccessFile
 public static void testRandomAccessFIleRead() throws Exception{
        //参数一文件路径,参数2是方式,访问模式,r,rw,rwd,rws
        RandomAccessFile ra = new RandomAccessFile("/home/ying/data/code/candidate/configs/tt1.txt", "r");
        ra.seek(3);//设置读取文件的起始点
        byte[] b = new byte[10];
         int len = 0;
         while((len = ra.read(b)) != -1){
      System.out.println(new String(b, 0, len));
         }
    }

public static void testRandomAccessFileWrite() throws Exception{
        RandomAccessFile ra = new RandomAccessFile("/home/ying/data/code/candidate/configs/tt1.txt", "rw");
        ra.seek(ra.length());
        ra.write("\n".getBytes());
        ra.write("你好".getBytes());
        ra.close();
    }
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容