#Java IO流

文件

保存数据的地方

文件流

文件在程序中是以流的形式来操作的
流:数据在数据源(文件)和程序(内存)之间经历的路径
输入流:文件->内存
输出流:内存->文件


常用的文件操作

创建文件的三个方法

image.png

方式1

//方式1
    @Test
    public void create01(){
        String filepath = "d:\\create01.txt";//也可以d:/create01.txt
        File file = new File(filepath);
        try {
            file.createNewFile();
            System.out.println("创建文件成功!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

方式2

 //方式2
    @Test
    public void create02(){
        File parentFile = new File("d:\\");
        String fileName = "create02.txt";
        File file = new File(parentFile, fileName);
        try {
            file.createNewFile();
            System.out.println("创建文件成功!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

方式3

//方式3
    @Test
    public void create03(){
        String parentPath = "d:\\";
        String fileName = "create03.txt";
        File file = new File(parentPath, fileName);
        try {
            file.createNewFile();
            System.out.println("创建文件成功!");
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

补充:
1.想直接执行某个方法,可以不用在main方法里创建对象再调用,可以在方法上一行加上@Test
(单元测试)



导入成功

2.创建文件路径的两个不同写法

"d:\\create01.txt"
"d:/create01.txt"

总结:
1.方式1和方式3很像,只不过方式3把路径和文件名分开写了,而方式2需要创建一个父目录路径对象
2.直接写 file.createNewFile();会报错,需要try-catch

获取文件的信息


1.先创建文件对象

File file = new File("e:\\create01.txt");

2.调用方法即可



方法什么意思看方法名就知道了,这里略过

目录操作和文件删除

删除文件

1.创建文件对象

File file = new File("e:\\create01.txt");

2.调用delete方法

 @Test
    public void delete(){
        File file = new File("d:\\create01.txt");
        if(file.exists()){//先判断文件存不存在
            if(file.delete()){
                System.out.println("文件删除成功");
            }else {
                System.out.println("文件删除失败");
            }
        }else {
            System.out.println("文件不存在");
        }
    }

删除目录

(目录在java编程中也被当成文件)
1.创建文件对象

File file = new File("e:\\demo01");

2.调用delete方法

 @Test
    public void delete(){
        File file = new File("d:\\demo01");
        if(file.exists()){//先判断目录存不存在
            if(file.delete()){
                System.out.println("目录删除成功");
            }else {
                System.out.println("目录删除失败");
            }
        }else {
            System.out.println("目录不存在");
        }
    }

创建多级目录

 @Test
    public void create01(){
        File file = new File("d:\\a\\b\\c");
        if(file.exists()){
            System.out.println("目录存在");
        }else {
            if(file.mkdirs()){//创建多级目录,创建一级目录用mkdirs即可
                System.out.println("创建成功");
            }else{
                System.out.println("创建失败");
            }
        }
    }

IO流分类

按流向分类:输入流,输出流
按操作的数据单位:字符流(用于文本文件(有中文,英文...)),字节流(二进制文件)

可以得到4个不同的操作

InputStream//字节输入流
OutputStream//字节输出流
Reader//字符输入流
Writer//字符输出流

这4个都是抽象基类,IO流大部分类都是这4个类派生出来的

InputStream(字节输入流)

主要有3个常用子类

1.FileInputStream文件输入流
2.BufferedInputStream缓冲字节输入流
3.ObjectInputStream对象输入流

1.FileInputStream

  @Test
    public void readFile01(){
        String filePath = "d:\\hello.txt";
        int readData = 0;
        FileInputStream fileInputStream = null;

        try {
            //创建FileInputStream对象,用于读取文件
            fileInputStream = new FileInputStream(filePath);
            //read方法:从该输入流中读取一个字节的数据,如果没有输入可用,该方法将会被阻止
            //如果返回-1,表示读取完毕
            while ((readData = fileInputStream.read()) != -1){
                System.out.print((char)readData);//读的是int类型,强转成char才能显示

            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭文件流
            try {
                fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
            }
        }
    }

详解:

1.创建fileInputStream 对象的时候,会报一次异常



相关解释:

说明某个方法在方法声明上已经声明了会抛异常,那么在调用这个方法的时候,就必须做异常处理,处理的方式有2种,要么try-catch这个异常,要么继续往上一层抛出这个异常,这是java语法要求的,必须这么做

所以我们try-catch一下就好了
2.read方法



我们可以看到int是类型,所以我们要定义一个int类型来接他的返回值

int readData = 0;
readData = fileInputStream.read()

此时又会报一个异常



根据前面异常那一章,我们可以把catch里的FileNotFoundException换成更高一级的异常IOException,这样就不会报错了
3.因为要输出字符,所以把readData强转成char类型

 System.out.print((char)readData);

然后用while循环不停的从文件读取内容即可
4.最后我们要在finally用对象名.close()关闭这个流,避免浪费
会发现


这是因为我们的对象fileInputStream是在try语句内创建的,他的作用域只在try里,我们只要在try外创建对象,然后分别在try和finally里使用就好了
此时又会报错,再try-catch一下就好了
最终结果

优化读取效率
换一个方法

read(byte[] b)
@Test
    public void readFile02() {
        String filePath = "d:\\hello.txt";
        FileInputStream fileInputStream = null;
        int readLen = 0;
        //字符数组,一次读取8个字符
        byte[] buf = new byte[8];
        try {
            fileInputStream = new FileInputStream(filePath);
            while((readLen = fileInputStream.read(buf)) != -1) {
                System.out.println(new String(buf, 0, readLen));
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
            }
        }

    }

补充:这里的new String方法是把数组转成字符串

2.FileOutputStream

配对着讲了,输入对输出
其实大致差不多,就改一些细节位置


write的三个方法
  • write第一个方法,输出一个字节
@Test
    public void writeFile01(){
        String filePath = "D:\\test.txt";
        //创建FileOutputStream对象
        FileOutputStream fileOutputStream = null;

        try {
            fileOutputStream = new FileOutputStream(filePath);
            fileOutputStream.write('x');

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
  • write第二个方法 输入一整个字节数组
@Test
    public void writeFile01(){
        String filePath = "D:\\test.txt";
        //创建FileOutputStream对象
        FileOutputStream fileOutputStream = null;
        String str = "hello, my world!";
        try {
            fileOutputStream = new FileOutputStream(filePath);
            fileOutputStream.write(str.getBytes());

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

补充:getBytes()方法把字符串->字节数组

  • write第三个方法 输入指定长度的字节数组
  @Test
    public void writeFile01(){
        String filePath = "D:\\test.txt";
        //创建FileOutputStream对象
        FileOutputStream fileOutputStream = null;
        String str = "hello, my world!";
        try {
            fileOutputStream = new FileOutputStream(filePath);
            fileOutputStream.write(str.getBytes(),0 ,3);//off是开头位置,len是输出长度

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

如果每次输入不想覆盖原来的,那就在改为

fileOutputStream = new FileOutputStream(filePath, true);

小练习--实现复制黏贴

public class FileCopy {
    public static void main(String[] args) {
        //创建地址
        String oriFilePath = "d:\\3.mp4";
        String desFilePath = "d:\\4.mp4";
        //创建输入输出流对象
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;
        //创建储存字节数组
        byte[] buf = new byte[1024];
        int readLen = 0;
        try {
            //读取地址
            fileInputStream = new FileInputStream(oriFilePath);
            fileOutputStream = new FileOutputStream(desFilePath);
            while((readLen = fileInputStream.read(buf)) != -1){
                //这里用 fileOutputStream.write(buf, 0, readLen)都可以,都是一边输入一边输出
                fileOutputStream.write(buf);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileInputStream.close();
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

补充:关于 fileOutputStream.write();用哪一个write方法,韩顺平老师推荐的是用fileOutputStream.write(buf, 0, readLen)方法,但我两个方法都试过好几次了,并没有出现打不开的情况,所以我觉得都应该是没问题的

字符IO流

相比于字节流,字符流是按字符读取数据,所以可以拷贝中文了

1.FileReader

练习--读取一个含有中文的文档

public class FileReaderTest {
    public static void main(String[] args) {
        //创建地址
        String filePath = "d:\\test.txt";
        //创建文件对象
        FileReader fileReader = null;
        //创建容量为8的字符数组
        char[] arr = new char[8];
        int readLen = 0;

        try {
            fileReader = new FileReader(filePath);//读取地址
            //读取到文件末尾返回-1,停止读取
            while((readLen = fileReader.read(arr)) != -1){
                System.out.print(new String(arr, 0, readLen));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

}

补充:
1.创建java文档时候别起和类相同的名字,避免遇到不必要的麻烦
2.读取txt文档没问题,但读取其他格式的文档会乱码如docx

2.FileWriter

练习--写入一段话到文档中

public class FileWriterTest {
    public static void main(String[] args) {
        //创建地址
        String filePath = "d:\\test.txt";
        //创建FileWriter对象
        FileWriter fileWriter = null;
        String info = "英特纳雄耐尔,就一定要实现";

        try {
            fileWriter = new FileWriter(filePath,true);
            fileWriter.write(info);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

}

总结

感觉JavaIO流都差不多,掌握格式然后注意方法的用法就行了,可能是我学的不精吧哈哈,剩下的以后再补,去学多线程了

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • java IO流学习总结 近期学习了Java的IO流,尝试着总结一下。 java.io 包下的IO流很多: 其中,...
    java萌新小白阅读 683评论 0 0
  • 标准输入输出,文件的操作,网络上的数据流,字符串流,对象流,zip文件流等等,java中将输入输出抽象称为流,就好...
    navy_legend阅读 801评论 0 0
  • 一、IO流 Java中I/O操作主要是指使用java.io包下的内容,进行输入、输出操作。输入、输出是相对于内存来...
    XAbo阅读 115评论 0 0
  • 1.流的分类 (1)输入输出流输入输出是针对程序运行的内存而言的输入流的基类:InputStream,Reader...
    ql2012jz阅读 623评论 0 3
  • 16宿命:用概率思维提高你的胜算 以前的我是风险厌恶者,不喜欢去冒险,但是人生放弃了冒险,也就放弃了无数的可能。 ...
    yichen大刀阅读 8,024评论 0 4

友情链接更多精彩内容