Java IO流

简介: Java IO流

一、File类的使用File类的使用

  java.io.File 类: 文件和文件目录路径 的抽象表示形式,与平台无关

  File 能新建、删除、重命名文件和目录,但 File 不能访问文件内容本身。

如果需要访问文件内容本身,则需要使用输入 / 输出流。

想要在 Java 程序中表示一个真实存在的文件或目录,那么必须有一个 File

象,但是 Java 程序中的一个 File 对象,可能没有一个真实存在的文件或目录。

  File 对象可以作为参数传递给流的构造器

File类常用构造器:

public File(String pathname)

pathname 为路径创建 File 对象,可以是 绝对路径或者相对路径 ,如果

pathname 是相对路径,则默认的当前路径在系统属性 user.dir 中存储。

绝对路径:是一个固定的路径 , 从盘符开始

相对路径:是相对于某个位置开始

public File(String parent,String child)

parent 为父路径, child 为子路径创建 File 对象。

public File(File parent,String child)

根据一个父 File 对象和子文件路径创建 File 对象

File类的获取功能

public String getAbsolutePath() 获取绝对路径

public String getPath() :获取路径

public String getName() :获取名称

public String getParent() 获取上层文件目录路径。若无,返回 null

 public long length() :获取文件长度(即:字节数)。不能获取目录的长度。

 public long lastModified() :获取最后一次的修改时间,毫秒值

 public String[] list() :获取指定目录下的所有文件或者文件目录的名称数组

 public File[] listFiles() :获取指定目录下的所有文件或者文件目录的 File 数组

File类的重命名功能

public boolean renameTo(File dest): 把文件重命名为指定的文件路径

File类的判断功能

public boolean isDirectory() 判断是否是文件目录

 public boolean isFile() : 判断是否是文件

 public boolean exists() :判断是否存在

 public boolean canRead() :判断是否可读

public boolean canWrite() :判断是否可写

public boolean isHidden() :判断是否隐藏

File类的创建功能

 public boolean createNewFile()  创建文件。若文件存在,则不创建,返回 false

public boolean mkdir() :创建文件目录。如果此文件目录存在,就不创建了。

如果此文件目录的上层目录不存在,也不创建。

 public boolean mkdirs() : 创建文件目录。如果上层文件目录不存在,一并创建

注意事项:如果你创建文件或者文件目录没有写盘符路径,那么,默认在项目

路径下。

File类的删除功能

public boolean delete() 删除文件或者文件夹

删除注意事项:

Java 中的删除不走 回收站

要删除一个文件目录,请注意该文件目录内不能包含文件或者文件目录

练习

1. 利用 File 构造器, new 一个文件目录 file

1) 在其中创建多个文件和目录

2) 编写方法,实现删除 file 中指定文件的操作

 @Test
    /**
     * 1. 利用File构造器,new 一个文件目录file
     * 1)在其中创建多个文件和目录
     * 2)编写方法,实现删除file中指定文件的操作
     */
    public void test1() throws IOException {
        File file = new File("d:/File","file");
        if(file.createNewFile()){
            System.out.println("文件目录创建成功!");
        }
        File file1 = new File("d:/file/Smile.txt");
        if(file1.createNewFile()){
            System.out.println("子文件创建成功!");
        }
        File dir=new File("d:/file/dir");
        if(dir.mkdir()){
            System.out.println("子文件目录创建成功!");
        }
        deleteFile(dir);
        deleteFile(file);
        deleteFile(file1);
    }
    public void deleteFile(File file){
        if(file.delete()){
            System.out.println("文件删除成功!");
        }
    }

2. 判断指定目录下是否有后缀名为 .jpg 的文件,如果有,就输出该文件名称

public void test2(){
        File file = new File("d:");
        judgeJpg(file);
 
    }
    public void judgeJpg(File file){
        String[] strings=file.list();
        for (int i = 0; i <strings.length ; i++) {
            if(strings[i].endsWith(".jpg")){
                System.out.println(strings[i]);
            }
        }
    }

3. 遍历指定目录所有文件名称,包括子文件目录中的文件。

@Test
    /**
     * 遍历指定目录所有文件名称,包括子文件目录中的文件。
     */
    public void test3(){
        File file = new File("c:");
        String[] strings=file.list();
        for (String str:strings) {
            System.out.println(str);
        }
    }

拓展 1 :并计算指定目录占用空间的大小

 @Test
    /**
     * 遍历指定目录所有文件名称,包括子文件目录中的文件。
     * 并计算指定目录占用空间的大小
     */
    public void test3(){
        File file = new File("c:");
        String[] strings=file.list();
        File[] files=file.listFiles();
        int sum=0;
        for (String str:strings) {
            System.out.println(str);
        }
        for (File file1:files) {
            sum+=file1.length();
        }
        System.out.println(sum);
    }

拓展 2 :删除指定文件目录及其下的所有文件

public void deleteAll(File file){
        if(file==null||!file.exists()){
            System.out.println("文件路径输入有误!");
        }else{
            File[] files = file.listFiles();
            //遍历该目录下的文件对象
            for (File f: files){
                //打印文件名
                String name = file.getName();
                System.out.println(name);
                //判断子目录是否存在子目录,如果是文件则删除
                if (f.isDirectory()){
                    deleteFile(f);
                }else {
                    f.delete();
                }
            }
            //删除空文件夹  for循环已经把上一层节点的目录清空。
            file.delete();
 
        }
 
    }

二、IIO流原理及流的分类

IO原理

I/O Input/Output 的缩写, I/O 技术是非常实用的技术,用于 处理设备之间的数据传输 。如读 / 写文件,网络通讯等。

Java 程序中,对于数据的输入 / 输出操作以 “流 (stream)

方式进行。

  java.io 包下提供了各种“流”类和接口,用以获取不同种类的

数据,并通过 标准的方法 输入或输出数据。

 输入 input : 读取外部数据(磁盘、光盘等存储设备的数据)到 程序(内存)中。

 输出 output : 将程序(内存)数据输出到磁盘、光盘等存储设 备中。

流的分类

按操作 数据单位 不同分为: 字节流 (8 bit) ,字符流 (16 bit)

按数据流的 流向 不同分为: 输入流,输出流

按流的 角色 的不同分为: 节点流,处理流

节点流:直接从数据源或目的地读写数据

处理流:不直接连接到数据源或目的地,而是“连接”在已存

在的流(节点流或处理流)之上,通过对数据的处理为程序提

供更为强大的读写功能。

InputStream & Reader

InputStream Reader 是所有 输入流 的基类。

 InputStream (典型实现: FileInputStream )

 int read()

 int read(byte[] b)

 int read(byte[] b, int off, int len)

 Reader (典型实现: FileReader )

 int read()

 int read(char [] c)

 int read(char [] c, int off, int len)

 程序中打开的文件 IO 资源不属于内存里的资源,垃圾回收机制无法回收该资

源,所以应该 显式关闭文件 IO 资源 。

 FileInputStream 从文件系统中的某个文件中获得输入字节。 FileInputStream

用于读取非文本数据之类的原始字节流。要读取字符流,需要使用 FileReader

OutputStream & Writer

 OutputStream 和 Writer 也非常相似:

 void write( int b / int c );

 void write( byte[] b / char[] cbuf );

 void write( byte[] b / char[] buff, int off, int len);

 void flush();

 void close(); 需要先刷新,再关闭此流

 因为字符流直接以字符作为操作单位,所以 Writer 可以用字符串来替换字符数组,

即以 String 对象作为参数

 void write(String str);

 void write(String str, int off, int len);

 FileOutputStream 从文件系统中的某个文件中获得输出字节。 FileOutputStream

用于写出非文本数据之类的原始字节流。要写出字符流,需要使用 FileWriter

三、节点流(或文件流)

读取文件

1.利用字符流

@Test
    /**
     * 读取文件
     */
    public void test1() {
        FileReader fr= null;
        try {
            //1.建立一个流文件,将已存在的文件加载进流
            fr = new FileReader("Hello.txt");
            //2.创建一个存放临时文件的char型数组
            char[] buffer=new char[1024];
            //3.调用对象流的方法将文件读到数组中
            int len=0;
            while ((len=fr.read(buffer))!=-1) {
                System.out.println(new String(buffer, 0, len));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4.关闭文件流
            if (fr!=null){
                try {
                    fr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
 
        }

2.利用字节流

@Test
    /**
     * 2.利用字节流读取文件
     */
    public void test2() {
        FileInputStream fi= null;
        try {
            //1.建立一个流文件,将已存在的文件加载进流
            fi = new FileInputStream("Hello.txt");
            //2.创建一个存放临时文件的char型数组
            byte[] buffer=new byte[1024];
            //3.调用对象流的方法将文件读到数组中
            int len=0;
            while ((len=fi.read(buffer))!=-1) {
                System.out.println(new String(buffer, 0, len));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4.关闭文件流
            if (fi!=null){
                try {
                    fi.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
 
        }
 
    }

写入文件

1.利用字符流写文件

 @Test
    /**
     * 1.利用字符流写文件
     */
    public void test1(){
        FileWriter fw= null;
        try {
            //1.创建流文件,建立数据存放文件
            fw = new FileWriter("Hello.txt");
            //2.调用对象的写入方法,将数据存入文件
            fw.write("加油!!!");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //3.关闭流文件
            if(fw!=null){
                try {
                    fw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
 
        }
 
    }

注意点

定义文件路径时,注意:可以用“ /” 或者“\\”。

 在 写入 一个文件时,如果使用构造器 FileOutputStream(file) ,则 目录下有同名文 件将被覆盖。

 如果使用构造器 FileOutputStream(file,true) ,则目录下的同名文件不会被覆盖,  在文件内容末尾追加内容。

 在 读取 文件时,必须保证该文件已存在,否则报异常。

 字节流操作字节,比如: .mp3 , .avi , .rmvb , mp4 , .jpg , .doc , .ppt

 字符流操作字符,只能操作普通文本文件。最常见的文本文 件:.txt , .java , .c , .cpp 等语言的源代码。尤其注意 .doc,excel,ppt 这些不是文本文件。

四、缓冲流

为了提高数据读写的速度 Java API 提供了带缓冲功能的流类,在使用这些流类时,会创建一个内部缓冲区数组,缺省使用 8192 个字节 (8Kb) 的缓冲区

 缓冲流要“套接”在相应的节点流之上,根据数据操作单位可以把缓冲流分为:

 BufferedInputStream 和 BufferedOutputStream

 BufferedReader 和 BufferedWriter

 当读取数据时,数据按块读入缓冲区,其后的读操作则直接访问缓冲区

 当使用 BufferedInputStream 读取字节文件时, BufferedInputStream 会一次性从

文件中读取 8192 个 (8Kb) ,存在缓冲区中,直到缓冲区装满了,才重新从文件中

读取下一个 8192 个字节数组。

 向流中写入字节时,不会直接写到文件,先写到缓冲区中直到缓冲区写满,

BufferedOutputStream 才会把缓冲区中的数据一次性写到文件里。使用方法

flush() 可以强制将缓冲区的内容全部写入输出流

 关闭流的顺序和打开流的顺序相反。只要关闭最外层流即可,关闭最外层流也

会相应关闭内层节点流

 flush() 方法的使用:手动将 buffer 中内容写入文件

 如果是带缓冲区的流对象的 close() 方法,不但会关闭流,还会在关闭流之前刷

新缓冲区,关闭后不能再写出

练习: 实现图片加密操作。

@Test
    /**
     * 实现对图片的加密
     */
    public void encrypt()  {
        BufferedInputStream bis= null;
        BufferedOutputStream bos= null;
        try {
            bis = new BufferedInputStream(new FileInputStream("20204.jpg"));
            bos = new BufferedOutputStream(new FileOutputStream("20206.jpg"));
            byte[] buffer=new byte[1024];
            int len=0;
            while((len=bis.read())!=-1){
                bos.write(len^5);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(bis!=null){
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(bos!=null){
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
 
 
        }
 
    }
    @Test
    /**
     * 实现对图片的解密
     */
    public void decrypt()  {
        BufferedInputStream bis= null;
        BufferedOutputStream bos= null;
        try {
            bis = new BufferedInputStream(new FileInputStream("20206.jpg"));
            bos = new BufferedOutputStream(new FileOutputStream("20208.jpg"));
            byte[] buffer=new byte[1024];
            int len=0;
            while((len=bis.read())!=-1){
                bos.write(len^5);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(bis!=null){
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(bos!=null){
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
 
 
        }
 
    }

五、转换流

转换流提供了在字节流和字符流之间的转换

Java API 提供了两个转换流:

InputStreamReader :将 InputStream 转换为 Reader

OutputStreamWriter :将 Writer 转换为 OutputStream

字节流中的数据都是字符时,转成字符流操作更高效。

很多时候我们使用转换流来处理文件乱码问题。实现编码和解码的功能

  public static void main(String[] args) {
        BufferedReader br= null;
        BufferedWriter bw= null;
        try {
            FileInputStream fis = new FileInputStream("D:/IDEA/day01/Smile.txt");
            InputStreamReader isr=new InputStreamReader(fis);
            br = new BufferedReader(isr);
            FileOutputStream fos=new FileOutputStream("new.txt");
            OutputStreamWriter osw=new OutputStreamWriter(fos);
            bw = new BufferedWriter(osw);
            String str;
            while((str=br.readLine())!=null){
                bw.write(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(bw!=null){
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(br!=null){
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
 
 
    }
    @Test
    public void test()
    {
        FileReader fr= null;
        try {
            fr = new FileReader("Hello.txt");
            char[] buffer=new char[1024];
            int len=0;
            while((len=fr.read(buffer))!=-1){
                System.out.println(new String(buffer, 0, len));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(fr!=null){
                try {
                    fr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
 
    }

目录
相关文章
|
5天前
|
Java
【Java基础】输入输出流(IO流)
Java基础、输入输出流、IO流、流的概念、输入输出流的类层次结构图、使用 InputStream 和 OutputStream流类、使用 Reader 和 Writer 流类
46 1
|
5天前
|
存储 缓存 Java
Java基础17-读懂Java IO流和常见面试题(二)
Java基础17-读懂Java IO流和常见面试题(二)
17 0
|
5天前
|
存储 Java Unix
Java基础17-读懂Java IO流和常见面试题(一)
Java基础16-读懂Java IO流和常见面试题(一)
18 0
|
11天前
|
存储 算法 NoSQL
JAVA—IO流知识点总结
JAVA—IO流知识点总结
|
13天前
|
Java 应用服务中间件
已解决:An error occurred at line: 1 in the generated java file The type java.io.ObjectInputStream canno
已解决:An error occurred at line: 1 in the generated java file The type java.io.ObjectInputStream canno
|
14天前
|
Java
io读两个文件,生成list 排重后写本地文件(Java)
io读两个文件,生成list 排重后写本地文件(Java)
|
14天前
|
Java Windows
文件操作和IO(2):Java中操作文件
文件操作和IO(2):Java中操作文件
8 0
|
18天前
|
存储 Java API
Java语言IO(输入/输出)编程技术深度解析
Java语言IO(输入/输出)编程技术深度解析
250 1
|
19天前
|
存储 监控 Java
Java nio非阻塞io
Java nio非阻塞io
|
24天前
|
存储 Java
Java IO流:深入解析与技术应用
Java IO流:深入解析与技术应用
262 1

热门文章

最新文章