0
点赞
收藏
分享

微信扫一扫

九、文件与IO流

以沫的窝 2022-02-21 阅读 70

目录

本节很多知识点会在代码中举例注释讲解

文件相关操作

代码演示

package File学习;

import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Date;

public class Demo1 {
    public static void main(String[] args) throws IOException {
        test1();
        deleteDir("test.txt");
        isContain("test");
    }
    //基础
    public static void test1() throws IOException {
        //判断文件是否存在
        File file1 = new File("D://test.txt.txt");//存在
        File file2 = new File("D://1.txt");//不存在并不会报错
        File fold1 = new File("D://ceshi");//存在
        File fold2 = new File("D://ceshi2");//不存在
        System.out.println(file1.exists());//true
        System.out.println(file2.exists());//false
        System.out.println(fold2.exists());//true
        System.out.println(fold1.exists());//false

        //file2和fold2都是不存在的,接下来我们开始创建
        //文件的创建
//        boolean f1 = file2.createNewFile();//该方法需要抛异常,返回boolean类型表示是否创建成功
        //文件夹的创建
//        boolean f2 = fold2.mkdir();//创建一层目录,如果给的是多层目录,就创建不了
//        System.out.println(f2);
        //boolean f2 = fold2.mkdirs();//创建多层目录,比如D://a//b//c,可以一次性创建三层目录
//        System.out.println(file1.delete());//删除文件,返boolean类型

        //查看文件相关信息
        System.out.println(file1.getName());//得到文件名String类型
        System.out.println(file1.length());//文件的大小long类型
        System.out.println(file1.canRead());//文件是否可读boolean类型
        System.out.println(file1.canWrite());//文件是否可写boolean类型
        System.out.println(file1.isHidden());//文件是否隐藏boolean类型
        long time = file1.lastModified();//最后修改的时间,long类型的时间可读性查,需要改一下格式
        System.out.println(new Date(time));
        System.out.println(file1.getPath());//相对路径
        System.out.println(file1.getAbsolutePath());//绝对路径
        boolean b1 = file1.isDirectory();
        boolean b2 = file1.isFile();

        File[] files = file1.listFiles();//获取文件夹下面的文件夹以及文件
        File[] files1 = fold1.listRoots();//获取所有盘符比如C:、D:
        String s = file1.getParent();//父级路径
        File f = file1.getParentFile();//父级文件夹

        //文件过滤,以fold2文件夹为例
        File[] files2 = fold2.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return name.endsWith(".java");//只找.java结尾的文件
            }
        });
        File[] files3 = fold2.listFiles((dir, name) -> (name.endsWith(".java")));//和上面一样的意思,jdk8后添加的方法
        //这两个过滤器差不多用法
        File[] files4 = fold2.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                return pathname.getName().equals("a.java");//只找这个名字的文件夹
                //.contains("b");文件名中包含b的文件
            }
        });
        File[] files5 = fold2.listFiles((pathname)->(pathname.getName().endsWith(".java")));
    }
    //传进来一个多层文件夹路径,删除该文件夹
    public static void deleteDir(String s){
        File file = new File(s);
        File[] files = file.listFiles();
        for (File f1:files){
            if (f1.isDirectory()){
//                System.out.println(f1.getAbsolutePath());
                deleteDir(f1.getAbsolutePath());
                f1.delete();
            }else {
                f1.delete();
            }
        }
        file.delete();
    }
    //传进来一个多层文件夹路径,判断该文件夹下是否有.txt结尾的文件
    public static boolean isContain(String s){
        //这里当然可以使用正则比较方面,但为了熟练一下刚学的内容,就用这种方法
        File[] files = new File(s).listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return name.endsWith(".txt");
            }
        });
        if (files.length>0){
            return true;
        }else{
            File[] files1 = new File(s).listFiles();
            System.out.println(s+"有");


            for (File f:files1){
                System.out.println("\t"+f.getName());
                if (f.isDirectory()){
                    return isContain(f.getPath());
                }
            }

        }
        return false;
    }


}

IO流

知识点

以上基本信息介绍完了,接下来以InputStream为例子详细介绍,其他的思想都一样

InputStream

代码演示

package IO流;

import java.io.*;

public class InputStreamTest {
    public static void main(String[] args) {
        test3();
    }
    //先了解一下
    public static void test1(){
//        InputStream inputStream = new FileInputStream()
        //FileInputStream()创建这个对象时,调用该构造方法,要满足构造方法的要求
        //这个构造方法方法抛出了异常,所以我们调用的时候需要处理该异常
        //当用完之后注意关闭inputStream.close()
        File file = new File("D:\\JAVASE\\src\\IO流\\test.txt");
        try {
            InputStream inputStream = new FileInputStream(file);
            /*注意:
            InputStream字节流,-一个字节-一个字节读取的。
            InputStream :如果是读取一个字节,紧接着输出到控制台,此时注意汉字,
            一个汉字如果是UTF-8占用3个字节,其他格式占用2个字节。所以按一个字节读取汉字当然会乱码
             */
            //这里以读取英文为例
            //读取一个字符,得到的是int类型的,需要转换成char类型的
            int c1 = inputStream.read();//此处抛异常
            System.out.println((char)c1);
            //读文件所有内容,读到文件末尾会返回-1
            int c;
            while ((c = inputStream.read()) != -1){
                System.out.print((char)c);
            }
            inputStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        /*
        输出:
        h
        ello1
        hello2
        hello3
         */
    }
    //打印文件中的内容(含中英文)
    public static void test2(){
        InputStream inputStream = null;
        try {
            File file = new File("D:\\JAVASE\\src\\IO流\\test.txt");
            inputStream = new FileInputStream(file);
            //inputStream.read()方法中有一种可以传进去一个字节,可以查看一下
            byte[] bytes = new byte[(int) file.length()];//文件的内容要存在这个数组中,所以做一个文件大小的数组存数据
            inputStream.read(bytes);//这样就可以把文字读出来,因为中文两个字节(utf-8是三个字符),全被按顺序记录了下来所以按顺序一起输出就能输出文字
            String s = new String(bytes);//byte类型传成String类型
            System.out.println(s);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (inputStream!=null){
                try {
                    inputStream.close();//需要抛异常
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    //接下来用的都比较少
    //截取字符
    public static void test3(){
        InputStream inputStream = null;
        try {
            File file = new File("D:\\JAVASE\\src\\IO流\\test.txt");
            inputStream = new FileInputStream(file);
            byte[] bytes = new byte[(int) file.length()];
            inputStream.read(bytes,2,4);//前面跳两个数据,然后读文件前四个字符
            //要想不从头读,就跳过几个字节inputStream.skip(n);
            String s = new String(bytes);
            System.out.println(s);
            //输出:(  hell                  )有很多空格,如果想去掉空格就输出s.trim()
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (inputStream!=null){
                try {
                    inputStream.close();//需要抛异常
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

OutputStream

知识点罗列

代码演示

package IO流;

import java.io.*;
import java.nio.charset.StandardCharsets;

public class OutputStreamTest {
    public static void main(String[] args) throws IOException {
        //test1();
        copy();
    }
    public static void test1() throws IOException {
        OutputStream outputStream = new FileOutputStream(new File("test1.txt"),true);
        /*
        没有该文件的话会新建该文件,
        后面的true如果不加,文件每次写入就会删掉之前的数据,即true表示可追加
         */
        outputStream.write('b');//可以是字符、数字会自动转换成字符也可以是byte[]类型的
        String s = "hello\n你好\n";//可以换行
        outputStream.write(s.getBytes());//字符串转成byte[]类型
        outputStream.write(s.getBytes(),2,5);//表示从第二个字符开始写入,连续写5个字符
        //截取字符时要注意,一个中文utf-8的格式下是3个字节,如果你截取的字节数把一个文字分开了,那么会把文件里面的内容文字全都弄成乱码
        //因为本来一个文字需要三个字节,但你只写入了文字中的一个字节,那么这个字节就可能回和其他字节组合,导致中文全部乱码
        //所以我们这为例,从(跳过两个)第三个字节开始截取,截取5个字节就是 l l o \n 你(的第一个字节)
        //没错这结果会是乱码,所以截取2,7是可以的,2,10也是可以的
    }
    //这些明白之后就可以实现文件的复制了
    //因为流是以字节的形式保存的,所以图片,视频...都是可以复制的
    //这里以图片为例
    public static void copy() throws IOException {
        FileOutputStream fileOutputStream = null;
        FileInputStream fileInputStream = null;
        try{
            File file = new File("1.jpg");
            fileInputStream = new FileInputStream(file);
            fileOutputStream = new FileOutputStream("copy.jpg");
            byte[] bytes = new byte[(int) file.length()];
            fileInputStream.read(bytes);
            fileOutputStream.write(bytes);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (fileOutputStream!=null){
                fileOutputStream.close();
            }
            if (fileInputStream!=null){
                fileInputStream.close();
            }
        }
    }

}

Reader

知识点罗列

代码演示

package IO流;

import java.io.*;
import java.util.Arrays;

public class ReaderTest {
    public static void main(String[] args) {
        test03();
    }

    /*
    前面说过Input是按字节读,Reader是按字符读,
    那么我们就可以把Input用Reader打包一下,就可以按字符读了,这样中文也是可以一个一个读的
     */
    public  static void test01(){
        InputStream inputStream = null;
        Reader reader = null;
        try {
            inputStream = new FileInputStream("D:/test.txt");
            reader = new InputStreamReader(inputStream);//把字节流打包
            int c;
            while((c=reader.read())!=-1){//Reader读到的内容可以直接保存在char类型中,中文也是可以读的
                System.out.print((char)c);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //这里关的话,也得按顺序,很容易理解
            try {
                if(null!=reader){
                    reader.close();
                }
                if(null!=inputStream){
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    //读整篇文件
    public  static void test02(){
        InputStream inputStream = null;
        Reader reader = null;
        try {
            File file = new File("D:/test.txt");
            inputStream = new FileInputStream(file);
            reader = new InputStreamReader(inputStream);
            char[] cs = new char[(int)file.length()];//因为文件的长度是按字节来算的,所以这里用这个长度当然是给大了
            //比如一个中文,按字节算可能是3或者是2,但是按字符来算就只占一个字符
            reader.read(cs);
            String s = new String(cs);
            System.out.println(s.trim());//这样读出来含有很多空格,用trim()方法,去掉前后空格
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if(null!=reader){
                    reader.close();
                }
                if(null!=inputStream){
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    /*
    如果每次都打包字节流就很麻烦,所以当然可以直接使用字符流
     */
    public  static  void test03(){
        InputStreamReader reader = null;
        try {
            reader = new FileReader("D:/test.txt");
            int c ;
            while ((c=reader.read())!=-1){
                System.out.print((char)c);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if(null!=reader){
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

Writer

知识点罗列

代码演示

package IO流;

import java.io.*;

public class WriterTest {
    public static void main(String[] args) {
        test01();
    }
    //道理都一样这里就不讲太多了,就讲一下常用
    public  static  void  test01(){
        OutputStream out = null;
        Writer writer = null;
        try {
            out = new FileOutputStream("D:/out2.txt");
            writer = new OutputStreamWriter(out);
            writer.write("hello,world.你好!");
            writer.flush();//文件写完之后,里面内容还是没有的,需要手动刷新一下,才会到文件中,即用这个方法
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if(null!=out){
                    out.close();
                }
                if(null!=writer){
                    writer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

缓冲流

代码演示

字节流

package IO流;

import java.io.*;

public class BufferedStreamTest {
    public static void main(String[] args) {
        test01();
    }
    //缓冲流进行文件复制
    public static  void test01(){
        //字节缓冲流
        InputStream inputStream = null;
        BufferedInputStream bufferedInputStream = null;
        OutputStream outputStream = null;
        BufferedOutputStream bufferedOutputStream = null;
        try {
            inputStream = new FileInputStream("D:/test.txt");
            bufferedInputStream = new BufferedInputStream(inputStream);
            outputStream = new FileOutputStream("D:/test_01.txt");
            bufferedOutputStream = new BufferedOutputStream(outputStream);
            int i ;
            while ((i=bufferedInputStream.read())!=-1){
                bufferedOutputStream.write(i);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if(null!=bufferedOutputStream){
                    bufferedOutputStream.close();
                }
                if(null!=outputStream){
                    outputStream.close();
                }
                if(null!=bufferedInputStream){
                    bufferedInputStream.close();
                }
                if(null!=inputStream){
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

字符流

package IO流;

import java.io.*;

public class BufferedTest {
    public static void main(String[] args) {
        test01();
    }
    /**
     * 字符缓缓冲流
     */
    public static  void test01(){
        //
        Reader reader =null;
        BufferedReader bufReader  =null;
        Writer writer = null;
        BufferedWriter bufWriter = null;
        try {
            reader = new FileReader("D:/test.txt");
            bufReader = new BufferedReader(reader);
            writer = new FileWriter("D:/test03.txt");
            bufWriter = new BufferedWriter(writer);
            String s ;
            while ((s=bufReader.readLine())!=null){//读一行
               // System.out.println(s);
                bufWriter.write(s);
                bufWriter.newLine();//换行
            }

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if(null!=bufWriter){
                    bufWriter.close();
                }
                if(null!=writer){
                    writer.close();
                }

                if(null!=bufReader){
                    bufReader.close();
                }
                if(null!=reader){
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

转换流

代码演示

package IO流;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class StreamReaderTest {
    public static void main(String[] args) {
        try {
            InputStream in = new FileInputStream("D:/test.txt");
            InputStreamReader reader = new InputStreamReader(in);
            int c ;
            while((c=reader.read())!=-1){
                System.out.print((char)c);
            }
            reader.close();
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

标准输入输出流

package IO流;

import java.io.*;

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

    }

    public static  void test02(){
        try {
            FileOutputStream outputStream = new FileOutputStream("D:/out.txt");
            //接下来两句就是对输出进行修改
            PrintStream printStream = new PrintStream(outputStream);
            System.setOut(printStream);//对System.out.println进行修改为输出在指定位置

             for(int i=0;i<26;i++){
                 System.out.println((char)(97+i));
             }
            printStream.close();
            outputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
/*
* */
    public  static  void test01(){
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));//从键盘读取数据到字节流
        String s ;
        try {
            while((s=reader.readLine())!=null){
                if(s.equals("e")||s.equals("exit")){
                    break;
                }
                System.out.println("---->"+(char)(s.charAt(0)-32));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //用户输入信息,将这个信息输出到文件中,并将大写转为小写,将小写转换为大写
    //用户输入的内容直接输出到文件中。System.out.println();
    public  static  void test03(){
        System.out.println("清输入信息,按0结束");
       InputStream inputStream = System.in;//键盘读取数据到字节流
        int s ;
        try {
            while((s=inputStream.read())!=-1){
                if(s==48){//指定退出字符0为退出
                    break;
                }
               if(s!=10){//回车也算一个字符,但我们不需要回车,所以不为回车时输出
                   System.out.println(s);
               }
               // System.out.println("---->"+(char)(s-32));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

对象流

代码演示

先做一个类

package IO流;

import java.io.Serializable;

public class Person implements Serializable {
    //要想实现序列化必须要继承这个接口

    private static final long serialVersionUID = -5981579002159173783L;
    //这个序列化的ID如果不加的话,反序列化时,当原来的类改变时,就会报错
    private int pid;
    private  String pName;
    private  String pSex;
    private  transient int page;
    /*
    瞬态关键字transient static
    当对象的某个属性被transient修饰,或者静态属性,那么不会被序列化,比如这个地方的page,即使之前复制,然后序列化、反序列化得到的这个属性为0
    */
    private  int score;

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }

    public int getPid() {
        return pid;
    }

    public void setPid(int pid) {
        this.pid = pid;
    }

    public String getpName() {
        return pName;
    }

    public void setpName(String pName) {
        this.pName = pName;
    }

    public String getpSex() {
        return pSex;
    }

    public void setpSex(String pSex) {
        this.pSex = pSex;
    }

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    public Person() {
    }


}

接下来实现序列化与反序列化

package IO流;

import java.io.*;

public class PersonTest {
    public static void main(String[] args) {
        test02();
    }
    //进行序列化
    public static  void test01(){
        //对象序列化
        Person person = new Person();
        person.setPid(1001);
        person.setPage(20);
        person.setpName("jerry");
        person.setpSex("男");

        try {
            ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("D:/person.txt"));
            //把对象保存在这个文件中,保存的信息我们看不懂,但反序列化时可以实现
            out.writeObject(person);
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //反序列 江文件中的内容转换为对象
    public static  void test02(){
        try {
            //接下来四步就是反序列化
            ObjectInput in = new ObjectInputStream(new FileInputStream("D:/person.txt"));
            Object obj =  in.readObject();
            System.out.println(obj);
            Person p =  (Person) obj;

            System.out.println(p.getPid()+"\t"+p.getpName()+"\t"+p.getpSex()+"\t"+p.getPage());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
举报

相关推荐

IO 流——文件

IO流分割文件

IO流(读写文件)

C++文件IO流

IO流复制文件(单级文件)

IO_节点流与处理流

0 条评论