一、File类
1、File类概念

  (1) 代表硬盘上的一个文件或者文件夹。
  (2) Windows中路径表示方式 c:\suns.txt
  (3) Java中路径表示方式:① c:\ \suns.txt ;② c:/sun.txt

2、File类的构造方法

  (1) File(String pathname)

import java.io.File;
import java.io.IOException;

public class FileTest {
	public static void main(String[] args) {
		createNewFile();
	}
	public static void createNewFile() {
		File file = new File("D:/File/javaFile.txt");
		try {
			// 创建新的文件,前提是必须文件夹已经存在,即D:/File已经存在,文件夹名字不区分大小写:
			file.createNewFile();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

  (2) File(String parent, String child)

import java.io.File;
import java.io.IOException;

public class FileTest {
	public static void main(String[] args) {
		createNewFile();
	}

	public static void createNewFile() {
		String url = "D:/File";
		String fileName = " HelloWorld.java";
		//有参构造方法
		File file = new File(url, fileName);
		try {
			// 创建新的文件,前提是必须文件夹已经存在,即D:/File已经存在,文件夹名字不区分大小写:
			file.createNewFile();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

  (3) File(File parent, String child)
注意: File类没有无参构造方法

3、File类的常用方法

  (1) createNewFile():boolean;创建新的文件,前提是必须文件夹已经存在,文件夹名字不区分大小写。

import java.io.File;
import java.io.IOException;

public class FileTest {
	public static void main(String[] args) {
		createNewFile();
	}
	public static void createNewFile() {
		File file = new File("D:/File/javaFile.txt");
		try {
			// 创建新的文件,前提是必须文件夹已经存在,即D:/File已经存在,文件夹名字不区分大小写:
			file.createNewFile();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

  (2) mkdir() / mkdirs():boolean;创建一个完整的路径,即包括所有的上层目录 ,前提是父文件夹已经存在;mkdirs()可以建立多级文件夹, mkdir()只会建立一级的文件夹。

import java.io.File;
public class FileTest {
	public static void main(String[] args) {
		createNewFile();
	}
	public static void createNewFile() {
		File file1 = new File("D:/File/java");
		File file2 = new File("D:/File/java/html");
		//只能创建一级文件夹,如果不小心写了多级,运行后不会报错,但是文件夹不会创建文件夹
		file1.mkdir();
		//可以创建多级文件夹
		file2.mkdirs();
	}
}

  (3) delete() :boolean:删除已存在的文件或文件夹,最终调用native本地方法 立即进行删除
  (4) deleteOnExit():boolean:调用后,不会立即删除,会等到虚拟机正常运行结束后,才去删除
  (5) delete() :boolean:删除已存在的文件或文件夹,最终调用native本地方法 立即进行删除
  (6) delete() :boolean:删除已存在的文件或文件夹,最终调用native本地方法 立即进行删除
  (7) exists() :boolean:判断文件是否存在,只写文件名就行,不需要写全路径
  (8) isFile() :boolean:判断是否是一个文件
  (9) isDirectory() :boolean:判断是否是一个文件夹

4、File类的常见方法

  (1) length():Int文件的大小。
  (2) getName():String:获取文件名。
  (3) getParent() :String:获取所在的文件夹的名字,如果沒有则返回null。
  (4) list():String[]:返回目录当前file对象代表的目录下所有文件、文件夹名。
  (5) getAbsolutePath():String :返回绝对路径。
  (6) getPath():String:创建时使用的是相对路径则返回相对路径,反之亦然。

/**
     * 详细步骤
     */
    private static void test1() {
        //获取文件的原始名称
        String originalFilename = "tim.hh.jpg";//timg (1).jpg
        //获取最后一个.的位置
        int lastIndexOf = originalFilename.lastIndexOf(".");
        //获取文件的后缀名 .jpg
        String suffix = originalFilename.substring(lastIndexOf);
        System.out.println("suffix = " + suffix);
    }
二、I/O的分类
1、按照方向分为:输入流 / 输出流

注意:以内存为参照物,从文件读取内容到内存的就是所谓的输
入流;从内存向文件中写入内容就是所谓的输出流。

2、按照内容分为:字节流 / 字符流
3、按照功能分为:节点流 / 过滤流
处理类型 字节(所有文件)
      Stream
字节(所有文件)
      Stream
字符(文本文件)
      Reader
字符(文本文件)
      Reader
备注
分类 输入流 输出流 输入流 输出流
抽象类 InputStream OutputStream
实现类 FileInputStream FileOutputStream
数据过滤流 DataStream抽象类
DataInputStream实现类
DataStream抽象类
DataOutputStream实现类
字节缓冲流 BufferedInputStream类 BufferedOutputStream类 很少使用
序列化 ObjectStream抽象类
ObjectInputStream实现类
ObjectStream抽象类
ObjectOutputStream实现类
readObject()方法
writeObject()方法
三、字节流

(一)、概念

  (1) 传输的数据单位是字节,也意味着字节流能够处理任何一种文件。

(二)、字节流的组成

1 输入流:InputStream抽象类

  (1) 将文件内容读入到程序。
  (2) 字节输入流:FileInputStream实现类
    ① 构造方法:FileInputStream(String filename)与FileInputStream(File file)
    ② int read() 方法

FileInputStream file = new FileInputStream("src/abc.txt");
System.out.println(file.read());
注意这里返回值的类型是int,指返回读取的内容的AskII码值,一次只能读一个字节 ,可以对其进行遍历输出:int 1en=0;
while( (len=in. read()) !=-1) {
System.out.println((char)len) ;                                       

    ③ 读取内容填充到b中,返回读取的长度:int read(byte[] buf)

byte b[] = new byte[10] ; 
while( (len=in. read(b))!=-1) {
for(int i=0;i<len;i++) {
System . out . print((char)b[i]);                                                       一次输出很多

    ④ 关闭流:close()

最好放到finally {
	fin.close();//省略代码
}代码块中

注意:为什么IO流需要关闭 ?
原因:需要close的东西,一般都是用了虚拟机之外的资源,例如端口,显存,文件等,虚拟机无法通过垃圾回收释放这些资源,只能你显式调用close方法来释放。许多情况下,如果在一些比较频繁的操作中,不对流进行关闭,很容易出现输入输出流超越了JVM的边界 ,所以有时可能无法回收资源。所以流操作的时候 凡是跨出虚拟机边界的资源都要求程序员自己关闭,不要指望垃圾回收。如果读一个文件,忘记关闭了流,你在操作系统里对这个文件的写,删除等操作就会报错,告诉你这个文件被某个进程占用。
    ⑤ read()方法逐个打印案例

public class InputStreamTest {
	public static void main(String[] args) {
		// 输入流对象要放到try外边声明,不然关闭的时候,finally块里面访问不到
		FileInputStream fi = null;
		try {
			fi = new FileInputStream("src/abc.txt");
			System.out.println(fi.read());
			System.out.println(fi.read());
			System.out.println(fi.read());
			System.out.println(fi.read());
			System.out.println(fi.read());

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				// 关闭输入流
				fi.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}
------------------------------------
输出内容
104
101
108
108
111
------------------------------------
abc.txt文件在src目录下,里面内容是;hello

    ⑥ 遍历文件输出内容

public class InputStreamTest {
	public static void main(String[] args) {
		// 输入流对象要放到try外边声明,不然关闭的时候,finally块里面访问不到
		FileInputStream fi = null;
		try {
			fi = new FileInputStream("src/abc.txt");
			int len = 0;
			// while遍历此文件
			while ((len = fi.read()) != -1) {
				System.out.print((char) len);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				// 关闭输入流
				fi.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}
2 输出流:OutputStream抽象类

  (1) 通过程序将内容写入到文件
  (2) 字节输出流:FileOutputStream实现类
    ① 构造方法:FileOutputStream(String path)与FileOutputStream(File file)
    ② FileOutputStream(String path, boolean append):可以指定覆盖或追加文件内容;默认是false,不能拼接,直接将原来的内容进行覆盖。

public class OutPutStreamTest {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		FileOutputStream f = null;
		try {
			while (true) {
				String str = scanner.nextLine();
				if (str.equals("exit")) {
					break;
				}
				// 将字符串转为字节数组
				byte[] byteArray = str.getBytes();
				// 设置参数为true,表示允许追加
				f = new FileOutputStream("src/abc.txt", true);
				// 调用write()方法将字节数组写入文件
				f.write(byteArray);
				f.close();
			}

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
}

    ③ write():Int:从输入流一个字节一个字节地写,返回的是读到的字节数。如果写到末尾,则返回-1
    ④ write(byte[] b):从输入流写若干字节,把这些字节保存到数组中,返回的是写到的字节数。如果写到末尾,则返回-1

public class OutPutStreamTest {
	public static void main(String[] args) {

		try {
			String str = "helloworld tom";
			// 将字符串转为字节数组
			byte[] byteArray = str.getBytes();
			FileOutputStream f = new FileOutputStream("src/abc.txt");
			// 调用write()方法将字节数组写入文件
			f.write(byteArray);
			f.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

    ⑤ write(byte[] b, int off, int len):从输入流写若干字节,把这些字节保存到数组中,off指的是字节数组中开始保存数据的其实下标,len指的是要写的长度,返回的是写到的字节数。如果写到末尾,则返回-1
    ⑥ close() 关闭流

最好放到finally {
	fin.close();//省略代码
}代码块中

    ⑦ flush() 强制将缓冲区清空
    ⑧ 新特性:try catch resource:将需要关闭的资源在try后边的括号中定义,这些资源会自动关闭,无需在finally块中手动调用close()方法,也无需处理关闭资源时的异常。只要是实现java.io.Closeable接口的类,都可以放到try后边的括号中实例化,最后这些资源都会被自动关闭。

public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		// 将需要关闭的资源放到try()里面, 设置参数为true,表示允许追加
		try (FileOutputStream f = new FileOutputStream("src/abc.txt", true);) {
			while (true) {
				String str = scanner.nextLine();
				if (str.equals("exit")) {
					break;
				}
				// 将字符串转为字节数组
				byte[] byteArray = str.getBytes();
				// 调用write()方法将字节数组写入文件
				f.write(byteArray);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
3、打印流:PrintStream类

(三)、数据过滤流:DataStream抽象类

1、DataInputStream类:从文件中读取指定数据类型的值:readXxx();
2、DataOutputStream类;向文件中写入指定数据类型的值:writeXxx();
3、过滤流的开发步骤

  (1) 创建节点流:即FileOutputStream与FileItputStream
  (2) 基于节点流创建过滤流
  (3) 读/写数据
  (4)关闭外层流

//数据输出过滤流,向文件中写数据
// 创建节点流
FileOutputStream fout = new FileOutputStream("pi.dat");
// 封装过滤流
DataOutputStream dout = new DataOutputStream(fout);
// 写数据
dout.writeDouble(3.14);
// 关闭外层流
dout.close();
---------------------------------------------------------------
//数据输入过滤流,从文件中读数据
// 创建节点流
FileInputStream fin = new FileInputStream("pi.dat");
// 封装过滤流
DataInputStream din = new DataInputStream(fin);
// 读数据
double pi = din.readDouble();
// 关闭外层流
din.close();

System.out.println(pi);

  (5) 注意:可以读入多个相同类型的数据,不会被覆盖,同时可以读入多个不同类型的数据,不能遍历数据过滤流,因为里面可存放不同的数据类型。

(四)、字节缓冲流(开发中很少使用)

1、作用:起缓冲作用
2、分类:

  (1) BufferedInputStream类
  (2) BufferedOutputStream类
  (3) 开发步骤

String data = "Hello World";
byte[] bs = data.getBytes();
// 创建节点流
FileOutputStream fout = new FileOutputStream("test.txt");
// 封装过滤流
BufferedOutputStream bout = new BufferedOutputStream(fout);
// 写数据
bout.write(bs);
// 关闭外层流
bout.close(); // bout.flush();

(五)、 序列化

1、前提:实现 Serializable接口

  (1) ObjectStream抽象类
    ① ObjectInputStream实现类
    ② ObjectOutputStream实现类
    ③ 读写对象:readObject()与writeObject()
注意:Serializable接口中没有方法,只是用来做一个标记:即声明该类的对象可以进行序列化。

2、对象序列化:把Java对象转换为字节序列的过程称为对象的序列化。即将对象写入文件:ObjectOutputStream类
3、对象反序列化:把字节序列恢复为Java对象的过程称为对象的反序列化。即从文件中读取序列,转换成对象:ObjectInputStream类
4、案例

  (1) Student类

public class Student implements Serializable {
	String name;
	int age;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}

}

  (2) ObjectStreamDemo类

public class ObjectStreamDemo {
	public static void main(String[] args) {
		// 读操作
		ObjectIn();
		// 写操作
		ObjectOut();

	}

	// 从文件读入内容到程序-》反序列化
	public static void ObjectIn() {
		try (FileInputStream fin = new FileInputStream("stu.data");
				ObjectInputStream oin = new ObjectInputStream(fin);) {
			Student stu1 = (Student) oin.readObject();
			Student stu2 = (Student) oin.readObject();
			Student stu3 = (Student) oin.readObject();
			System.out.println(stu1);
			System.out.println(stu2);
			System.out.println(stu3);
		} catch (Exception e) {
			// TODO: handle exception
		}
	}

	// 将内容写入文件-》序列化
	public static void ObjectOut() {
		Student stu1 = new Student("jerry", 20);
		Student stu2 = new Student("tom", 21);
		Student stu3 = new Student("mark", 18);
		try (FileOutputStream fout = new FileOutputStream("stu.data");
				ObjectOutputStream oout = new ObjectOutputStream(fout);) {

			oout.writeObject(stu1);
			oout.writeObject(stu2);
			oout.writeObject(stu3);
		} catch (IOException e) {
			// TODO: handle exception
		}
	}
}
---------------------------------------------------------
输出结果
Student [name=jerry, age=20]
Student [name=tom, age=21]
Student [name=mark, age=18]

5、注意

  (1) transient 关键字标注的属性不会被序列化

public class Student implements Serializable {
//将name属性用transient 关键字标注
	transient String name;
	int age;
}
-----------------------------------------------------------------
上面的程序输出为
Student [name=null, age=20]
Student [name=null, age=21]
Student [name=null, age=18]

  (2) 静态的属性不会被序列化
  (3) 如果一个对象的属性又是一个对象,则要求这个属性对象也实现了Serializable接口

四、字符流
1、字符编码

  (1) 编码:将字符转换为字节
  (2) 解码:将字节转换为字符
  (3) 乱码问题:编码时采用一种字符集,但是解码时使用了其他的字符集
    ① 编码和解码格式相同,则不会出现乱码问题

public class BianMa {
	public static void main(String[] args) {
		String str = "一起去爬山!";
		try {
			// 使用GBK编码
			byte[] barry = str.getBytes("GBK");
			// 使用GBK解码
			String str1 = new String(barry, "GBK");
			System.out.println(str1);

		} catch (Exception e) {
			// TODO: handle exception
		}
	}
}
--------------------------------------------------------------------
输出结果:
一起去爬山!

    ② 编码和解码格式不同,则会出现乱码问题

public class BianMa {
	public static void main(String[] args) {
		String str = "一起去爬山!";
		try {
			// 使用GBK编码
			byte[] barry = str.getBytes("GBK");
			// 使用UTF-8解码
			String str1 = new String(barry, "UTF-8");
			System.out.println(str1);

		} catch (Exception e) {
			// TODO: handle exception
		}
	}
}
----------------------------------------------------------------
输出结果:
?????????

  (4) 乱码的解决方案:使用错误的字符编码解码,然后再用错误的字符编码还原回byte[],最后再用正确的字符编码来解码,成功解决乱码问题

public class BianMa {
	public static void main(String[] args) {
		String str = "一起去爬山!";
		try {
			byte[] bytes = str.getBytes("GBK");// 编码
			// 使用错误的字符编码解码
			String errorStr = new String(bytes, "iso-8859-1");
			//输出错误的
			System.out.println(errorStr);

			// 使用错误的字符编码还原回byte[]
			byte[] bytes2 = errorStr.getBytes("iso-8859-1");
			// 再用正确的字符编码来解码,成功解决乱码问题
			String rightStr = new String(bytes2, "GBK");
			//输出正确的
			System.out.println(rightStr);

		} catch (Exception e) {
			// TODO: handle exception
		}
	}
}
-------------------------------------------------------
输出结果:
????????????
一起去爬山!

注意:注意,不能编码成utf-8后再进行转码,这样不能解决来乱码问题,因为utf-8采用1~6个字节对汉字进行编码,所以不确定每个汉字到底是几个字节

public class BianMa {
	public static void main(String[] args) {
		String str = "测试";
		try {
			// 编码
			byte[] bytes = str.getBytes("GBK");
			// 使用错误的字符编码解码
			String errorStr = new String(bytes, "utf-8");
			// 输出错误的
			System.out.println(errorStr);

			// 使用错误的字符编码还原回byte[]
			byte[] bytes2 = errorStr.getBytes("utf-8");
			// 再用正确的字符编码来解码,这里无法解决乱码问题, 原因是utf-8是变长的字符编码
			String rightStr = new String(bytes2, "GBK");
			// 输出utf-8转码后的
			System.out.println(rightStr);

		} catch (Exception e) {
			// TODO: handle exception
		}
	}
}
--------------------------------------------------
输出:
????
锟斤拷锟斤拷
2、InputStreamReader类 :字符输入流

  (1) 可以把一个字节流转换成一个字符流
在转换时可以执行编码方式
  (2) 在转换时可以执行编码方式
  (3) 构造方法:
    ① InputStreamReader(InputStream is)
    ② InputStreamReader(InputStream is, String charSet)
    ③ int read(char[] cbuf)

3、OutputStreamWriter类:字符输出流

  (1) 构造方法:
    ① OutputStreamWriter(OutputStream is)
    ② OutputStreamWriter(nOuputStream is, String charSet(指编码格式))
    ③ write(String value)

public class CharStreamDemo {
	static Scanner sc = new Scanner(System.in);

	public static void main(String[] args) {
		// writer();
		reader();

	}

	// 字符输出流
	public static void writer() {
		// 新特性,将需要关闭的流写入到try后面的()里面,系统会自动关闭,不需要手动调用close()方法关闭流
		// 参数true表示文件可追加内容
		try (FileOutputStream fout = new FileOutputStream("src/abc.txt", true);
				OutputStreamWriter writer = new OutputStreamWriter(fout, "GBK");)

		{
			while (true) {
				String str = sc.nextLine();
				if (str.equals("exit")) {
					break;
				}
				writer.write(str);
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 字符输入流
	public static void reader() {
		try (FileInputStream fin = new FileInputStream("src/abc.txt");
				InputStreamReader reader = new InputStreamReader(fin);) {
			char[] carry = new char[1024];
			int len = 0;
			while ((len = reader.read(carry)) != -1) {
				for (int i = 0; i < len; i++) {
					System.out.print(carry[i]);
				}
			}
		} catch (Exception e) {
			// TODO: handle exception
		}
	}
}
4、字符流过滤流

  (1) BufferedReader类
    ①字符过滤流、提供了缓冲功能可以一行一行的读取内容public String readLine()

//创建字节流
InputStream is = new FileInputStream("oracle.txt");
//创建字符流
InputStreamReader ir = new InputStreamReader(is);
//创建字符流过滤流
BufferedReader br = new BufferedReader(ir);

String value = null;
//每次读取一行
while ((value = br.readLine()) != null) {
	System.out.println(value);

  (2) BufferedWriter类
    ① 一行一行的写内容

public static void main(String[] args) {
try (
FileInputStream fin = new FileInputStream( " suny . txt " ) ;
InputStreamReader reader = new InputStreamReader(fin, "utf-8");
BufferedReader brReader = new BufferedReader(reader) ;)                                                                               {
String  str = nul1 ;
while( (str=brReader . readLine())!=nu11) {
System.out.println(str);
} catch (Exception e) {
e. printStackTrace();
}
5、PrintWriter类

  (1) 字符过滤流 、提供了缓冲功能、可以一行一行的输出内容
  (2) 第一种方式,比较灵活的方式

OutputStream output = new FileOutputStream("abc.txt", true);
Writer writer = new OutputStreamWriter(output, "utf-8");
PrintWriter printWriter = new PrintWriter(writer);

  (3) 第二种,不需要一层一层的封装流,但是这种方式不能设置字符添加,会直接将原来的内容给覆盖

PrintWriter printWriter = new PrintWriter("abc.txt", "utf-8");
6、完整的字符输入流的开发步骤

  (1) 创建节点流
  (2) 利用节点流创建字符流
  (3) 在字符流的基础上封装过滤流
  (4) 读/写数据

五、Properties类
1、作用:以key : value的形式存放数据,主要用于读取项目的配置文件,配置文件以.properties结尾的文件和xml文件myName= \u674E\u519B\u5E05 //转译字符,用来表示汉字age=18

注意:是用 = 连接

2、构造方法

  (1) Properties()
  (2) Properties(Properties defaults)

3、常用方法

  (1) setProperty(key,value) :往文件里面写数据
  (2) getProperty(key) :从文件里面读数据

Properties properties = new Properties();
 try {
  InputStream input = new FileInputStream("src/mytest.properties");
//InputStreamReader in = new InputStreamReader(input, "GBK");
	 properties.load(input);
	       System.out.println(properties.getProperty("myName"));
	       System.out.println(properties.getProperty("job"));
	} catch (Exception e) {
		e.printStackTrace();                                                     }
public class PropertiesDemo {
	public static void main(String[] args) {
		Properties properties = new Properties();

		try {
			// 从properties文件中读取数据
			// InputStream input = new FileInputStream("src/mytest.properties");
			// properties.load(input);
			// String name = properties.getProperty("myName");
			// System.out.println(name);
			// 向properties文件中写入数据
			URL url = PropertiesDemo.class.getClassLoader().getResource("mytest.properties");
			PrintStream ps = new PrintStream(new File(url.toURI()));
			properties.setProperty("phone", "123456");
			properties.setProperty("email", "123456@qq.com");
			properties.list(ps);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
六、NIO(New IO):实际开发很少用到
1、新IO介绍

  (1) 概念:新IO采用内存映射文件的方式来处理输入/输出,新IO将文件或文件的一段区域映射到内存中,这样就可以像访问内存一样访问文件。使用这种方式来进行输入/输出比传统的输入输出要快得多。
  (2) 方法:getChannel():获得管道
  (3) 相关包:
    ① java.nio
    ② java.nio.channels
    ③ java.nio.charset
    ④ java.nio.channels.spi
    ⑤ java.nio.charset.spi

2、案例:
FileChannel inChannel = null;
FileChannel outChannel = null;
File file1 = new File("channel1.txt");
File file2 = new File("channel2.txt");
try {
// 创建FileInputStream,以该文件创建输入流创建FileChannel
inChannel = new FileInputStream(file1).getChannel();
ByteBuffer byteBuffer = inChannel.map(
FileChannel.MapMode.READ_ONLY, 0, file1.length());
outChannel = new FileOutputStream(file2).getChannel();

// 将byteBuffer里的数据全部输出
outChannel.write(byteBuffer);
} catch (IOException e) {
	e.printStackTrace();
} finally {
	//省略关闭流代码
}
FileChannel inChannel = null;
File file = new File("channel1.txt");
try {
// 创建FileInputStream,以该文件创建输入流创建FileChannel
inChannel = new FileInputStream(file).getChannel();
ByteBuffer byteBuffer = inChannel.map(
FileChannel.MapMode.READ_ONLY, 0, file.length());
// 使用UTF-8字符集创建解码器
Charset charset = Charset.forName("UTF-8");
// 创建解码器
CharsetDecoder decoder = charset.newDecoder();
// 使用解码器将ByteBuffer转换成CharBuffer
CharBuffer buffer = decoder.decode(byteBuffer);
System.out.println(buffer);
} catch (IOException e) {
	e.printStackTrace();
} finally {
try {
if (inChannel != null) {
	inChannel.close();
}
} catch (IOException e) {
	e.printStackTrace();
}
}