Java基础之 I/O 流

Posted in-the-game-of-thrones

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java基础之 I/O 流相关的知识,希望对你有一定的参考价值。

 

Java.io包中:五个核心类与一个核心接口。

 

  类:File、InputStream、OutputStream、Reader、Writer;

 

  接口:Serializable

 

File类:文件操作类

  构造方法

    设置完整路径:File(String pathname)

    设置父路径与子文件路径:File(File parent, String child)

  常量:

     public static final String separator;  //系统依赖的默认名称分隔符

  方法

    public boolean createNewFile() throws IOException;  //创建一个新的空文件,前提这个文件不存在;

    public boolean delete();  //删除文件或空文件夹(文件夹中没有任何东西,才能够删除)

     public boolean exists();  //判断文件或目录是否存在

    public File getParentFile()  //找到父路径后,直接通过exists()判断父文件夹是否存在

    public String getPath()  //找到父路径所在的路径

    public boolean mkdirs()  //创建多级目录

 1 package com.imooc.demo;
 2 
 3 import java.io.File;
 4 import java.io.IOException;
 5 
 6 public class Demo{
 7 
 8     public static void main(String[] args) throws IOException {
 9         long st = System.currentTimeMillis();
10 
11         //设置文件路径
12         /**
13          * 问题注意: 在Windows中,使用“”分隔符
14          *           在Linux中,使用“/”分隔符
15          *           使用File.separator常量
16          */
17         File file = new File("D:"+File.separator+"中文用于测试IO"+File.separator+"demo"+File.separator+"demo2"+File.separator+"7771.txt");
18         File file2 = new File("D:"+File.separator+"中文用于测试IO"+File.separator+File.separator+"7771.txt");
19         if (!file.exists()){//如果父路径不存在
20 //            file.getParentFile().mkdir();//创建单级demo文件夹
21             boolean is = file.getParentFile().mkdirs();//创建多级目录
22             System.out.println(is?"创建多级目录成功":"创建文件夹错误");
23         }
24 
25         if (file2.exists()){//如果文件存在,者删除
26             boolean delete = file2.delete();
27             System.out.println(delete?"文件或空目录删除成功":"文件或目录删除失败");
28         }else {
29             //创建一个新的文件
30             boolean newFile = file2.createNewFile();
31             System.out.println(newFile ? "创建成功" : "创建失败");
32         }
33         long et = System.currentTimeMillis();
34         System.out.println("消耗多少毫秒:"+(et-st));
35     }
36 
37 }

 

取得文件信息内容方法

    public long length()  //取得文件大小

    public boolean isFile()  //是否为文件

    public boolean isDirectory()  //是否为目录

    public long lastModified()  //返回最近修改的日期

 1 package com.imooc.demo;
 2 
 3 import java.io.File;
 4 import java.io.IOException;
 5 import java.math.BigDecimal;
 6 import java.text.SimpleDateFormat;
 7 import java.util.Calendar;
 8 import java.util.Date;
 9 
10 public class Demo{
11 
12     public static void main(String[] args) throws IOException {
13         long st = System.currentTimeMillis();
14 
15         //设置文件路径
16         /**
17          * 问题注意: 在Windows中,使用“”分隔符
18          *           在Linux中,使用“/”分隔符
19          *           使用File.separator常量
20          */
21         File file = new File("D:"+File.separator+"中文用于测试IO"+File.separator+"demo"+File.separator+"demo2"+File.separator+"7771.txt");
22         File file2 = new File("D:"+File.separator+"中文用于测试IO"+File.separator+File.separator+"7771.txt");
23         /**
24          * 得到Long类型的值
25          */
26         long lastModified = file2.lastModified();
27         /**
28          * 使用Calendar类的setTimeInMillis(long)方法,
29          * 得到年月日
30          */
31         Calendar instance = Calendar.getInstance();
32         instance.setTimeInMillis(lastModified);
33         System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(instance.getTime()));
34 
35         System.out.println("------------------------");
36         if (file2.exists()){//如果父路径存在
37 //            /**
38 //             * 精确
39 //             * 任意精度有符号的十进制数
40 //             */
41 //            BigDecimal bigDecimal = new BigDecimal(length);
42 //            /**
43 //             * divide()方法中三个参数指定的是
44 //             *  divisor值,这 BigDecimal是分。(被除数)
45 //                scale的 BigDecimal商规模要返回。(结果保留两位小数)
46 //                roundingMode -舍入模式适用。(进位模式)
47 //             */
48             System.out.println("文件大小:"+new BigDecimal((double)file2.length()/1024/1024).divide(new BigDecimal(1),2,BigDecimal.ROUND_HALF_UP)+"M");
49         }else
50             System.out.println("文件为空");
51     }
52 }

 

字节流与字符流的最大的区别:

  1. 字节流直接与终端进行数据交互,而字符流需要将数据经过缓冲区处理后才可以输出。
  2. 在使用OutputStream输出时,即使最后没有关闭输出流,那么内容也可以正常的输出,但是如果是字符输出流如果不关闭,那么表示在缓冲区的内容不会被强制清空,所以就不会输出数据,如果有特殊的情况,暂时不允许关闭输出流,那么可以试用flush()方法强制清空缓冲区。
  3. 开发中,对于图片、音乐、视频都是用字节流进行处理,而字符流最大的好处就是对于中文的有效处理。

 

(父)抽象类字节流 :InputStream 和 OutputStream

  (二级)对象序列化:ObjectOutputStream和ObjectInputStream

  (二级)字节数组缓冲流对象:ByteArrayOutputStream 和 ByteArrayInputStream,类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException。

  (二级)字节流 FileInputStream 和 FileOutputStream

    (三级)打印流:PrintStream(字节打印流)和PrintWriter(字符打印流),但是他们都还是需要OutputStream支持。

        将控制台中的数据,输出到指定的文件中

        注意:如果程序输出数据的话,一定要使用打印流完成功能。

    (三级)内存操作流:ByteArrayInputStream 和 ByteArrayOutputStream

        内存操作流,将数据读完或写完,关闭流后,不会对数组中的数据产生影响。

    (三级)缓冲字节流:BufferedInputStream 和 BufferedOutputStream

        缓冲输入流目的是为了解决中文乱码的问题

(父)字符流:Reader和Writer

  (二级)字符流:FileReader 和 FileWriter

  (二级)缓冲字符流:BufferedReader 和 BufferedWriter

  (二级)字节流和字符流转换桥梁:InputStreamReader 和 OutputStreamWriter

示例:将【D:中文用于测试IO】目录以及子目录下的所有以.txt为后缀的文件,复制到D磁盘中,并且改变后缀为.docx后

 1 package com.imooc.demo;
 2 
 3 import java.io.*;
 4 
 5 /** 
 6  * 将【D:中文用于测试IO】目录以及子目录下的所有以.txt为后缀的文件,复制到D磁盘中,并且改变后缀为.docx后
 7  */
 8 public class Demo2 {
 9 
10     public static void main(String[] args) {
11 //        String fromURI = "D:"+File.separator+"中文用于测试IO"+File.separator+"D9D9D.txt";
12         String fromURI = "D:"+File.separator+"中文用于测试IO";
13         File file = new File(fromURI);
14         try {
15             method(file);
16         } catch (Exception e) {
17             e.printStackTrace();
18         }
19 //        test();
20     }
21 
22     /**
23      * 使用字符流,读取数据并且使用字符流直接将数据写入到磁盘中
24      * 将【D:中文用于测试IO】目录以及子目录下的所有以.txt为后缀的文件,复制到C磁盘中,并且改变后缀为.docx后
25      * @param file
26      */
27     private static void method(File file) throws Exception {
28         StringBuilder stringBuilder = new StringBuilder();
29         //判断是文件还是路径
30         if (file.isFile()){//是文件
31             sufficeMethod(file, stringBuilder);
32 
33         }else{//是目录
34             File[] files = file.listFiles();
35             for (int i = 0; i < files.length; i++) {
36                 File file1 = files[i];
37                 method(file1);//递归
38             }
39         }
40     }
41 
42     private static void sufficeMethod(File file, StringBuilder stringBuilder) throws IOException {
43         //判断文件是否以 【.txt】 为后缀的
44         if (file.getName().endsWith(".txt")){
45             //如果是以【.txt】结尾,修改后缀名后,拷贝到指定的盘符
46             String newFileName = file.getName().replace(".txt", ".docx");
47             String noDParentDir = file.getParent().substring(1)+ File.separator;
48             //修改盘符
49             stringBuilder.append("E");
50 //                stringBuilder.append(file.getAbsolutePath().substring(1).substring(0,(file.getAbsolutePath().lastIndexOf("\"))));
51             stringBuilder.append(noDParentDir);
52             stringBuilder.append(newFileName);//新的文件名
53             String newFileURI = stringBuilder.toString();
54 
55             //定义目的地文件文件对象
56             File toFile = new File(newFileURI);
57             //创建目录
58             if (!toFile.getParentFile().exists()){
59                 toFile.getParentFile().mkdirs();
60                 System.out.println("【"+toFile+"】---》文件夹创建成功。。。");
61             }
62             //定义字符输入流,与字符输出流,一边写同时一边读到指定的盘符中
63             Reader reader = new FileReader(file);//输入流,格式为系统默认格式
64 //            Reader reader = new InputStreamReader(new FileInputStream(file));
65 
66             //因为windows系统默认是GBK编码格式,然而在使用OutputStreamWriter对象时,Java无法将其转换为UTF-8格式
67 //            Writer writer = new OutputStreamWriter(new FileOutputStream(toFile), "UTF-8");
68             Writer writer = new OutputStreamWriter(new FileOutputStream(toFile,true), "GBK");
69 
70             char[] chars = new char[1024];
71             int len = 0;
72             while ((len = reader.read(chars)) != -1){
73                 writer.write(chars,0,len);
74                 writer.flush();
75                 System.out.println("文件copy成功");
76             }
77             writer.close();
78             reader.close();
79         }
80     }
81 
82 }

示例:使用System.setIn()与System.setOut()将系统属性打印到SystemtProperties.txt文件中

 1 package com.imooc.demo;
 2 
 3 import java.io.*;
 4 import java.util.Scanner;
 5 
 6 /**
 7  * System.setIn()
 8  *
 9  */
10 public class Demo1 {
11 
12     public static void main(String[] args) throws Exception{
13         /**
14          * System.setIn()方法的使用
15          */
16         InputStream fileInputStream = new FileInputStream(new File("D:" + File.separator + "LiQiang-Space" + File.separator + "SystemtPropertiesSystemIN.txt"));
17         BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
18         System.setIn(bufferedInputStream);
19         Scanner scanner = new Scanner(System.in);
20         while (scanner.hasNextLine()){
21             String line = scanner.nextLine();
22             System.out.println(line);
23         }
24         System.out.println("-----------------------------------------------------------------------");
25         /**
26          * System.setOut()方法的使用
27          */
28         long beginTime = System.currentTimeMillis();
29         File file = new File("D:" + File.separator + "LiQiang-Space" + File.separator + "SystemtPropertiesSystemOUT.txt");
30         /**
31          * 判断my.txt的上一级目录是否存在
32          */
33         if (!file.getParentFile().exists())
34             file.getParentFile().mkdirs();
35         //定义打印流,将目的地文件对象作为参数
36         PrintStream printStream = new PrintStream(new FileOutputStream(file));
37 
38         Thread.sleep(1000);
39 
40         /**
41          * 调用系统的setOut方法,就可以将数据输出到指定的文件中了
42          * 注意:要将内容放在打印流之后,才可以!!!
43          */
44         System.setOut(printStream);
45         /**
46          * 系统属性
47          */
48         System.getProperties().list(System.out);
49         System.out.println("将本该在控制台输出的信息,从定向到指定的文件中。");
50         long endTime = System.currentTimeMillis();
51         System.out.println("开始时间【"+ beginTime +"】");
52         System.out.println("结束时间【"+ endTime +"】");
53         System.out.println("写入总耗时【"+(endTime-beginTime)+"】");
54         printStream.close();
55         scanner.close();
56         bufferedInputStream.close();
57         fileInputStream.close();
58     }
59 
60 }

待续。。。


    

 

  

以上是关于Java基础之 I/O 流的主要内容,如果未能解决你的问题,请参考以下文章

Java基础之IO流

JavaSE入门学习46:文件传输基础之I/O流(Java序列化)

java I/O流基础(知识+代码示例)

java I/O流基础(知识+代码示例)

JAVA基础之IO流

JavaSE入门学习43:文件传输基础之I/O流