1. File类
介绍
- java.io.File类:文件和文件目录路径的抽象表示形式,与平台无关
- File 能新建、删除、重命名文件和目录,但 File 不能访问文件内容本身。如果需要访问文件内容本身,则需要使用输入/输出流。
- 想要在Java程序中表示一个真实存在的文件或目录,那么必须有一个File对象,但是Java程序中的一个File对象,可能没有一个真实存在的文件或目录。
- File对象可以作为参数传递给流的构造器
常用构造器
public File(String pathname) public
File(String parent,String child)
public File(File parent,String child)
路径分隔符
路径中的每级目录之间用一个路径分隔符隔开, windows和DOS系统默认使用“\”来表示,UNIX和URL使用“/”来表示。Java程序支持跨平台运行,因此路径分隔符要慎用。为了解决这个隐患,File类提供了一个常量:public static final String separator。根据操作系统,动态的提供分隔符。
常用方法
栗子:筛选出以.txt结尾的文件,并打印文件名
- File data = new File("E:\\CODE\\review\\javaReview\\data");
- File[] files = data.listFiles();
- //帅选出后缀为.txt的文件,并打印
- for (File file : files) {
- String name = file.getName();
- if(name.contains(".txt")){
- System.out.println(name);
- }
- }
复制代码 2. IO流整体介绍
概述
I/O是Input/Output的缩写, I/O技术是非常实用的技术,用于处理设备之间的数据传输。如读/写文件,网络通讯等。Java程序中,对于数据的输入/输出操作以“流(stream)” 的
方式进行。 java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过标准的方法输入或输出数据。
输入input:读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中。
输出output:将程序(内存)数据输出到磁盘、光盘等存储设备中。
IO流的分类
IO流体系如下:
4大抽象基类的说明
输入流基类Inputstream & Reader
InputStream 和 Reader 是所有输入流的基类。InputStream的典型实现为FileInputStream,用于读取数据的常用方法如下:
- int read()
- int read(byte[] b)
- int read(byte[] b, int off, int len)
- //以上三个方法读取到流末尾时均会返回-1
复制代码 Reader的典型实现为FileReader,读取数据常用的方法如下:
- int read()
- int read(char [] c)
- int read(char [] c, int off, int len)
复制代码 FileInputStream 从文件系统中的某个文件中获得输入字节。FileInputStream用于读取非文本数据之类的原始字节流。要读取字符流,需要使用 FileReader。要注意的是,程序中打开的文件 IO 资源不属于内存里的资源,垃圾回收机制无法回收该资源,所以应该显式关闭文件 IO 资源。
输出流基类 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 对象作为参数,Writer额外的写出数据的方法如下:
void write(String str);
void write(String str, int off, int len);
FileOutputStream 从文件系统中的某个文件中获得输出字节。FileOutputStream用于写出非文本数据之类的原始字节流。要写出字符流,需要使用 FileWriter。
3. 节点流的使用
节点输入流:FileInputStream \ FileReader
节点输出流:FileOuputStream \ FileWriter
使用节点流读取文件的步骤:
- 建立一个流对象,将已存在的一个文件加载进流。
- 创建一个临时存放数据的数组。
- 调用流对象的读取方法将流中的数据读入到数组中。
- 关闭资源。
栗子1:使用FileReader读取文件内容并打印
- FileReader reader = null;
- try {
- reader = new FileReader(new File("E:\\CODE\\review\\javaReview\\data\\data1.txt"));
- char[] chars = new char[1024];
- int len ;
- while ((len = reader.read(chars)) != -1){
- System.out.println(new String(chars,0 ,len));
- }
- } catch (IOException e) {
- e.printStackTrace();
- }finally {
- try {
- reader.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
复制代码 栗子二:使用FileInputStream和FileOutputStream实现文件的复制
- FileInputStream fin = null;
- FileOutputStream fout = null;
- try {
- fin = new FileInputStream(new File("E:\\CODE\\review\\javaReview\\data\\01.jpg"));
- fout = new FileOutputStream(new File("E:\\CODE\\review\\javaReview\\data\\02.jpg"));
- byte[] buff = new byte[1024];
- int len;
- while ((len = fin.read(buff)) != -1){
- fout.write(buff,0, len);
- fout.flush();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }finally {
- try {
- fin.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- try {
- fout.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这些不是文本文件。
4. 处理流
4.1 缓冲流
为了提高数据读写的速度,Java API提供了带缓冲功能的流类,在使用这些流类时,会创建一个内部缓冲区数组,缺省使用8192个字节(8Kb)的缓冲区。缓冲流要“套接”在相应的节点流之上,根据数据操作单位可以把缓冲流分为:
- BufferedInputStream 和 BufferedOutputStream
- BufferedReader 和 BufferedWriter
当使用BufferedInputStream读取字节文件时,BufferedInputStream会一次性从文件中读取8192个(8Kb),存在缓冲区中,直到缓冲区装满了,才重新从文件中读取下一个8192个字节数组。向流中写入字节时,不会直接写到文件,先写到缓冲区中直到缓冲区写满,BufferedOutputStream才会把缓冲区中的数据一次性写到文件里。使用方法flush()可以强制将缓冲区的内容全部写入输出流。 关闭流的顺序和打开流的顺序相反。只要关闭最外层流即可,关闭最外层流也会相应关闭内层节点流。
栗子:使用BufferReader和BufferWriter实现文本文件的复制
- BufferedReader br = null;
- BufferedWriter bw = null;
- try {
- br = new BufferedReader(new FileReader("E:\\CODE\\review\\javaReview\\data\\data1.txt"));
- bw = new BufferedWriter(new FileWriter("E:\\CODE\\review\\javaReview\\data\\data3.txt"));
- String buff;
- while ((buff = br.readLine()) != null){
- bw.write(buff);
- bw.newLine();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }finally {
- try {
- br.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- try {
- bw.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
复制代码 4.2 转换流
转换流提供了在字节流和字符流之间的转换,Java API提供了两个转换流:
- InputStreamReader:将InputStream转换为Reader
- OutputStreamWriter:将Writer转换为OutputStream
InputStreamReader
- 实现将字节的输入流按指定字符集转换为字符的输入流。
- 需要和InputStream“套接”。
- 构造器
public InputStreamReader(InputStream in)
public InputSreamReader(InputStream in,String charsetName)
OutputStreamWriter
- 实现将字符的输出流按指定字符集转换为字节的输出流。
- 需要和OutputStream“套接”。
- 构造器
public OutputStreamWriter(OutputStream out)
public OutputSreamWriter(OutputStream out,String charsetName)
- FileInputStream fis = null;
- FileOutputStream fos = null;
- InputStreamReader isr = null;
- OutputStreamWriter osw = null;
- BufferedReader br = null;
- BufferedWriter bw = null;
- try {
- fis = new FileInputStream("E:\\CODE\\review\\javaReview\\data\\data1.txt");
- fos = new FileOutputStream("E:\\CODE\\review\\javaReview\\data\\data4.txt");
- //使用转换流转换
- isr = new InputStreamReader(fis);
- osw = new OutputStreamWriter(fos);
- br = new BufferedReader(isr);
- bw = new BufferedWriter(osw);
- String str;
- while ((str = br.readLine()) != null){
- bw.write(str);
- bw.newLine();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }finally {
- try {
- br.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- try {
- bw.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
复制代码 4.3 对象流
ObjectInputStream && OjbectOutputSteam对象流,用于存储和读取基本数据类型数据或对象的处理流,对象流的作用如下:
ObjectOutputStream:内存中的对象—>存储中的文件、通过网络传输出去:序列化过程
ObjectInputStream:存储中的文件、通过网络接收过来 —>内存中的对象:反序列化过程
对象的序列化
对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。
对象系列化步骤:
- 需要实现接口:Serializable
- 当前类提供一个全局常量:serialVersionUID
- 除了当前Person类需要实现Serializable接口之外,还必须保证其内部所属性 也必须是可序列化的。(默认情况下,基本数据类型可序列化)
栗子:
- @Test
- public void test1(){
- //测试对象序列化
- ObjectOutputStream oos = null;
- try {
- oos = new ObjectOutputStream(new FileOutputStream("object.dat"));
- oos.writeObject(new String("我爱中国!!"));
- oos.writeObject(new Student("1001","小强"));
- } catch (IOException e) {
- e.printStackTrace();
- }finally {
- try {
- oos.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- @Test
- public void test2(){
- //反序列化
- ObjectInputStream ois = null;
- try {
- ois = new ObjectInputStream(new FileInputStream("object.dat"));
- String str = (String)ois.readObject();
- System.out.println(str);
- Student stu = (Student)ois.readObject();
- System.out.println(stu);
- } catch (Exception e) {
- e.printStackTrace();
- }finally {
- }
- }
- public class Student implements Serializable {
- private static final long serialVersionUID = 12345678765432L;
- private String id;
- private String name;
- public Student(String id, String name) {
- this.id = id;
- this.name = name;
- }
- @Override
- public String toString() {
- return "Student{" +
- "id='" + id + '\'' +
- ", name='" + name + '\'' +
- '}';
- }
- }
复制代码 4.4 随机存储文件流
RandomAccessFile 声明在java.io包下,但直接继承于java.lang.Object类。并且它实现了DataInput、DataOutput这两个接口,也就意味着这个类既可以读也可以写。RandomAccessFile 类支持 “随机访问” 的方式,程序可以直接跳到文件的任意地方来读、写文件:
- 支持只访问文件的部分内容
- 可以向已存在的文件后追加内容
- RandomAccessFile 对象包含一个记录指针,用以标示当前读写处的位置。
RandomAccessFile 类对象可以自由移动记录指针:
- long getFilePointer():获取文件记录指针的当前位置
- void seek(long pos):将文件记录指针定位到 pos 位置
构造器
- public RandomAccessFile(File file, String mode)
- public RandomAccessFile(String name, String mode)
mode参数有如下4种:
r: 以只读方式打开
rw:打开以便读取和写入
rwd:打开以便读取和写入;同步文件内容的更新
rws:打开以便读取和写入;同步文件内容和元数据的更新
- @Test
- public void test3() throws IOException {
- RandomAccessFile raf1 = new RandomAccessFile("hello.txt","rw");
- raf1.seek(3);//将指针调到角标为3的位置
- //保存指针3后面的所数据到StringBuilder中
- StringBuilder builder = new StringBuilder((int) new File("hello.txt").length());
- byte[] buffer = new byte[20];
- int len;
- while((len = raf1.read(buffer)) != -1){
- builder.append(new String(buffer,0,len)) ;
- }
- //调回指针,写入“xyz”
- raf1.seek(3);
- raf1.write("xyz".getBytes());
- //将StringBuilder中的数据写入到文件中
- raf1.write(builder.toString().getBytes());
- raf1.close();
- }
复制代码 5. Path/Paths/Files的使用
NIO简单概述
- Java NIO (New IO,Non-Blocking IO)是从Java 1.4版本开始引入的一套新的IO API,可以替代标准的Java IO AP。
- NIO与原来的IO同样的作用和目的,但是使用的方式完全不同,NIO支持面向缓冲区的(IO是面向流的)、基于通道的IO操作。
- NIO将以更加高效的方式进行文件的读写操作。
- 随着 JDK 7 的发布,Java对NIO进行了极大的扩展,增强了对文件处理和文件系统特性的支持,以至于我们称他们为 NIO.2。
Path类:JDK7提供
实例化方法:
- static Path get(String first, String … more) : 用于将多个字符串串连成路径
- static Path get(URI uri): 返回指定uri对应的Path路径
Path 常用方法:
Files类:JDK7提供
用途:用于操作文件或目录的工具类
常用方法:
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |