文件IO上.md

1、 File 类

表示文件和目录路径名的抽象表示形式

File 类可以实现文件的创建、删除、重命名、得到路径、创建时间, 是唯一与文件本身有关的操作类

无法删除非空文件夹

路径分隔可以使用 “/” “\”

public static final String separator表示路径分隔符 “”
public File(String pathname)构造File 类实例, 要传入路径
public boolean createNewFile()创建新文件
public boolean delete()删除文件
public class FileDemo {
    public static void main(String[] args) {
        File fi = new File("1.txt");
        System.out.println("是否存在1.txt "+ fi.exists());
        if (!fi.exists()) {
            try {
                fi.createNewFile();
                System.out.println("文件创建成功");
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        System.out.println("是否为文件夹 "+fi.isDirectory());
        System.out.println("文件大小 "+fi.length());
        System.out.println("文件的绝对路径 "+fi.getAbsolutePath());
        System.out.println("删除文件 "+fi.delete());

        File f2 = new File("array");
        File[] names = f2.listFiles();
        System.out.println("array 文件夹下的文件 "+Arrays.toString(names));

        File f4 = new File("temp");
        f4.mkdir();
        // 重命名和移动文件
        f4.renameTo(new File("tempp"));
        System.out.println("删除文件夹 "+new File("tempp").delete());
        System.out.println("删除文件夹 "+f4.delete());
        File f5 = new File("F:\\Algorithm");
//        File[] files = f5.listFiles(new FileFilter() {
//            @Override
//            public boolean accept(File pathname) {
//                return pathname.getName().endsWith(".txt");
//            }
//        });

        File[] files = f5.listFiles((pathname)->pathname.getName().endsWith("y"));
        for (File f : files) {
            System.out.println("以y结尾的文件 "+f.getName());
        }



    }

查找文件

public class findFileDemo {

    public static void main(String[] args){
        findFile(new File("F:\\"),".pdf");
    }

    private static void findFile(File target, String ext){
        if(target == null) return;
        //如果文件是目录
        if(target.isDirectory()){
            File[] files = target.listFiles();
            if(files!=null){
                for(File f: files){
                    findFile(f,ext); // 递归调用
                }
            }
        }else{ // 如果File 是一个文件
            String name = target.getName().toLowerCase();
            if(name.endsWith(ext)){
                System.out.println(target.getAbsolutePath());
            }

        }
    }
}

2、 字节流

以字节为单位

流是一组有顺序的,有起点和重点的字节集合,是对数据传输的总称或抽象,即数据在两设备间的传输称为流

流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作

根据处理数据类型的不同分为:字符流和字节流。 根据数据流向不同分为:输入流和输出流

public abstrat class OutputStream extends Object implements Closeable, Flushable

public abstract vlass InputStream extends Object implements Closeable

输出流:超类OutputStream, 对文件的输出流使用子类FileOutputStream

输入流 超类InputStream, 对文件的输入流使用子类FileOutputStream

原理:

每次只会操作一个字符,(从我呢见中读取或写入)

public class ByteStreamDemo {
    private static void out() throws IOException {
        File file = new File("1.txt");
        file.createNewFile();
        OutputStream out = new FileOutputStream(file, true); // append 为true 表示追加内容
        String info = "hahalal辣豆腐\r\n";
        String line = System.getProperty("line.separator");
        info += line;
        out.write(info.getBytes());
        out.close();
    }

    private static void in() throws IOException {
        File file = new File("1.txt");
        InputStream in = new FileInputStream(file);
        byte[] bytes = new byte[1024];   // 每次读取的字节长度,1兆
        StringBuilder buf = new StringBuilder();
        int len = -1; // 把数据读到数组中,并返回读取的字节数,当不等-1时,表示读取到数据,等于-1表示文件已经读完了
        while ((len = in.read(bytes)) != -1) {
            buf.append(new String(bytes,0,len));
        }

        in.close();
        System.out.println(buf);
        file.delete();
    }

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

        in();
    }


}

3、字符流

以字符为单位

writer

写入字符流的抽象类。子类必须实现的方法仅有write(char[], int, int)\ flush() 和 close() 但是多数子类将重写此处定义的一些方法,以提供更高的效率或其他功能

与OutputStream 一样,对文件的操作使用: FileWriter 类完成

Reader

用于读取字符流的抽象类,子类必须实现的方法只有read(char[]. int, int) 和close() , 但是大多数子类将重写此处定义的一些方法,以提供更高的效率或其他功能, 使用FileReader 类进行实例化操作

public class CharStreamDemo {
    // 文件字符操作流会自带缓存,默认大小为1024,在缓存满后,或手动刷新缓存,或关闭流会把数据写入文件
    private static void out() throws IOException {
        File file = new File("1.txt");
        Writer out = new FileWriter(file,true);
        out.write("村花到我家\n");
        out.close();//   有一个writeBuffer 数组,缓存超过1KB 或者close 后才会写入到文件中
    }

    public static  void in() throws IOException {
        File file = new File("1.txt");
        Reader in = new FileReader(file);
        char[] cs = new char[1];
        int len = -1;
        StringBuilder buf = new StringBuilder();
        while((len = in.read(cs))!= -1){
            buf.append(new String(cs,0,len));

        }
        in.close();
        System.out.println(buf);
    }
    public static void main(String[] args) throws IOException {
        out();
        in();
    }

}

字节流与字符流的区别

在所有的流操作里,字节永远是最基础的。任何基于字节的操作都是正确的,无论你是文本文件还是二进制的文件。如果确认流里面只有可打印的字符,包括英文的和各种国家的汉字,也包括中文,那么可以考虑使用字符流。由于编码不同,多字节的字符可能占用多个字节。比如GBK的汉字就占用2个字节,而UTF-8的汉字就占用3个字节。所以,字符流是根据指定的编码,将1个或多个字节转化为java里面的unicode 字符,然后进行操作,字符操作一般使用Writer , Reader, 字节操作一般是InputStream, OutputStream, 以及各种包装类, 如BufferedInputStream 和 BufferedOutputStream

总结: 如果要处理的流是可以印的字符,那么使用字符流更简单一点,如果不确定使用字节流不会出错

复制文件

public class CopyFileDemo {
    public static void main(String[] args) {
        System.out.println("start");
        long start = System.currentTimeMillis();
        copy("F:\\千峰java\\千锋java基础教程:第08章 文件与IO\\第08章 文件与IO_01_File类的使用.mp4", "F:\\第08章 文件与IO_01_File类的使用.mp4");
        System.out.println("end");
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }

    private static void copy(String src, String target) {
        File srcFile = new File(src);
        File targetFile = new File(target);
        InputStream in = null;
        OutputStream out = null;

        try {
            in = new FileInputStream(srcFile);
            out = new FileOutputStream(targetFile);
            byte[] bytes = new byte[1024];
            int len = -1;
            while ((len = in.read(bytes)) != -1) {
                out.write(bytes, 0, len);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (in != null) in.close();
                if (out != null) out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

4、 字节字符转换流

可以将一个字节流转换为字符流,也可以将一个字符流转换为字节流

字节流:FileOutputStream FileInputStream 字符流: FileWriter FileReader

OutputStreamWriter: 将输出的字符流转化为字节流的输出形式

InputStreamReader: 将输入的字节流转换为字符流输入形式

输入: 文件 —> InputStream —> InputStreamReader —> 程序

输出: 文件 <— OutputStream <— OutputStreamWriter <— 程序

public class ChangeStreamDemo {
    // 读入到程序,将字节流转换为字符流,操作更方便
    private static void read(InputStream in){
        Reader reader = new InputStreamReader(in, Charset.forName("utf-8"));
        char[] cs = new char[1024];
        int len = -1;
        try {
            while ((len = reader.read(cs)) != -1) {
                System.out.println(new String(cs, 0, len));
            }
            reader.close();
        }catch(Exception e ){
            e.printStackTrace();
        }
    }
// 输出到文件, 将字符流变为字节流
    public static void write(OutputStream out) throws IOException {
        Writer writer = new OutputStreamWriter(out, Charset.defaultCharset());
        writer.write("开开心心来玩耍");

    }

    public static void main(String[] args) throws IOException {
        InputStream in = new FileInputStream("1.txt");
        read(in);

        OutputStream out = new FileOutputStream("1.txt");
        write(out);
    }


}

5、 缓冲流

对文件或其他目标频繁的读写操作,效率低,性能差

使用缓冲流的好处是:能够更高效的读写信息,原理是将数据先缓存起来,然后一起写入或者读取出来

BufferedInputStream: 为另一个输入流添加一些功能,在创建BufferedInputStream 时, 会创建一个内部缓冲区数组,用于缓冲数据

最大的缓存大小是Integer.MAX_VALUE - 8

BufferedOutputStream: 通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必针对每次字节写入调用底层系统

内部默认的缓存大小是8KB, 每次写入时缓存到缓存中的byte数组中,当数组存满时,会把数组中的数据写入文件,并把缓存下标归零

BufferedReader: 从字符输入流中读取文本, 缓冲各个字符,从而实现字符、数组和行的高效读取

BufferedWriter : 将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入

public class BufferStreamDemo {
    private static void byteWriter() throws IOException {  // 缓存 8KB
        File file = new File("1.txt");
        OutputStream out = new FileOutputStream(file,true);
        BufferedOutputStream bos = new BufferedOutputStream(out);
        bos.write("你好呀\n".getBytes());
        bos.close(); // flush 方法就是刷新用的
    }

    private static void byteReader() throws IOException {  // 缓存很大
        File file = new File("1.txt");
        InputStream in = new FileInputStream(file);
        BufferedInputStream bis = new BufferedInputStream(in);
        byte[] bytes = new byte[1024];
        int len = -1;
        while((len = bis.read(bytes))!= -1){
            System.out.println(new String(bytes,0,len));
        }
        bis.close();
    }
    public static void main(String[] args) throws IOException {
        byteWriter();
        System.out.println();
        byteReader();
    }
}

字符流

  1. 加入字符缓冲流,增强读取功能(readLine)
  2. 更高效的读取数据

FileReader: 内部使用InputStreamReader (sub.nio.cs.StreamDecoder), 解码过程, byte —> char, 默认缓存大小是8K

BufferedReader: 默认缓存大小是8K, 但可以手动指定缓冲大小,把数据读取到缓存中, 减少每次转换过程,效率更高

BufferedWriter: 同上

6、 打印流

更方便的进行输出, 再字节输出时,可以泽强输出功能

字节打印流: PrintStream

字符打印流: printWriter

public class PrintStreamDemo {
    private static void charPrint() throws IOException {
        File file = new File("2.txt");
        Writer out = new FileWriter(file);
        // 加缓存
        BufferedWriter bos = new BufferedWriter(out);
        // 增强打印功能
        PrintWriter ps = new PrintWriter(bos);
        ps.println("打印");
        ps.close();
    }
    private static void bytePrint() throws FileNotFoundException {
        File file = new File("2.txt");
        OutputStream out = new FileOutputStream(file);
        // 加缓存
        BufferedOutputStream bos = new BufferedOutputStream(out);
        // 增强打印功能
        PrintStream ps = new PrintStream(bos);
        ps.println("打印");
        ps.close();
    }

    public static void main(String[] args) throws FileNotFoundException {
        bytePrint();
    }
}

7、 对象流

对象流的两个类:

ObjectOutputStream 将Java 对象的基本数据类型和图形写入OutputStream

ObjectInputStream 对以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化

什么时候需要序列化

  1. 把对象存储在物理介质上
  2. 对象需要在网络上传输

序列化一组对象

如果一个类需要被序列化,那么该类必须实现Serializable 接口, 是一个标记接口,没有任何定义,只是为了告诉Jvm 该类对象可以被序列化。

在序列化操作中,同时序列化多个对象时,反序列化也必须按顺序操作,如果想要序列化一组对象:

序列化一组对象可采取:对象数组的形式,因为对象数组可以向Object进行转型操作。

transient 关键字:

如果用transient 声明一个实例变量: 当对象存储时,它的值不需要维持,所声明的字段无法序列化(被忽略掉)

public class ObjectStreamDemo {
    public static void writeObject() throws IOException {
        Dog dog = new Dog("大王");
        File file = new File("dog.obj");
        OutputStream out = new FileOutputStream(file);
        ObjectOutputStream oos = new ObjectOutputStream(out);
        oos.writeObject(dog);


    }

    public static void readObject() throws IOException, ClassNotFoundException {
        File file = new File("dog.obj");
        InputStream in = new FileInputStream(file);
        ObjectInputStream ois = new ObjectInputStream(in);
        Dog dog = (Dog) ois.readObject();
        ois.close();
        System.out.println(dog);

    }

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        writeObject();
        readObject();

    }
}

我们直到在Java中,对象的序列化可以通过实现两种接口来实现,若实现的是Serializable 接口,则所有的序列化将会自动进行,若实现的是Externalizable 接口,则没有任何东西可以自动序列化,需要在writeExternal 方法中进行手工指定所要序列化的变量,这与是否被transient修饰无关,

8、 字节数组流

ByteArrayInputStream

包含一个内部缓冲区,该缓冲区包含从流中读取的字节。内部计数器跟踪read方法要提供的下一个字节。关闭ByteArrayInputStream 无效,此类方法在关闭流后仍可被调用,而不会产生任何IOException

ByteArrayOutputStream

此类实现了一个输出流,其中的数据被写入一个byte 数组。 缓冲区随着数据不断写入而自动增长。可使用toByteArray() 和 toString() 获取数据。 关闭ByteArrayOutputStream 无效, 此类方法在关闭此流后仍可被调用,而不会产生任何IOException

// 内部维护着一个字节数组,可以利用流的读取机制来处理字符串
// 基于内存的, 不需要关闭, 和文件也没有关系
public class ByteArrayStreamDemo {
    private static void byteArray(){
        String s = "12345667890;'./dDF";
        ByteArrayInputStream bais = new ByteArrayInputStream(s.getBytes());
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int curr = -1; // 每次读取的字节
        while((curr = bais.read()) != -1){
            if((curr >=65 && curr <= 90) || (curr >= 97 && curr <= 122)){
                baos.write(curr);
            }

        }
        System.out.println(baos.toString());

    }
    public static void main(String [] args){
        byteArray();
    }
}
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值