Java 基础笔记4

一、IO流

IO流

  1. 程序设计的输入输出系统(Input/Output),即为IO流
  2. 输入(Input)指的是:可以让程序系统从外部系统获得数据,核心含义是读取外部数据
  3. 输出(Output)指的是程序输出数据给外部系统,核心含义是将数据写出外部系统

数据源Data Source

  1. 数据源是提供数据的原始媒介,分为源设备和目标设备
  2. 源设备:为程序提供数据,一般对应输入流
    目标设备:程序数据的目的地,一般对应输出流

  1. 流的动态概念是一连串连续动态的数据集合
  2. 输入流:将数据源中的数据输送到程序中
    输出流:将程序中的数据输送到数据源中

四大IO抽象类

  1. InputStream :表示字节输入流的抽象类;数据读取通过子类来实现,不能直接实例化
  2. OutputStream :表示字节流输出流的抽象类,将接收到的输出字节发送到某个目的地
  3. Reader :用于读取字符流的抽象类
  4. Writer:用于输出字符流的抽象类
 例:图片加密
 /*
 * 加密操作
 * 解密操作
 *
 * 原理:一个数据异或两次,数据不变
 * */
public class Case01 {
    public static void main(String[] args) throws IOException {

//        1、输入输出流
        FileInputStream fis = new FileInputStream("C:\\Users\\19605\\Desktop\\p.jpg");
        FileOutputStream fio = new FileOutputStream("C:\\Users\\19605\\Desktop\\p2.jpg");

        //        解密的时候只需把p2再异或一遍,写到新的文件
//        FileInputStream fis = new FileInputStream("C:\\Users\\19605\\Desktop\\p2.jpg");
//        FileOutputStream fio = new FileOutputStream("C:\\Users\\19605\\Desktop\\p3.jpg");
//          2、读写数据

        int b = 0;
        while ((b = fis.read()) != -1) {
            fio.write(b ^ 5);
            System.out.print(b);
        }

        fis.close();
        fio.close();

        System.out.println("图像加密ok");
 
    }
}

二、File类

  在 Java 中,File 类是 java.io 包中唯一代表磁盘文件本身的对象,也就是说,如果希望在程序中操作文件和目录,则都可以通过 File 类来完成。File 类定义了一些方法来操作文件,如新建、删除、重命名文件和目录等。
  File 类不能访问文件内容本身,如果需要访问文件内容本身,则需要使用输入/输出流。
  File 类提供了如下三种形式构造方法。
File(String path):如果 path 是实际存在的路径,则该 File 对象表示的是目录;如果 path 是文件名,则该 File 对象表示的是文件。
File(String path, String name):path 是路径名,name 是文件名。
File(File dir, String name):dir 是路径对象,name 是文件名。
  使用任意一个构造方法都可以创建一个 File 对象,然后调用其提供的方法对文件进行操作。

  常用方法:
boolean canRead()   测试应用程序是否能从指定的文件中进行读取
boolean canWrite()   测试应用程序是否能写当前文件
boolean delete()   删除当前对象指定的文件
boolean exists()   测试当前 File 是否存在
String getAbsolutePath()   返回由该对象表示的文件的绝对路径名
String getName()   返回表示当前对象的文件名或路径名(如果是路径,则返回最后一级子路径名)
String getParent()   返回当前 File 对象所对应目录(最后一级子目录)的父目录名
boolean isAbsolute()   测试当前 File 对象表示的文件是否为一个绝对路径名。该方法消除了不同平台的差异,可以直接判断 file 对象是否为绝对路径。在 UNIX/Linux/BSD 等系统上,如果路径名开头是一条斜线/,则表明该 File 对象对应一个绝对路径;在 Windows 等系统上,如果路径开头是盘符,则说明它是一个绝对路径。
boolean isDirectory()   测试当前 File 对象表示的文件是否为一个路径
boolean isFile()   测试当前 File 对象表示的文件是否为一个“普通”文件
long lastModified()   返回当前 File 对象表示的文件最后修改的时间
long length()   返回当前 File 对象表示的文件长度
String[] list()   返回当前 File 对象指定的路径文件列表
String[] list(FilenameFilter)   返回当前 File 对象指定的目录中满足指定过滤器的文件列表
boolean mkdir()   创建一个目录,它的路径名由当前 File 对象指定
boolean mkdirs()   创建一个目录,它的路径名由当前 File 对象指定
boolean renameTo(File)   将当前 File 对象指定的文件更名为给定参数 File 指定的路径名

一、 获取文件属性

  在 Java 中获取文件属性信息的第一步是先创建一个 File 类对象并指向一个已存在的文件

public class Demo01 {
    public static void main(String[] args) {
        String path = "C:/windows/"; // 指定文件所在的目录
        File f = new File(path, "notepad.exe"); // 建立File变量,并设定由f变量引用
        System.out.println("C:\\windows\\notepad.exe文件信息如下:");
        System.out.println("============================================");
        System.out.println("文件长度:" + f.length() + "字节");
        System.out.println("文件或者目录:" + (f.isFile() ? "是文件" : "不是文件"));
        System.out.println("文件或者目录:" + (f.isDirectory() ? "是目录" : "不是目录"));
        System.out.println("是否可读:" + (f.canRead() ? "可读取" : "不可读取"));
        System.out.println("是否可写:" + (f.canWrite() ? "可写入" : "不可写入"));
        System.out.println("是否隐藏:" + (f.isHidden() ? "是隐藏文件" : "不是隐藏文件"));
        System.out.println("最后修改日期:" + new Date(f.lastModified()));
        System.out.println("文件名称:" + f.getName());
        System.out.println("文件路径:" + f.getPath());
        System.out.println("绝对路径:" + f.getAbsolutePath());
    }
}

二、 创建和删除文件

File 类不仅可以获取已知文件的属性信息,还可以在指定路径创建文件,以及删除一个文件。创建文件需要调用 createNewFile() 方法,删除文件需要调用 delete() 方法。无论是创建还是删除文件通常都先调用 exists() 方法判断文件是否存在

public class Demo01 {
    public static void main(String[] args) throws IOException {
        File f = new File("C:\\test.txt"); // 创建指向文件的File对象
        if (f.exists()) // 判断文件是否存在
        {
            f.delete(); // 存在则先删除
        }
        f.createNewFile(); // 再创建
    }
}

ps:在不同的操作系统中,路径的分隔符是不一样的,例如:
  Windows 中使用反斜杠\表示目录的分隔符。
  Linux 中使用正斜杠/表示目录的分隔符。

public static void main(String[] args) throws IOException {
    String path = "C:" + File.separator + "test.txt"; // 拼凑出可以适应操作系统的路径
    File f = new File(path);
    if (f.exists()) // 判断文件是否存在
    {
        f.delete(); // 存在则先删除
    }
    f.createNewFile(); // 再创建
}

  此更新代码可在任意操作系统使用

三、 创建和删除目录

  File 类除了对文件的创建和删除外,还可以创建和删除目录。创建目录需要调用 mkdir() 方法,删除目录需要调用 delete() 方法。无论是创建还是删除目录都可以调用 exists() 方法判断目录是否存在。

public class Demo01 {
    public static void main(String[] args) {
        String path = "C:/config/"; // 指定目录位置
        File f = new File(path); // 创建File对象
        if (f.exists()) {
            f.delete();
        }
        f.mkdir(); // 创建目录
    }
}

四、 遍历目录

  通过遍历目录可以在指定的目录中查找文件,或者显示所有的文件列表。File 类的 list() 方法提供了遍历目录功能,该方法有如下两种重载形式。

  1. String[] list()
    该方法表示返回由 File 对象表示目录中所有文件和子目录名称组成的字符串数组,如果调用的 File 对象不是目录,则返回 null。
    提示:list() 方法返回的数组中仅包含文件名称,而不包含路径。但不保证所得数组中的相同字符串将以特定顺序出现,特别是不保证它们按字母顺序出现。

  2. String[] list(FilenameFilter filter)
    该方法的作用与 list() 方法相同,不同的是返回数组中仅包含符合 filter 过滤器的文件和目录,如果 filter 为 null,则接受所有名称。

public class Demo01 {
    public static void main(String[] args) {
        File f = new File("C:/"); // 建立File变量,并设定由f变量变数引用
        System.out.println("文件名称\t\t文件类型\t\t文件大小");
        System.out.println("===================================================");
        String fileList[] = f.list(); // 调用不带参数的list()方法
        for (int i = 0; i < fileList.length; i++) { // 遍历返回的字符数组
            System.out.print(fileList[i] + "\t\t");
            System.out.print((new File("C:/", fileList[i])).isFile() ? "文件" + "\t\t" : "文件夹" + "\t\t");
            System.out.println((new File("C:/", fileList[i])).length() + "字节");
        }
    }
}

三、常用流

一、 文件字节流

  针对文件的读写,JDK专门提供了两个类,分别是 FileInputStream 和 FileOutputStream ,它们都是InputStream 的子类。
  Example01:以字节流形式读取文件中的数据
  Example02:将数据以字节流形式写入文件(覆盖文件内容)
  Example03:将数据以字节流形式写入文件(追加文件内容)

1. 字节输入流

FileInputStream 通过字节的方式读取文件,适合读取所有类型的文件

import java.io.FileInputStream;
import java.io.IOException;

public class Demo01 {
    public static void main(String[] args) throws IOException {
        FileInputStream in = null;
        try{
            //创建文件字节输入流对象
            in = new FileInputStream("C:/Users/lenovo/Desktop/ztx.txt");
            int temp = 0;
            while((temp = in.read()) != -1){
                System.out.println(temp);
            }
        } catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (in !=null){
                    in.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

注意:首先要确保文件 ztx.txt 存在并且可读,否则会抛出文件找不到的异常。

2.字节输出流

FileOutputStream 通过字节的方式写数据到文件中,适合所有类型的文件。

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo01 {
    public static void main(String[] args) throws IOException {
        FileInputStream in = null;
        FileOutputStream on = null;
        try{
            //创建文件字节输入流对象
            in = new FileInputStream("C:/Users/lenovo/Desktop/ztx.txt");
            //创建文件字节输出流对象
            on = new FileOutputStream("C:/Users/lenovo/Desktop/zxt.txt");
            int temp = 0;
            while((temp = in.read()) != -1){
                on.write(temp);
            }
            //将数据从内存中写入到磁盘中
            on.flush();
        } catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (in !=null){
                    in.close();
                }
                if (on !=null){
                    on.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

注意:程序运行后,会自动生成一个新的文本文件 zxt.txt 。如果 zxt .txt 已经存在数据,那么该文件中的数据会先被清空,再写入新的数据。

3. 加了缓冲区来提高读写的效率

方法一、

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo01 {
    public static void main(String[] args) throws IOException {
        FileInputStream in = null;
        FileOutputStream on = null;
        try{
            //创建文件字节输入流对象
            in = new FileInputStream("C:/Users/lenovo/Desktop/ztx.txt");
            //创建文件字节输出流对象
            on = new FileOutputStream("C:/Users/lenovo/Desktop/zxt.txt");
            //创建一个缓冲区,提高读写效率
            byte[] buff = new byte[1024];
            int temp = 0;
            while((temp = in.read(buff)) != -1){
                on.write(buff, 0, temp);
            }
            //将数据从内存中写入到磁盘中
            on.flush();
        } catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (in !=null){
                    in.close();
                }
                if (on !=null){
                    on.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

  此方法是给指定空间大小的缓冲区,然后一次一次的输出直到结束。例如410斤大米给能装50斤的袋子,一袋子一袋子装走,最后一袋少点。

方法二、

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo01 {
    public static void main(String[] args) throws IOException {
        FileInputStream in = null;
        FileOutputStream on = null;
        try{
            //创建文件字节输入流对象
            in = new FileInputStream("C:/Users/lenovo/Desktop/ztx.txt");
            //创建文件字节输出流对象
            on = new FileOutputStream("C:/Users/lenovo/Desktop/zxt.txt");
            //创建一个缓冲区,提高读写效率
            byte[] buff = new byte[in.available()];
            int temp = 0;
            while((temp = in.read(buff)) != -1) {
                in.read(buff);
                //将数据从内存中写入到磁盘中
                on.write(buff);
                on.flush();
            }
        } catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (in !=null){
                    in.close();
                }
                if (on !=null){
                    on.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

  此方法是根据输入流对象预估长度给出空间大小的缓冲区。例如200斤的大米就给200斤的袋子一次性扛走,但是对大文件会占用很大的内存,所以不建议大文件使用

4. 字节缓冲流提高读写效率

import java.io.*;

public class Demo01 {
    public static void main(String[] args) throws IOException {
        FileInputStream in = null;
        FileOutputStream on = null;
        BufferedInputStream bin = null;
        BufferedOutputStream bon = null;
        try {
            in = new FileInputStream("C:/Users/lenovo/Desktop/ztx.txt");
            bin = new BufferedInputStream(in);
            on = new FileOutputStream("C:/Users/lenovo/Desktop/zxt.txt");
            bon = new BufferedOutputStream(on);
            //缓冲流中的byte数组长度默认是8192
            int temp=0;
            while ((temp = bin.read()) != -1){
                bon.write(temp);
            }
            bon.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                //注意:关闭流顺序:“后开的先关闭”
                if (bin != null){
                    bin.close();
                }
                if (bon != null){
                    bon.close();
                }
                if (in != null){
                    in.close();
                }
                if (on != null){
                    on.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

区别:FileInputStream是字节流,BufferedInputStream是字节缓冲流,使用BufferedInputStream读资源比FileInputStream读取资源的效率高(BufferedInputStream的read方法会读取尽可能多的字节),且FileInputStream对象的read方法会出现阻塞

5. FileOutputStream

FileOutputStream的构造函数 FileOutputStream(String fileName,boolean append) ,用于把数据追加写入文件。

import java.io.FileOutputStream;
import java.io.IOException;

public class HelloWorld {
    public static void main(String[] args) throws IOException {
        FileOutputStream on = null;
        try {
            on = new FileOutputStream("C:/Users/lenovo/Desktop/ztx.txt", ture);
            String str = " zhangtxbadboy";
            on.write(str.getBytes());
            on.flush();
        }catch (Exception e ){
            e.printStackTrace();
        }finally {
            try {
                if (on != null){
                    on.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        on.close();
    }
}

注意:在 FileOutputStream 函数中第二个参数为ture时,为追加内容到文末;为flase时,为覆盖为其内容

6.定义文件拷贝工具类

import java.io.*;

public class HelloWorld {
    public static void main(String[] args) {
        Copy("C:/Users/lenovo/Desktop/ztx.txt","C:/Users/lenovo/Desktop/zxt.txt");
    }

    //src 表示要拷贝的来源 ,des 表示拷贝到的地址
    public static void Copy(String src,String des){
        FileInputStream in =null;
        BufferedInputStream bin =null;
        FileOutputStream on =null;
        BufferedOutputStream bon = null;
        try {
            in=new FileInputStream(src);
            bin = new BufferedInputStream(in);
            on =new FileOutputStream(des);
            bon =new BufferedOutputStream(on);
            int temp = 0;
            while ((temp=bin.read()) != -1){
                bon.write(temp);
            }
            bon.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if(bin !=null){
                    bin.close();
                }
                if (in !=null){
                    in.close();
                }
                if (bon !=null){
                    bon.close();
                }
                if (on !=null){
                    on.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

二、 文件字符流

1. 文件字符输入流

  如果我们处理的是文本文件,也可以使用文件字符流,它以字符为单位进行操作

import java.io.FileReader;

public class Demo01 {
    public static void main(String[] args) {
        FileReader fr = null;
        try {
            fr = new FileReader("C:/Users/lenovo/Desktop/ztx.txt");
            int temp=0;
            while ((temp=fr.read())  != -1){
                System.out.println((char)temp);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (fr !=null){
                    fr.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

2. 文件字符输出流

import java.io.FileWriter;

public class Demo01 {
    public static void main(String[] args) {
        FileWriter fw = null;
        FileWriter fw2 = null;
        FileWriter fw3 = null;
        try {
            fw = new FileWriter("C:/Users/lenovo/Desktop/ztx.txt");
            fw.write("hello\r\n");// \r\n 是回车换行
            fw.write("world\r\n");

            fw2 = new FileWriter("C:/Users/lenovo/Desktop/ztx1.txt");
            fw2.write("wao\r\n");//会覆盖前面的hello

            fw3=new FileWriter("C:/Users/lenovo/Desktop/ztx2.txt",true);//true是使其能够继续编写,不会覆盖
            fw3.write("waowaowao\r\n");

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if(fw !=null){
                    fw.close();
                }if(fw2 !=null){
                    fw2.close();
                }if(fw3 !=null){
                    fw3.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

  用法和字节流有很多相似之处

3. 字符输入缓冲流

  提供更方便的按行读取的方法:readLine() 在使用字符流读取文本文件时,我们可以使用该方法以行为单位进行读取

import java.io.BufferedReader;
import java.io.FileReader;

public class Demo01 {
    public static void main(String[] args) {
        FileReader fr = null;
        BufferedReader bfr = null;
        try {
            fr = new FileReader("C:/Users/lenovo/Desktop/ztx.txt");
            bfr = new BufferedReader(fr);
            String temp = "";
            while ((temp = bfr.readLine()) !=null){
                System.out.println(temp);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (bfr !=null)
                    bfr.close();
                if (fr !=null)
                    fr.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

4. 字符输出缓冲流

  在字符输出缓冲流中可以使用newLine();方法实现换行处理

import java.io.BufferedWriter;
import java.io.FileWriter;

public class Demo01 {
    public static void main(String[] args) {
        FileWriter fw = null;
        BufferedWriter bfw = null;
        try {
            fw = new FileWriter("C:/Users/lenovo/Desktop/ztx.txt");
            bfw = new BufferedWriter(fw);
            bfw.write("ztx你懂的,");
            bfw.write("啊对对对");
            bfw.newLine();
            bfw.write("说多了不好了");
            bfw.newLine();
            bfw.write("懂就行了");
            bfw.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (bfw !=null)
                    bfw.close();
                if (fw !=null)
                    fw.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

5. 字符流实现定义拷贝工具

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;

public class Demo01 {
    public static void main(String[] args) {
        Copy("C:/Users/lenovo/Desktop/ztx.txt","C:/Users/lenovo/Desktop/zxt.txt");
    }

    public static void Copy(String src,String des){
        FileReader fr = null;
        FileWriter fw = null;
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            fr=new FileReader(src);
            br = new BufferedReader(fr);
            fw = new FileWriter(des);
            bw = new BufferedWriter(fw);
            String temp = "";
            while ((temp= br.readLine())!=null)
            {
                bw.write(temp);
                bw.newLine();
                bw.flush();
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (br !=null){
                    br.close();
                }
                if (fr !=null){
                    fr.close();
                }
                if (bw !=null){
                    bw.close();
                }
                if (fw !=null){
                    fw.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

6.字符缓冲流为文件内容添加行号

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;


public class Demo01 {
    public static void main(String[] args) {
        BufferedReader bfr = null;
        BufferedWriter bfw = null;
        try {
          bfr = new BufferedReader(new FileReader("C:/Users/lenovo/Desktop/ztx.txt"));
          bfw = new BufferedWriter(new FileWriter("C:/Users/lenovo/Desktop/zxt.txt"));
          String temp = "";
          int i = 1;
          while ((temp = bfr.readLine()) != null){
            bfw.write(i + "," + temp);
            bfw.newLine();
            i++;
            }
          bfw.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (bfw !=null)
                    bfw.close();
                if (bfr !=null)
                    bfr.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值