转载和引用,请注明原文出处! Fork me on GitHub
结局很美妙的事,开头并非如此!

IO和NIO

一、文件的概念以及文件基本函数的操作

      1. 什么是文件:文件可认为是相关记录或放在一起的数据的集合
      2. File类是“文件和目录路径名的抽象表示”。 而不是指文件的内容。
      3. File类定义了一些与平台无关的方法操作,如:创建、删除文件和重命名等。
      4. Java中目录被看成是一个特殊的文件。List()方法可以返回目录中所有的子目录和文件。
      5. 在unix下路径分隔符为(/),而在windos中则是为(\),在java中可以正确的处理不同系统中的分隔符。

       示例代码:

 1 package com.study.test;
 2 
 3 import java.io.*;
 4 import java.util.Date;
 5 
 6 import static java.lang.System.*;
 7 
 8 //什么是文件:文件可认为是相关记录或放在一起的数据的集合
 9 //File类是“文件和目录路径名的抽象表示”。 而不是指文件的内容。
10 //File类定义了一些与平台无关的方法操作,如:创建、删除文件和重命名等。
11 //Java中目录被看成是一个特殊的文件。List()方法可以返回目录中所有的子目录和文件。
12 //在unix下路径分隔符为(/),而在windos中则是为(\),在java中可以正确的处理不同系统中的分隔符。 
13 public class MyFile {
14 
15     public static void main(String[] args) {
16         // //F:\\temp\\java\\luna\\io\\src\\aa.txt
17         File f1 = new File("D:\\study\\aa.txt");// 通过File类的构造函数传入一个文件名称
18         out.println(f1.getName());
19         out.println(f1.getPath());// 获取相对路径
20         out.println(f1.getAbsolutePath());// 获取绝对路径
21         out.println(f1.getAbsoluteFile());// 目录也可以看作一个文件
22         out.println(f1.getParent());// 返回此文件对象的父目录
23         File f2 = new File("D:\\study\\bb.txt");
24         out.println(f1.renameTo(f2));// 把文件aa.txt重新命名为bb.txt
25         out.println(f2.exists());
26         out.println(f1.canRead());
27         out.println(f1.canWrite());
28         out.println(f1.isFile());
29         out.println(f1.isDirectory());
30         out.println(new Date(f2.lastModified()));// 文件最后的修改时间
31         out.println(f1.length());// 获取文件内容的长度
32 
33     }
34 
35 }
View Code

二、文件字节流FileInputStream与FileOutputStream的区别以及文件复制的实现

       1. 文件输入流(FileInputStream)与文件输出流(FileOutputStream)的区别

              1.1  FileInputStream:从已经存在的文件中获取里面已输入的内容,获取的是ASCII码字节
              1.2  FileOutputStream:把内容写入到指定的文件中去,如果指定的文件不存在则自己创建一个,写入是以字节为单位的,每次只能写一个

       2. 文件复制的实质就是从一个文件中读取内容到另一个文件中去,如果目标文件不存在则自动创建一个

       示例代码:

 1 package com.study.test;
 2 
 3 import java.io.FileInputStream;
 4 import java.io.FileOutputStream;
 5 import java.io.IOException;
 6 
 7 //文件输入流(FileInputStream)与文件输出流(FileOutputStream)的区别
 8 //FileInputStream:从已经存在的文件中获取里面已输入的内容,获取的是ASCII码字节
 9 //FileOutputStream:把内容写入到指定的文件中去,如果指定的文件不存在则自己创建一个,写入是以字节为单位的,每次只能写一个
10 
11 //文件复制的实质就是从一个文件中读取内容到另一个文件中去,如果目标文件不存在则自动创建一个
12 public class FileCopy {
13     public static void main(String[] args) throws IOException {
14         FileInputStream f1 = new FileInputStream("D:\\study\\bb.txt");
15         FileOutputStream f2 = new FileOutputStream("D:\\study\\aa.txt");
16         while (true) {
17             int i = f1.read();
18             f2.write(i);
19             if (i == -1)
20                 break;
21 
22         }
23         f1.close();
24         f2.close();
25 
26     }
27 
28 }
View Code

      3. 往文件里面写入字符串

       示例代码:

 1 package com.study.test;
 2 
 3 import java.io.BufferedWriter;
 4 import java.io.FileOutputStream;
 5 import java.io.IOException;
 6 import java.io.OutputStreamWriter;
 7 
 8 public class ReadFileAndWirteFile {
 9 
10     public static void main(String[] args) throws IOException {
11 
12         // 写内容(以字节写入)到指定文件中,如果文件不存在则自动创建
13         FileOutputStream f2 = new FileOutputStream("D:\\study\\dd.txt");
14         // 把写入的字节转换成字符流
15         OutputStreamWriter osw = new OutputStreamWriter(f2);
16         // 以整行方式把字符流写入目标文件中 调用
17         BufferedWriter bw = new BufferedWriter(osw);
18         bw.write("您好!");
19         bw.write("您好!");
20         bw.write("您好!");
21         bw.close();// 一定要关闭,否则不能写入 缓冲区游离
22         f2.close();
23 
24     }
25 
26 }
View Code

三、文件字符流读取(FileReader)与写入(FileWriter)的区别

 1 package com.study.test;
 2 
 3 import java.io.*;
 4 
 5 //文件字符流读取FileReader与写入FileWriter的区别
 6 import static java.lang.System.*;
 7 
 8 public class ReadFileAndWirteFile {
 9 
10     public static void main(String[] args) throws IOException {
11         // 文件字符流读取:FileReader
12         FileReader fr = new FileReader("D:\\study\\bb.txt");// 读取指定文件的内容并将其转换为字符流
13         BufferedReader br = new BufferedReader(fr);// 将字符流包装到缓冲区
14         String s;
15         while ((s = br.readLine()) != null) {
16             out.println(s);
17         }
18 
19         // 文件字符流写入:FileWriter
20         // 把字符文件写入指定文件中,如果文件不存在则自动创建, FileWriter已经将字节转换为字符不用再用OutputStreamWriter来转换
21         FileWriter fw = new FileWriter("D:\\study\\ee.txt");
22         BufferedWriter bw = new BufferedWriter(fw);
23         bw.write("我们");
24         bw.close();// 一定要关闭 否则不能写入
25 
26     }
27 
28 }
View Code

四、找到指定目录下指定文件格式的文件

 1 package com.study.test;
 2 
 3 import static java.lang.System.out;
 4 
 5 import java.io.File;
 6 import java.io.FilenameFilter;
 7 import java.io.IOException;
 8 
 9 class AA implements FilenameFilter {
10     private String i;
11 
12     AA(String i) {
13         this.i = i;
14     }
15 
16     @Override
17     public boolean accept(File dir, String name) {
18         return name.endsWith(this.i);
19     }
20 
21 }
22 
23 public class ReadFileAndWirteFile {
24     public static void main(String[] args) throws IOException {
25         File f = new File("D:\\study");
26         // 只想搜索.txt文件
27         for (File temp : f.listFiles(new AA("txt")))
28             out.println(temp.getName());
29 
30     }
31 }
View Code

输出结果:

aa.txt
bb.txt
dd.txt
ee.txt

五、什么是NIO

         NIO提供了一个全新的底层I/O模型,与最初的java.io包中面向流的概念不同,NIO中采用了面向块的概念。

         I/O操作以大的数据块为单位进行,而不是一次一个字节或字符进行

         采用这样的操作方式java的I/O性能有很大提高,但也牺牲了java操作的简单性。

         NIO中所有的操作都要使用到缓冲区(内存)处理,且所有的读写操作都是通过缓冲区(内存)完成的。

         NIO提供与平台无关的非阻塞I/O。与面向线程的、阻塞式I/O方式比较,多道通信、非阻塞I/O技术可以使应用程序更有效地处理大量连接的情况。

         Java新IO中使用Buffer和Channel支持以上的操作。

六、NIO之Buffer类以及其方法的使用

        1. Buffer类与StringBuffer非常类似,都可以自动扩容,只不过Buffer的效率更高,因为Buffer类是把内容放入内存中(缓冲区)以数据块的方式读写的,而StringBuffer是以流的方式读写的

         示例代码:

 1 package com.study.test;
 2 
 3 import static java.lang.System.*;
 4 
 5 import java.nio.CharBuffer;
 6 
 7 public class NIOBuffer {
 8 
 9     public static void main(String[] args) {
10 //         Buffer类与StringBuffer非常类似,都可以自动扩容,只不过Buffer的效率更高,
11 //         因为Buffer类是把内容放入内存中(缓冲区)以数据块的方式读写的,而StringBuffer是以流的方式读写的
12 
13         // 创建缓冲
14         // CharBuffer存储字符 用allocate 用allocate(int capacity)分配缓冲区空间
15         CharBuffer buffer = CharBuffer.allocate(4); 
16         buffer.put('a');// 位置0插入a
17         buffer.put('b');// 位置1插入b
18         out.println(buffer.position());// 当前位置为2 缓冲区的指针指向即将操作的下一个位置
19         out.println(buffer.limit());// limit=4 //把缓冲区的容量限制为当前容量 不能再自动扩容 只能存储4个字符
20         // out.println(buffer.capacity());//capacity=4//缓冲区的当前容量
21         // buffer.put('c');
22         // buffer.put('d');
23         // buffer.put('e');//异常 bufferoverflowexception 因为缓冲区容量已被limit方法限制为4
24         // 所以此时不能插入多余数据到缓冲区
25 
26         out.println(buffer);// 从当前位置输出什么都没有
27         out.println("-------------------改变指针-------------------------");
28         // 改变指针
29         buffer.position(0);
30         out.println(buffer.limit());// limit=4
31         out.println(buffer.capacity());// capacity=4;
32         out.println(buffer);// 输出内容 ab
33         // 重置缓冲区
34         out.println("-------------------重置缓冲区-------------------------");
35         buffer.flip();
36         out.println(buffer.position());
37         out.println(buffer.limit());// limit=2
38         out.println(buffer.capacity());// capacity=4;
39         out.println(buffer);// 输出内容,仅仅输出到limit,不会输出多余字符
40 
41         out.println(buffer.position(4));// 定位到b之后继续输入
42         buffer.put('c');// 缓冲区已经重置到0位置 所以不能插入 必须 重置到位置2才能插入
43         // //子缓冲区
44         // CharBuffer childBuffer=buffer.slice();//截取0到达limit的位置
45         // out.println(childBuffer);//
46         // out.println(childBuffer.limit());
47         // out.println(childBuffer.capacity());
48         // //只读缓冲区
49         // CharBuffer bufferRO=buffer.asReadOnlyBuffer();
50         // bufferRO.put('x');//出错
51 
52     }
53 
54 }
View Code

七、NIO之内存映射与传统IO流的区别

        1. 内存映射可以把文件映射到内存中,这样文件内的数据就可以用内存读写指令来访问,而不是用InputStream或OutputStream这样的I/O操作类,采用此方式读取文件的速度是最快的。使用FileChannel类提供的map()方法。

        2. Map()方法在使用时要指定映射模式,在内存映射中提供三种模式:读取和写入:READ_WRITE,只读READ_ONLY,专用(写入时复制)映射模式

         示例代码:

 1 package com.study.test;
 2 
 3 import java.io.File;
 4 import java.io.IOException;
 5 import java.io.RandomAccessFile;
 6 import java.nio.MappedByteBuffer;
 7 import java.nio.channels.FileChannel;
 8 
 9 //内存映射可以把文件映射到内存中,这样文件内的数据就可以用内存读写指令来访问,而不是用InputStream或OutputStream这样的I/o操作类,
10 //采用此方式读取文件的速度是最快的。使用FileChannel类提供的map()方法。
11 //Map()方法在使用时要指定映射模式,在内存映射中提供三种模式:读取和写入:READ_WRITE,只读READ_ONLY,专用(写入时复制)映射模式
12 public class NIOBuffer {
13 
14     public static void main(String[] args) throws IOException {
15         // 下面再次读取文件,原来的流其实是一个管子
16         RandomAccessFile fis = new RandomAccessFile("D:\\study\\cc.txt", "rw");// 获取一个文件
17         // 不直接通过流了,出现了一个管道
18         FileChannel fc = fis.getChannel();// 通过通道把文件映射到内存中去
19         // 怎么用通道读取内容? 通过FileChannel的map()方法读写文件
20         MappedByteBuffer mb = fc.map(FileChannel.MapMode.READ_WRITE, 4,
21                 new File("D:\\study\\cc.txt").length());
22         mb.put(1, (byte) '2');
23         mb.put(2, (byte) '3');
24 
25     }
26 
27 }
View Code

 

posted @ 2017-10-08 21:46  小不点啊  阅读(492)  评论(0编辑  收藏  举报