一、File类

概念

  • 代表物理盘符中的一个文件或者文件夹

常见方法

**exists()** 文件是否存在
isDirectory() 是否是目录
isFile() 是否是文件
length() 返回文件长度
**getName()** 文件的名字
getAbsolutePath() 获取文件绝对路径
**createNewFile()** 创建一个新的文件
**delete()** 删除文件
getParent() 上级目录
mkdir() 创建一个新目录
listFiles() 列出目录中的所有内容

跟文件相关的

  1. public static void main(String[] args) throws IOException {
  2. //创建文件对象
  3. File f = new File("d:/test");
  4. File f1 = new File("d:\\test");
  5. /*
  6. File.separator获取当前操作系统的路径拼接符号
  7. File file2 = new File("d:"+File.separator+ "test");
  8. */
  9. System.out.println("文件是否可读:" + f.canRead());
  10. System.out.println("文件是否可写:" + f.canWrite());
  11. System.out.println("文件的名字:" + f.getName());
  12. System.out.println("上级目录:" + f.getParent());
  13. System.out.println("是否是一个目录:" + f.isDirectory());
  14. System.out.println("是否是一个文件:" + f.isFile());
  15. System.out.println("是否隐藏:" + f.isHidden());
  16. System.out.println("文件的大小:" + f.length());
  17. System.out.println("是否存在:" + f.exists());
  18. System.out.println("比较两个对象对应的文件路径:" + f.equals(f1));
  19. System.out.println("绝对路径路径:" + f.getAbsolutePath());
  20. System.out.println("相对路径:" + f.getPath());
  21. System.out.println("toString:" + f.toString());//相当于相对路径
  22. if (f.exists()) {//如果文件存在,将文件删除操作
  23. f.delete();
  24. } else { //如果文件不存在,就创建这个文件
  25. f.createNewFile();
  26. }
  27. }
  28. }

跟目录相关的

  1. public class File01 {
  2. public static void main(String[] args) {
  3. //创建文件对象
  4. File f = new File("d:/test");
  5. f.mkdir();//创建单层目录
  6. f.mkdirs();//创建多层目录
  7. f.delete();//只会删除一层,并且这层目录是空的,如果有内容就不会删除
  8. //查看文件下的目录
  9. File[] files = f.listFiles();
  10. for(File file:files){
  11. System.out.println(file.getAbsolutePath());
  12. }
  13. }
  14. }

二、io流

iO流用来处理设备之间的数据传输,io流形象地理解一个“管子”,程序和数据源直接**沟通**的桥梁

IO流分类

  1. 方向:输入流 和 输出流
  2. 内容:字节流 和 字符流

IO流体系

未命名文件.png

经验 , Stream结尾的为字节流 Reader Writer为字符流

三、字节流

文件流

以字节形式读取文件数据,通常适用于读二进制文件 如图片 视频 音频文件等。

输入流 FileInputStream

方式1

public static void main(String[] args) throws IOException {

        //1. 创建流对象
        FileInputStream fis = new FileInputStream("G:\\LOL.jpg");

        // 2. 读数据
        int count = 0;//定义一个计数器,用来计读入的字节个数
        int n = frs.read();
        while(n! = -1){
            count++;
            System.out.print(n); 
            n= frs.read();
      }
       System.out.print(count);

    // 3.关闭流
        fis.close();

    }

方式2

public static void main(String[] args) throws IOException {

        //1. 创建流对象
        FileInputStream fis = new FileInputStream("G:\\LOL.jpg");

        // 2. 读数据
        byte[] buff = new byte[6];// 准备临时存放容器,用于每次存储读取的数据
        int len = 0;//本次读取的实际字节数
        //循环读取字节
        while ((len = fis.read(buff)) != -1) {
            String s = new String(buff, 0, len);
            System.out.println(s);
        }
        // 3.关闭
        fis.close();

    }

注意事项

  • 文件是**utf-8**进行存储的,**英文字符**:底层占用**1个字节****中文字符**,底层占用**3个字节**
  • 如果文件是文本文件,不要使用字节流读取,建议使用字符流
  • **read()**读取一个字节,返回值是int类型,而不是byte类型,这是因为read方法底层做了处理,让繁华的数据都是**正数**,就是为了避免如果字节繁华的是-1,那么到底是读入的字节,还是文件结尾呢

输出流 FileOutStream

public class FileOutputStreamCase {

    public static void main(String[] args) throws IOException {
        //1. 创建流
        FileOutputStream fos = new FileOutputStream("G:\\LOL.jpg",true);

        //2. 写数据
        String massage = "我喜欢景甜";
        fos.write( massage.getBytes() );

        //3 . 关闭流
        fos.close();
    }
}

功能:完成图片复制

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

        //源图片
        File f1 = new File("G:\\LOL.jpg");

        //目标图片
        File f2 = new File("G:\\LOL.jpg");

        //创建输入流对象
        FileReader fr = new FileInputStream(f1);

        //创建输出流对象
        FileWriter fw = new FileOutputStream(f2);

        //【方式1 读数据 写数据】
        int n = fis.read();
        while(n! = -1){
         fw.write(n) 
         n= fis.read();
      }
       //【方式2 利用缓冲字符数组】
        byte[] b = new byte[5];
        int len = fis.read(b);
        while(len != -1){
            fw.write(b,o,len)//将缓冲数组中有效长度写出
            len = fis.read(b);
        }


       //关闭流(关闭流的时候,倒着关闭,后用先关)
        fos.close();
        fis.close();
    }
}

缓存流

没有特别功能,指定提供了缓冲,优先从缓存中读写,降低和IO设备访问次数提高效率。

输入流 BufferedInputStream

    public static void main(String[] args) throws IOException {
        //1. 创建流
        BufferedInputStream bis =
                new BufferedInputStream(
                        new FileInputStream("G:\\LOL.jpg"));

        //2. 读文件
        byte[] buff = new byte[1024];
        int len = 0;
        while( (len=bis.read(buff)) !=-1  ){
            String xx = new String( buff, 0 , len );
            System.out.println(xx);
        }
        //3.关闭
        bis.close();
    }

输出流 BufferedOutputStream

  public static void main(String[] args) throws IOException {

        //1. 创建流
        BufferedOutputStream bos =
                new BufferedOutputStream(
                        new FileOutputStream("G:\\LOL.jpg)  );
        //2. 写数据
        String massage = "q床前明月光,疑是地上霜q";
        bos.write( massage.getBytes() );
        bos.flush(); //缓冲流的方法
        //3. 关闭流
        bos.close();

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

        //1. 源图片
        BufferedInputStream bis =
                new BufferedInputStream(
                        new FileInputStream("G:\\LOL.jpg"));

        //1. 目标图片
        BufferedOutputStream bos =
                new BufferedOutputStream(
                        new FileOutputStream("G:\\LOL1.jpg)  );


       //利用缓冲字符数组
        byte[] b = new byte[1024*5];
        int len = bis.read(b);
        while(len != -1){
            bos.write(b,o,len)//将缓冲数组中有效长度写出
            len = bis.read(b);
        }


       //关闭流(
        bos.close();
        bis.close();
    }
}

对象流

对象流作用是,可以把一个对象写到文件中,或者把一个文件中的对象,读取到内存。它就是序列化和反序列化的流:
序列化: 把对象二进制信息 写入流。
反序列化: 从流中读取对象的二进制信息,还原到内存。

序列化流ObjectOutputStream

  public static void main(String[] args) throws IOException {

        //1 创建流
        ObjectOutputStream oos = new ObjectOutputStream(    new FileOutputStream("obj.dat")   );

        //2. 写数据:将内存中的字符串写到文件中
        oos.writeInt("你好");

        //3.关闭
        oos.close();
    }

反序列化流ObjectInputStream

public static void main(String[] args) throws IOException, ClassNotFoundException {
        //1. 创建流
         ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.dat"));

        //2. 读,必须按照序列化顺序读取且不可多读,否则引发EOFException异常。
         String s = (String)(ois.readObject();
         System.out.println(s);

        //3.关闭
         ois.close();

  }

细节: 1. 反序列化必须提供需要的字节码 2. 本地字节码版本号和流中的版本号要一致。

四、字符流

文件流[重点]

以子符形式读取文件数据,通常适用于读取纯文本文件 存文本信息。

FileReader 输入流

/* 
 *    需求:往文件中读数据
 *    写数据--输出流--FileReader
 */

public class FileReaderDemo {
  public static void main(String[] args) throws IOException {

    //创建一个File类
    File f = new File("d:\\Test.txt");

    //创建输入流对象
    FileReader fr = new FileReader(f);

    //方式1:读数据
    int n = fr.read();
      while(n! = -1){
         System.out.print(n); 
          n= fr.read();
      }

    //方式2:读数据
    int n;
    while((n=fr.read())!=-1) {
     System.out.print((char)n);
    }

    //关闭流
    fr.close();
  }
}

FileWriter 输出流

/* 
 *    需求:往文件中写数据
 *    写数据--输出流--FileWriter
 */

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

        //目标文件
        File f = new File("d:\\demo.txt");

        //创建输出流对象
        FileWriter fw = new FileWriter();

        //写数据
        String str = "你好中国";
        char[] chars = str.toCharArray();
        fw.write(chars);

       //关闭流
        fw.close();
    }
}

利用:FileReader、FileWriter文件复制

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

        //源文件
        File f1 = new File("d:\\demo.txt");

        //目标文件
        File f2 = new File("d:\\demo1.txt");

        //创建输入流对象
        FileReader fr = new FileReader(f1);

        //创建输出流对象
        FileWriter fw = new FileWriter(f2);

        //【方式1 读数据 写数据】
        int n = fr.read();
        while(n! = -1){
         fw.write(n) 
         n= fr.read();
      }
       //【方式2 利用缓冲字符数组】
        char[] ch = new char[5];
        int len = fr.read(ch);
        while(len != -1){
            fw.write(ch,o,len)//将缓冲数组中有效长度写出
            len = fr.read(ch);
        }


       //关闭流(关闭流的时候,倒着关闭,后用先关)
        fw.close();
        fr.close();
    }
}

注意事项
相对路径:相对当前项目而言的,在项目的根目录下(Test.txt)
绝对路径:以盘符开始的路径(d:\Test.txt)
* 不要用字符流操作非文本文件

close()和flush()方法的区别:

  • flush(): 刷新缓冲区。流对象还可以继续使用。
  • close(): 先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了。

    public class FileWriterDemo2 {
    public static void main(String[] args) throws IOException {
      //创建输出流对象
      //FileWriter fw = new FileWriter("d:\\word.txt");
      FileWriter fw = new FileWriter("word.txt");
    
      //调用输出流对象的写数据方法,并刷新缓冲区
      fw.write("helloworld");
      fw.flush();
      fw.write("java");
      fw.flush();
    
      //释放资源
      fw.close();
    
      //Stream closed
      //fw.write("javaee");
      //fw.flush();
    }
    }
    

构造方法

  • void write(String str):写一个字符串数据
  • void write(String str,int index,int len):写一个字符串中的一部分数据
  • void write(int ch):写一个字符数据,这里写int类型的好处是既可以写char类型的数据,也可以写char对应的int类型的值。’a’,97
  • void write(char[] chs):写一个字符数组数据
  • void write(char[] chs,int index,int len):写一个字符数组的一部分数据

    public class FileWriterDemo3 {
    public static void main(String[] args) throws IOException {
      //创建输出流对象
      FileWriter fw = new FileWriter("b.txt");
    
      //void write(String str):写一个字符串数据
      //fw.write("abcde");
    
      //void write(String str,int index,int len):写一个字符串中的一部分数据
      //fw.write("abcde",0,5);
      //fw.write("abcde",1,3);
    
      //void write(int ch):写一个字符数据,这里写int类型的好处是既可以写char类型的数据,也可以写char对应的int类型的值。'a',97
      //fw.write('a');
      //fw.write(97);
    
      //void write(char[] chs):写一个字符数组数据
      char[] chs = {'a','b','c','d','e'};
      //fw.write(chs);
    
      //void write(char[] chs,int index,int len):写一个字符数组的一部分数据
      //fw.write(chs,0,5);
      fw.write(chs,2,3);
    
      //释放资源
      fw.close();
    }
    }
    

缓冲流

BufferedReader 输入流

BufferedWriter 输出流

特别方法 **readLine() **可以一次读取一行,如果未读到返回null
特别方法 **newLine() **相当于写一个**换行**

  public static void main(String[] args) throws IOException {
        //1 创建流
        BufferedReader br = new BufferedReader( new FileReader("g:/book.txt"));

        //1 创建流
        BufferedWriter bw = new BufferedWriter(  new FileWriter("node.txt",true));

        //2 读数据
        String str = br.readLine()//每次读取文本中一行,返回字符串
        while( str !=null ){
           br.write(str)
           bw.newLine();//换行    
           str = br.readLine()
        }
        //3.关闭流
        bw.close();
        br.close();
 }

转换流

有些时候,如果读取的文件是文本文件,但是提供的却是字节流,字符流明显读取文本字符更加方便,这时可以把字节流转换成字符流操作。

只有字节流转 字符流没有字符流转字节流,转换流本身就是一种字符流。

InputStreamReader 输入流

/**
 * 字节输入流  转 字符输入流
 */
public class InputStreamReaderCase {

    public static void main(String[] args) throws IOException {

        //字符流
        BufferedReader br = new BufferedReader( new InputStreamReader(  new FileInputStream("d:/text.txt")  )  );

        String buff = null;

        while (  (buff=br.readLine()) !=null  ){
            System.out.println(buff);
        }

        br.close();

    }
}

OutputStreamWriter 输出流

 *
 *  字节输出流  转 字符输出流
 */
public class OutputStreamWriterCase {
    public static void main(String[] args) throws IOException {
        BufferedWriter bw = new BufferedWriter(   new OutputStreamWriter( new FileOutputStream("d:/text.txt")  ) );
        bw.newLine();
        bw.write("王麻子,20,男,C#");
        bw.flush();
        bw.close();
    }
}

利用:InputStreamReader、OutputStreamWriter文件复制

public class Test {

    public static void main(String[] args) throws IOException {

        //源文件输入方向
        BufferedReader br = new BufferedReader( new InputStreamReader(  new FileInputStream("d:/text.txt")  )  );

        //目标文件输出方向
        BufferedWriter bw = new BufferedWriter( new OutputStreamWriter( new FileOutputStream("d:/text1.txt")  ) );

        //开始动作
        char[] ch = new char[20];
        int len = br.read(ch);
        while(len!=-1){
            bw.write(ch,0,len)
            en = br.read(ch);
        }
        //关闭流
       bw.close();
       br.close();

    }
}

编码与字符集

编码指的是把字符与数字对应的过程。 字符集就是一张记录了对应关系的信息表。ASCII就是一种编码表。像这种还有很多。

  1. GBK 国标码
  2. ISO-8859-1 西欧语言
  3. Big5 台湾香港 繁体字
  4. Unicode 联合编码( UTF-8 UTF-16 )

    public static void main(String[] args) throws IOException {
    
        String hello = "你好中国";
        byte[] bytes = hello.getBytes();// UTF-8  解码
        System.out.println(Arrays.toString(bytes));
    
        byte[] buff = {-28, -67, -96, -27, -91, -67, -28, -72, -83, -27, -101, -67};
        String newHello = new String( buff ,"UTF-8" ); // 使用 UTF-8 编码
        System.out.println(newHello);
    
        System.out.println("--------------------------------------");
        FileInputStream fis = new FileInputStream("d:/hello.txt");
        InputStreamReader isr = new InputStreamReader(fis,"GBK");
    
        char[] buff2= new char[1204];
        int len;
        while (  ( len = isr.read(buff2))!=-1  ){
            System.out.println(buff2);
        }
        isr.close();
        fis.close();
    }
    

    编码解码不一致,就会出现乱码

打印流

打印流也是输出流, 存在字节打印流和字符打印流。

字节打印流PrintStream

public class PrintDemo {
    public static void main(String[] args) throws IOException {
        // 直接打印到文件
        PrintStream out = new PrintStream("d:/abc.txt");
        out.println("helloword");

        //  打印到 其他字节输出流
        FileOutputStream os = new FileOutputStream("d:/abc.txt",true);
        PrintStream out2 = new PrintStream( os);
        out2.println("java");
    }
}

字符打印流 PrintWriter

public class PrintDemo {
    public static void main(String[] args) throws IOException {

        //直接 打印到文件
        PrintWriter pw = new PrintWriter("D:/abc.txt");
        pw.println("css");
        pw.close();
        //打印 到其它字符输出流
        PrintWriter pw2 = new PrintWriter(  new FileWriter("d:/abc.txt",true));
        pw2.println("java");
        pw2.close();
        //打印 到其他字节输出流
        PrintWriter pw2 = new PrintWriter(  new FileOutputStream("d:/abc.txt",true)  );
        pw2.println("java");
        pw2.close();
    }
}

键盘录入的内容输出到文件中【重点】

public class Test03 {
    public static void main(String[] args) throws IOException {
        // 1、先准备输入方向
        //键盘录入
        InputStream in = System.in;//属于字节流
        //字节流转字符流
        InputStreamReader isr = new InputStreamReader(in);
        //在isr外面套一个缓冲流
        BufferedReader br = new BufferedReader(isr);

        // 2、再准备输出方向
        //准备目标文件
        File f = new File("d:\\test.tex");
        FileWriter fw = new FileWriter(f);
        BufferedWriter bw = new BufferedWriter(fw);

        // 3、开始动作
        String s = br.readLine();
        while (!s.equals("exit")){
            bw.write(s);
            bw.newLine();
            s = br.readLine();
        }
        // 4、关闭流
        bw.close();
        br.close();
    }
}

随机文件访问类

RandomAccessFile 此类是一个文件读写操作工具类,它和其他流不同,它没有方向性,它既可以读文件,也可以写文件。
支持模式: r 只读 w只写 rw读写
通过seek(int pos) 方法移动指针

package print;

import java.io.*;

public class PrintDemo {
    public static void main(String[] args) throws IOException {

        //随机访问文件类
        RandomAccessFile raf = new RandomAccessFile("d:/abc.txt","rw");
        //移动光标到末尾 写数据
        raf.seek( raf.length() );
        raf.writeBytes("mysql");

        //移动光标到 开始 读操作
        raf.seek(0);
        String line = raf.readLine();
        System.out.println(line);
        raf.close();
    }
}

System类对IO流的支持

**System.in**输入流——>默认情况下,从键盘输入
**Scanner**: 起扫描作用

public class Test {
    public static void main(String[] args) throws IOException {
       Scanner sc = new Scanner(new FileInputStream(new File("d\\Test.txt")));
        while (sc.hasNext()){
            System.out.println(sc.next());
        }
    }
}


**System.out**: 输出流——>默认情况下,输出到控制台

public class Test02 {
    public static void main(String[] args) {
        //写到控制台
        PrintStream out = System.out;

        //调用方法:不换行
        out.print("你好1");
        out.print("你好2");
        out.print("你好3");

        //换行
        out.println("你好1");
        out.println("你好2");
        out.println("你好3");

        System.out.println("你是");
        System.out.print("中国人");
    }
}