JAVA中的IO流

2 I/O

2.1 文件对象

2.1.1 创建一个文件对象

JAVA中的IO流_第1张图片

/**

 *

 * @author yrf

 * D盘下创建abc.txt 内容:aaa

 *

 */

public class IOTest {

public static void main(String[] args) {

    // 绝对路径

    File f1=new File("D:/test/abc.txt");

    System.out.println("当前文件是:"+f1); // 当前文件是:D:\test\abc.txt

    // 文件是否存在

    System.out.println(f1.exists()); // true

    // 文件是否是文件夹

    System.out.println(f1.isDirectory());//  false

    // 是否是文件

    System.out.println(f1.isFile()); //  true

    // 文件的长度

    System.out.println(f1.length()); //  3

    // 文件最后修改时间

    long updateLastTime = f1.lastModified();

    Date date=new Date(updateLastTime);

    SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd E HH:mm:ss SSS");

    System.out.println("最后修改时间:"+sdf.format(date)); //最后修改时间:2018-08-14 星期二 17:01:15 116

//  f1.setLastModified(0);

    //文件重命名 renameTo方法用于对物理文件名称进行修改,但是并不会修改File对象的name属性。

    File f2=new File("D:/test/abcd.txt"); //true

    System.out.println(f1.renameTo(f2));

}

}

2.2 文件常用方法

public class IOTest {

public static void main(String[] args) {

    // 绝对路径

    File f=new File("D:/test/oracletest");

    // 以字符串数组的形式,返回当前文件夹下的所有文件(不包含子文件及子文件夹)

    f.list();

    // 以文件数组的形式,返回当前文件夹下的所有文件(不包含子文件及子文件夹)

    File[]fs= f.listFiles();

    // 以字符串形式返回获取所在文件夹

    f.getParent();

    // 以文件形式返回获取所在文件夹

    f.getParentFile();

    // 创建文件夹,如果父文件夹skin不存在,创建就无效

    f.mkdir();

    // 创建文件夹,如果父文件夹skin不存在,就会创建父文件夹

    f.mkdirs();

    // 创建一个空文件,如果父文件夹skin不存在,就会抛出异常

    try {

       f.createNewFile();

    } catch (IOException e) {

       // TODO Auto-generated catch block

       e.printStackTrace();

    }

    // 所以创建一个空文件之前,通常都会创建父目录

    f.getParentFile().mkdirs();

    // 列出所有的盘符c: d: e: 等等

    f.listRoots();

    // 刪除文件

    f.delete();

    // JVM结束的时候,刪除文件,常用于临时文件的删除

    f.deleteOnExit();

}

}

2.3 什么是流

什么是流(Stream),流就是一系列的数据

比如读取文件的数据到程序中,站在程序的角度来看,就叫做输入流
输入流: InputStream
输出流:OutputStream

2.4 字节流

InputStream字节输入流 
OutputStream字节输出流 
用于以字节的形式读取和写入数据

以字节流的形式读取文件内容

InputStream是字节输入流,同时也是抽象类,只提供方法声明,不提供方法的具体实现。
FileInputStream 是InputStream子类,以FileInputStream 为例进行文件读取

JAVA中的IO流_第2张图片

public class IOTest {

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

    // 绝对路径 创建文件 内容 aaa

    File f=new File("D:/test/abcd.txt");

    try {

       // 创建基本的文件输入流

       FileInputStream fis =new FileInputStream(f);

       // 创建字节数组

       byte[] b=new byte[(int)f.length()];

       //以字节流的形式读取文件内容

       fis.read(b);

       for (byte c : b) {

           System.out.println(c);  //a对应的ASCII码表 97    97 97 97

       }

       fis.close();

    } catch (FileNotFoundException e) {

       // TODO Auto-generated catch block

       e.printStackTrace();

    }

}

}

以字节流的形式向文件写入数据

OutputStream是字节输出流,同时也是抽象类,只提供方法声明,不提供方法的具体实现。
FileOutputStream 是OutputStream子类,以FileOutputStream 为例向文件写出数据
注: 如果文件D:/test/abcd.txt不存在,写出操作会自动创建该文件

public class IOTest {

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

    // 绝对路径 创建文件 内容 aaa

    File f=new File("D:/test/abcd.txt");

    // 准备输出的字节数组 88:X 89:Y

    byte[] b={88,89};

    FileOutputStream fos=new FileOutputStream(f);

    fos.write(b);  //会覆盖原来的内容

    fos.close();

    System.out.println("写入成功");

}

}

2.5 关闭流的方式

所有的流,无论是输入流还是输出流,使用完毕之后,都应该关闭。 如果不关闭,会产生对资源占用的浪费。 当量比较大的时候,会影响到业务的正常开展。

在finally中关闭

这是标准的关闭流的方式
1. 首先把流的引用声明在try的外面,如果声明在try里面,其作用域无法抵达finally.
2. 在finally关闭之前,要先判断该引用是否为空
3. 关闭的时候,需要再一次进行try catch处理

使用try()的方式

把流定义在try()里,try,catch或者finally结束的时候,会自动关闭
这种编写代码的方式叫做 try-with-resources, 这是从JDK7开始支持的技术
所有的流,都实现了一个接口叫做 AutoCloseable,任何类实现了这个接口,都可以在try()中进行实例化。 并且在try, catch, finally结束的时候自动关闭,回收相关资源。

 

2.6 字符流

使用字符流读取文件

public class IOTest {

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

    // 绝对路径 创建文件 内容 XY

    File f=new File("D:/test/abcd.txt");

    // 创建Reader

    FileReader fr=new FileReader(f);

    char[] c=new char[(int)f.length()];

    fr.read(c);

    for (char d : c) {

       System.out.println(d); // X Y

    }

    System.out.println("读入成功");

}

}

使用字符流把字符串写入到文件

FileWriter 是Writer的子类,以FileWriter 为例把字符串写入到文件

public class IOTest {

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

    // 绝对路径 创建文件 内容 XY

    File f=new File("D:/test/abcd.txt");

    // 创建 Writer

    FileWriter fw=new FileWriter(f);

    // 以字符流的形式把数据写入到文件中

    String str="hello world !!!";

    char[] c=str.toCharArray();

    fw.write(c);

    fw.close();

    System.out.println("写入成功");

}

}

2.7 中文问题

常见编码

工作后经常接触的编码方式有如下几种:
ISO-8859-1 ASCII 数字和西欧字母
GBK GB2312 BIG5 中文
UNICODE (统一码,万国码)
其中
ISO-8859-1 包含 ASCII
GB2312 是简体中文,BIG5是繁体中文,GBK同时包含简体和繁体以及日文。
UNICODE 包括了所有的文字,无论中文,英文,藏文,法文,世界所有的文字都包含其中

如果完全按照UNICODE的方式来存储数据,就会有很大的浪费。
比如在ISO-8859-1中,a 字符对应的数字是0x61
而UNICODE中对应的数字是 0x00000061,倘若一篇文章大部分都是英文字母,那么按照UNICODE的方式进行数据保存就会消耗很多空间
在这种情况下,就出现了UNICODE的各种减肥子编码, 比如UTF-8对数字和字母就使用一个字节,而对汉字就使用3个字节,从而达到了减肥还能保证健康的效果
UTF-8,UTF-16和UTF-32 针对不同类型的数据有不同的减肥效果,一般说来UTF-8是比较常用的方式

Java采用的是Unicode

2.8 缓存流

字节流和字符流的弊端: 
在每一次读写的时候,都会访问硬盘。 如果读写的频率比较高的时候,其性能表现不佳。 

为了解决以上弊端,采用缓存流。 
缓存流在读取的时候,会一次性读较多的数据到缓存中,以后每一次的读取,都是在缓存中访问,直到缓存中的数据读取完毕,再到硬盘中读取。

缓存流在写入数据的时候,会先把数据写入到缓存区,直到缓存区达到一定的量,才把这些数据,一起写入到硬盘中去。按照这种操作模式,就不会像字节流,字符流那样每写一个字节都访问硬盘,从而减少了IO操作

使用缓存流读取数据

缓存字符输入流 BufferedReader 可以一次读取一行数据

JAVA中的IO流_第3张图片

public class IOTest {

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

    // 绝对路径 创建文件 内容 hello world!!!  12306

    File f=new File("D:/test/abcd.txt");

    // 创建文件字符流

    FileReader fr=new FileReader(f);

    BufferedReader br=new BufferedReader(fr);

    while(true){

       // 一次读取一行

       String line=br.readLine();

       if(null==line)

           break;

       System.out.println(line);

    }

    System.out.println("读取成功");

}

}

使用缓存流写出数据

PrintWriter 缓存字符输出流, 可以一次写出一行数据

public class IOTest {

public static void main(String[] args){

    // 绝对路径 创建文件 内容 hello world!!!  12306

    File f=new File("D:/test/abcd.txt");

    // 创建文件字符流

    try (

            // 创建文件字符流

            FileWriter fw = new FileWriter(f);

            // 缓存流必须建立在一个存在的流的基础上             

            PrintWriter pw = new PrintWriter(fw);             

    ) {

        pw.println("garen kill teemo");

        pw.println("teemo revive after 1 minutes");

        pw.println("teemo try to garen, but killed again");

    } catch (IOException e) {

        // TODO Auto-generated catch block

        e.printStackTrace();

    }

}

}

Flush

有的时候,需要立即把数据写入到硬盘,而不是等缓存满了才写出去。 这时候就需要用到flush

2.9 数据流

DataInputStream 数据输入流 
DataOutputStream 数据输出流

2.10 对象流

对象流指的是可以直接把一个对象以流的形式传输给其他的介质,比如硬盘 
一个对象以流的形式进行传输,叫做序列化。 该对象所对应的类,必须是实现Serializable接口

2.11 System.in

System.out 是常用的在控制台输出数据的 
System.in 可以从控制台输入数据

JAVA中的IO流_第4张图片

public class IOTest {

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

    InputStream is=System.in;

    while (true) {

        /**敲入a,然后敲回车可以看到

         97 13 10

         97是a的ASCII码

         13 10分别对应回车换行

         */

       int i=is.read();

       System.out.println(i);

    }

}

}

Scanner读取字符串

使用System.in.read虽然可以读取数据,但是很不方便
使用Scanner就可以逐行读取了

JAVA中的IO流_第5张图片

public class IOTest {

public static void main(String[] args){

    System.out.println("请输入:");

    Scanner sc=new Scanner(System.in);

    String line=sc.nextLine();

    System.out.println(line);

}

}

你可能感兴趣的:(java知识点,IO流,java)