1 文件操作
1.1 概念
File是数据源(保存数据的地方)的一种,可以表示一个文件,也可以表示一个文件目录。
File类只能对文件和文件夹进行创建和删除等操作,可以查看文件和文件夹的属性,不能读取或修改内容。如果需要读取或修改文件的内容,需要使用IO流。
常常将File类的对象作为参数传递到IO流的类的构造器中。
1.2 绝对路径和相对路径
绝对路径:绝对路径名是完整的路径名,不需要任何其他信息就可以定位它所表示的文件或文件夹。
相对路径:相对路径名必须使用取自其他路径名的信息进行解释。
相对路径创建的实例不等于绝对路径创建的实例。
1.3 常用方法
查看文件和文件夹:
1 // 获得文件名或目录名。 2 String getName(); 3 // 获得相对路径。 4 String getPath(); 5 // 获得绝对路径。 6 String getAbsolutePath();
创建或删除文件和文件夹:
1 // 创建一个空文件。 2 boolean createNewFile(); 3 // 创建一个空目录。 4 boolean mkdir(); 5 // 创建指定的目录及父目录。 6 boolean mkdirs(); 7 // 删除文件或空目录。 8 boolean delete();
常用的判断方法:
1 // 判断是否存在。 2 boolean exists(); 3 // 判断是否目录。 4 boolean isDirectory(); 5 // 判断是否文件。 6 boolean isFile();
1.4 常量
1.4.1 File.separator
与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串。此字符串只包含一个字符,即separatorChar。
separatorChar被初始化为包含系统属性file.separator值的第一个字符。在UNIX系统上,此字段的值为“/”;在Windows系统上,它为“\”。
1.4.2 File.pathSeparator
与系统有关的路径分隔符,为了方便,它被表示为一个字符串。此字符串只包含一个字符,即pathSeparatorChar。
pathSeparatorChar被初始为包含系统属性path.separator值的第一个字符。此字符用于分隔以路径列表形式给定的文件序列中的文件名。在UNIX系统上,此字段为“:”;在Windows系统上,它为“;”。
2 IO流
2.1 概念
流:数据在数据源(文件)和程序(内存)之间经历的路径。
以内存为参照,如果数据流向内存流动,则是输入流,反之,则是输出流。
文件和文件夹在程序中是以流的形式来操作的。
凡是与输入输出相关的都定义在java.io包下。
打开的资源不属于内存里的资源,垃圾回收机制无法回收该资源,所以应该显式关闭IO资源。不过在JDK1.7之后,可以在try代码块中打开流,最后程序会自动关闭流对象,不再需要显示地关闭流。
关闭流时只需要考虑关闭最外层的流即可,如果要强制关闭所有流,必须先关闭外层的流。
2.2 流的分类
按数据流的流向不同分为:输入流,输出流。
按操作数据单位不同分为:字节流(InputStream、OutputStream),字符流(Reader、Writer)。
按流的角色的不同分为:节点流,处理流。
3 文件流
文件流主要有:FileInputStream、FileOutputStream、FileReader、FileWriter。
这四个类是专门操作文件流的,用法高度相似,区别在于前面两个是操作字节流,后面两个是操作字符流。
它们都会直接操作文件流,直接与OS底层交互,因此他们也被称为节点流,节点流在输出时不需要考虑flush操作。
3.1 FileInputStream
3.1.1 构造方法
1 FileInputStream(File file); 2 FileInputStream(String name);
3.1.2 常用方法
1 // 从输入流中读入一个字节。 2 int read(); 3 // 从输入流中读入到数组。 4 int read(byte[] b); 5 // 从输入流中将len个数据读入到数组。 6 int read(byte[] b, int off, int len); 7 // 关闭输入流并释放系统资源。 8 void close();
3.1.3 读入文件到输入流
1 public void test() { 2 FileInputStream fis = null; 3 try { 4 fis = new FileInputStream(new File("D:" + File.separator + "hello.txt")); 5 byte[] buffer = new byte[1024]; 6 int len = 0; 7 String txt = ""; 8 while ((len = fis.read(buffer)) != -1) { 9 txt += new String(buffer, 0, len); 10 } 11 System.out.println(txt); 12 } catch (IOException e) { 13 e.printStackTrace(); 14 } finally { 15 if (fis != null) { 16 try { 17 fis.close(); 18 } catch (IOException e) { 19 e.printStackTrace(); 20 } 21 } 22 } 23 }
3.2 FileOutputStream
3.2.1 构造方法
1 FileOutputStream(File file); 2 FileOutputStream(File file, boolean append); 3 FileOutputStream(String name); 4 FileOutputStream(String name, boolean append);
3.2.2 常用方法
1 // 从指定字节中写出到输出流。 2 void write(int b); 3 // 从数组中写出到输出流。 4 void write(byte[] b); 5 // 从数组中将len个数据写出到输出流。 6 void write(byte[] b, int off, int len); 7 // 刷新该流的缓冲。 8 void flush(); 9 // 关闭输出流并释放系统资源。 10 void close();
3.2.3 读出文件到输出流
1 public void test() { 2 FileOutputStream fos = null; 3 try { 4 fos = new FileOutputStream(new File("D:" + File.separator + "hello.txt")); 5 fos.write("hello".getBytes()); 6 } catch (IOException e) { 7 e.printStackTrace(); 8 } finally { 9 if (fos != null) { 10 try { 11 fos.close(); 12 } catch (IOException e) { 13 e.printStackTrace(); 14 } 15 } 16 } 17 }
3.3 FileReader
3.3.1 构造方法
1 FileReader(File file); 2 FileReader(String fileName);
3.3.2 常用方法
1 // 返回此流使用的字符编码的名称。 2 String getEncoding(); 3 // 从输入流中读入一个字节。 4 int read(); 5 // 从输入流中读入到数组。 6 int read(char[] cbuf); 7 // 从输入流中将len个数据读入到数组。 8 int read(char[] cbuf, int off, int len); 9 // 关闭输入流并释放系统资源。 10 void close();
3.3.3 读入文本到输入流
1 public void test() { 2 FileReader fr = null; 3 try { 4 fr = new FileReader(new File("D:" + File.separator + "hello.txt")); 5 char[] buffer = new char[1024]; 6 int len = 0; 7 String txt = ""; 8 while ((len = fr.read(buffer)) != -1) { 9 txt = new String(buffer, 0, len); 10 } 11 System.out.print(txt); 12 } catch (IOException e) { 13 e.printStackTrace(); 14 } finally { 15 if (fr != null) { 16 try { 17 fr.close(); 18 } catch (IOException e) { 19 e.printStackTrace(); 20 } 21 } 22 } 23 }
3.4 FileWriter
3.4.1 构造方法
1 FileWriter(File file); 2 FileWriter(File file, boolean append); 3 FileWriter(String fileName); 4 FileWriter(String fileName, boolean append);
3.4.2 常用方法
1 // 返回此流使用的字符编码的名称。 2 String getEncoding(); 3 // 从指定字节中写出到输出流。 4 void write(int b); 5 // 从数组中写出到输出流。 6 void write(byte[] b); 7 // 从数组中将len个数据写出到输出流。 8 void write(byte[] b, int off, int len); 9 // 从字符串中写出到输出流。 10 void write(String str); 11 // 从字符串中将len个数据写出到输出流。 12 void write(String str, int off, int len); 13 // 刷新该流的缓冲。 14 void flush(); 15 // 关闭输出流并释放系统资源。 16 void close();
3.4.3 读出文本到输出流
1 public void test() { 2 FileWriter fw = null; 3 try { 4 fw = new FileWriter(new File("D:" + File.separator + "hello.txt")); 5 fw.write("hello"); 6 } catch (IOException e) { 7 e.printStackTrace(); 8 } finally { 9 if (fw != null) { 10 try { 11 fw.close(); 12 } catch (IOException e) { 13 e.printStackTrace(); 14 } 15 } 16 } 17 }
3.5 文件的复制
3.5.1 字节文件的复制
1 public void test() { 2 FileInputStream fis = null; 3 FileOutputStream fos = null; 4 try { 5 fis = new FileInputStream("D:" + File.separator + "old.jpeg"); 6 fos = new FileOutputStream("D:" + File.separator + "new.jpeg"); 7 byte[] buffer = new byte[1024]; 8 int len = 0; 9 while ((len = fis.read(buffer)) != -1) { 10 fos.write(buffer, 0, len); 11 } 12 } catch (IOException e) { 13 e.printStackTrace(); 14 } finally { 15 if (fis != null) { 16 try { 17 fis.close(); 18 } catch (IOException e) { 19 e.printStackTrace(); 20 } 21 } 22 if (fos != null) { 23 try { 24 fos.close(); 25 } catch (IOException e) { 26 e.printStackTrace(); 27 } 28 } 29 } 30 }
3.5.2 字符文件的复制
1 public void test() { 2 FileReader fr = null; 3 FileWriter fw = null; 4 try { 5 fr = new FileReader("D:" + File.separator + "old.txt"); 6 fw = new FileWriter("D:" + File.separator + "new.txt"); 7 char[] buffer = new char[1024]; 8 int len = 0; 9 while ((len = fr.read(buffer)) != -1) { 10 fw.write(buffer, 0, len); 11 } 12 } catch (IOException e) { 13 e.printStackTrace(); 14 } finally { 15 if (fr != null) { 16 try { 17 fr.close(); 18 } catch (IOException e) { 19 e.printStackTrace(); 20 } 21 } 22 if (fw != null) { 23 try { 24 fw.close(); 25 } catch (IOException e) { 26 e.printStackTrace(); 27 } 28 } 29 } 30 }
4 缓冲流
缓冲流主要有:BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter。
这四个类可以封装现有的节点流,实现对数据传输的效率的提升。
缓冲流比文件流多了一个缓冲区,执行read时先从缓冲区读取,当缓冲区数据读完时再把缓冲区填满。因此,当每次读取的数据量很小时,文件流每次都是从硬盘读入,而缓冲流大部分是从缓冲区读入。读取内存速度比读取硬盘速度快得多,因此缓冲流效率高。
缓冲流的默认缓冲区大小是8192字节。当每次读取数据量接近或远超这个值时,两者效率就没有明显差别了。
缓冲流属于处理流,在输出时需要考虑使用flush操作。
4.1 BufferedInputStream
4.1.1 构造方法
1 BufferedInputStream(InputStream in); 2 BufferedInputStream(InputStream in, int size);
4.1.2 常用方法
1 // 从输入流中读入一个字节。 2 int read(); 3 // 从输入流中读入到数组。 4 int read(byte[] b); 5 // 从输入流中将len个数据读入到数组。 6 int read(byte[] b, int off, int len); 7 // 关闭输入流并释放系统资源。 8 void close();
4.2 BufferedOutputStream
4.2.1 构造方法
1 BufferedOutputStream(OutputStream out); 2 BufferedOutputStream(OutputStream out, int size);
4.2.2 常用方法
1 // 从指定字节中写出到输出流。 2 void write(int b); 3 // 从数组中写出到输出流。 4 void write(byte[] b); 5 // 从数组中将len个数据写出到输出流。 6 void write(byte[] b, int off, int len); 7 // 刷新该流的缓冲。 8 void flush(); 9 // 关闭输出流并释放系统资源。 10 void close();
4.3 BufferedReader
4.3.1 构造方法
1 BufferedReader(Reader in); 2 BufferedReader(Reader in, int size);
4.3.2 常用方法
1 // 从输入流中读入一个字节。 2 int read(); 3 // 从输入流中读入到数组。 4 int read(char[] cbuf); 5 // 从输入流中将len个数据读入到数组。 6 int read(char[] cbuf, int off, int len); 7 // 关闭输入流并释放系统资源。 8 void close();
4.4 BufferedWriter
4.4.1 构造方法
1 BufferedWriter(Writer out); 2 BufferedWriter(Writer out, int size);
4.4.2 常用方法
1 // 从指定字节中写出到输出流。 2 void write(int c); 3 // 从数组中写出到输出流。 4 void write(char[] cbuf); 5 // 从数组中将len个数据写出到输出流。 6 void write(char[] cbuf, int off, int len); 7 // 从字符串中写出到输出流。 8 void write(String str); 9 // 从字符串中将len个数据写出到输出流。 10 void write(String str, int off, int len); 11 // 刷新该流的缓冲。 12 void flush(); 13 // 关闭输出流并释放系统资源。 14 void close();
4.5 文件的复制
4.5.1 字节文件的复制
1 public void test() { 2 BufferedInputStream bis = null; 3 BufferedOutputStream bos = null; 4 try { 5 bis = new BufferedInputStream(new FileInputStream("D:" + File.separator + "old.mp3")); 6 bos = new BufferedOutputStream(new FileOutputStream("D:" + File.separator + "new.mp3")); 7 byte[] buffer = new byte[1024]; 8 int len = 0; 9 while ((len = bis.read(buffer)) != -1) { 10 bos.write(buffer, 0, len); 11 } 12 } catch (IOException e) { 13 e.printStackTrace(); 14 } finally { 15 if (bis != null) { 16 try { 17 bis.close(); 18 } catch (IOException e) { 19 e.printStackTrace(); 20 } 21 } 22 if (bos != null) { 23 try { 24 bos.close(); 25 } catch (IOException e) { 26 e.printStackTrace(); 27 } 28 } 29 } 30 }
4.5.2 字符文件的复制
1 public void test() { 2 BufferedReader br = null; 3 BufferedWriter bw = null; 4 try { 5 br = new BufferedReader(new FileReader("D:" + File.separator + "old.txt")); 6 bw = new BufferedWriter(new FileWriter("D:" + File.separator + "new.txt")); 7 char[] buffer = new char[1024]; 8 int len = 0; 9 while ((len = br.read(buffer)) != -1) { 10 bw.write(buffer, 0, len); 11 } 12 } catch (IOException e) { 13 e.printStackTrace(); 14 } finally { 15 if (br != null) { 16 try { 17 br.close(); 18 } catch (IOException e) { 19 e.printStackTrace(); 20 } 21 } 22 if (bw != null) { 23 try { 24 bw.close(); 25 } catch (IOException e) { 26 e.printStackTrace(); 27 } 28 } 29 } 30 }
5 转换流
转换流主要有:InputStreamReader、OutputStreamWriter。
这两个流可以将文本在字节流和字符流之间进行转换,但只能处理文本文件。
5.1 InputStreamReader
5.1.1 构造方法
1 InputStreamReader(InputStream in); 2 InputStreamReader(InputStream in, String charsetName);
5.1.2 常用方法
1 // 返回此流使用的字符编码的名称。 2 String getEncoding(); 3 // 从输入流中读入一个字节。 4 int read(); 5 // 从输入流中读入到数组。 6 int read(char[] cbuf); 7 // 从输入流中将len个数据读入到数组。 8 int read(char[] cbuf, int off, int len); 9 // 关闭输入流并释放系统资源。 10 void close();
5.2 OutputStreamWriter
5.2.1 构造方法
1 OutputStreamWriter(OutputStream out); 2 OutputStreamWriter(OutputStream out, String charsetName);
5.2.2 常用方法
1 // 返回此流使用的字符编码的名称。 2 String getEncoding(); 3 // 从指定字节中写出到输出流。 4 void write(int c); 5 // 从数组中写出到输出流。 6 void write(char[] cbuf); 7 // 从数组中将len个数据写出到输出流。 8 void write(char[] cbuf, int off, int len); 9 // 从字符串中写出到输出流。 10 void write(String str); 11 // 从字符串中将len个数据写出到输出流。 12 void write(String str, int off, int len); 13 // 刷新该流的缓冲。 14 void flush(); 15 // 关闭输出流并释放系统资源。 16 void close();
5.3 文件的复制
1 public void test() { 2 InputStreamReader isr = null; 3 OutputStreamWriter osw = null; 4 try { 5 isr = new InputStreamReader(new FileInputStream("D:" + File.separator + "old.txt"), "UTF-8");// 确定解码集 6 osw = new OutputStreamWriter(new FileOutputStream("D:" + File.separator + "new.txt"), "UTF-8");// 确定编码集 7 char[] buffer = new char[20]; 8 int len = 0; 9 while ((len = isr.read(buffer)) != -1) { 10 osw.write(buffer, 0, len); 11 } 12 } catch (IOException e) { 13 e.printStackTrace(); 14 } finally { 15 if (isr != null) { 16 try { 17 isr.close(); 18 } catch (IOException e) { 19 e.printStackTrace(); 20 } 21 } 22 if (osw != null) { 23 try { 24 osw.close(); 25 } catch (IOException e) { 26 e.printStackTrace(); 27 } 28 } 29 } 30 }
6 内存读写流
内存读写流主要有:ByteArrayOutputStream、ByteArrayInputStream。
内存读写流将数组当作流输入输出对象的类。
不同于指向硬盘的流,它内部是使用字节数组读内存的,这个字节数组是它的成员变量,当这个数组不再使用变成垃圾的时候,Java的垃圾回收机制会将它回收,所以内存读写流不需要关流。
6.1 ByteArrayInputStream
6.1.1 构造方法
1 ByteArrayInputStream(byte[] b); 2 ByteArrayInputStream(byte[] b, int off, int len);
6.1.2 常用方法
1 // 从输入流中读入一个字节。 2 int read(); 3 // 从输入流中将len个数据读入到数组。 4 int read(byte[] b, int off, int len);
6.2 ByteArrayIOutputStream
6.2.1 构造方法
1 ByteArrayIOutputStream(); 2 ByteArrayIOutputStream(int size);
6.2.2 常用方法
1 // 从指定字节中写出到输出流。 2 void write(int b); 3 // 从数组中将len个数据写出到输出流。 4 void write(byte[] b, int off, int len); 5 // 将缓冲区内容转换字节数组。 6 byte toByteArray(); 7 // 将缓冲区内容转换为字符串。 8 String toString(); 9 // 将缓冲区内容转换为指定编码格式的字符串。 10 String toString(String charsetName); 11 // 将缓冲区内容输出到指定的输出流。 12 void writeTo(OutputStream out);
6.3 解决乱码
当用字节数组读取字符串时,受数组长度的影响,导致产生乱码。
如果用String类型接收,则不能完全解析出正常的文字,需要使用字节数组输出流将字节数组的内容输出到缓冲区,待读取完成后再转换为String类型的字符串。
1 public void test() { 2 ByteArrayInputStream bais = null; 3 ByteArrayOutputStream baos = null; 4 try { 5 bais = new ByteArrayInputStream("测试写入内容".getBytes()); 6 baos = new ByteArrayOutputStream(); 7 byte[] buffer = new byte[1]; 8 int len = -1; 9 String txt = ""; 10 while ((len = bais.read(buffer)) != -1) { 11 baos.write(buffer, 0, len); 12 txt += new String(buffer, 0, len); 13 } 14 System.out.println("正常:" + baos.toString()); 15 System.out.println("乱码:" + txt); 16 } catch (IOException e) { 17 e.printStackTrace(); 18 } 19 }
7 标准流
7.1 System.in
可以获取键盘输入的值,属于字节流。
获取方式:
1 static InputStream in;
7.2 System.out
可以将文本从控制台输出,属于字节流。
PrintStream是FileOutputStream下的子类,而FileOutputStream是OutputStream下的子类。
获取方式:
1 static PrintStream out;
7.3 获取输入内容
7.3.1 获取输入内容并显示在控制台
1 public void test() { 2 BufferedReader br = null; 3 try { 4 br = new BufferedReader(new InputStreamReader(System.in)); 5 System.out.println("请输入字符串:"); 6 System.out.println("输入的字符串为:" + br.readLine()); 7 } catch (IOException e) { 8 e.printStackTrace(); 9 } finally { 10 if (br != null) { 11 try { 12 br.close(); 13 } catch (IOException e) { 14 e.printStackTrace(); 15 } 16 } 17 } 18 }
7.3.2 将内容保存在文件
1 public void test() { 2 try { 3 System.out.println("这是输出到控制台的文字。"); 4 System.setOut(new PrintStream("D:" + File.separator + "input.txt")); 5 System.out.println("这是输出到文件里的文字。"); 6 } catch (IOException e) { 7 e.printStackTrace(); 8 } 9 }
7.3.3 从文件中读取内容
1 public void test() { 2 try { 3 System.setIn(new FileInputStream("D:" + File.separator + "output.txt")); 4 byte[] buffer = new byte[1024]; 5 int len = 0; 6 String str = ""; 7 while ((len = System.in.read(buffer)) != -1) { 8 str += new String(buffer, 0, len); 9 } 10 System.out.println(str); 11 } catch (IOException e) { 12 e.printStackTrace(); 13 } 14 }
8 对象流
对象流主要有:ObjectInputStream、ObjectOutputStream。
这两个类型都是字节流,可以处理所有文件,可以将内存中的对象保存到本地,也可以将本地的对象还原到内存中。
8.1 序列化
8.1.1 概念
对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,当其它程序获取了这种二进制流,就可以恢复成原来的Java对象。
如果想将一个对象进行网络传输,要求是该对象必须是可序列化的,该类必须实现Serializable接口或者Externalizable接口。
不能序列化static和transient修饰的属性。
8.1.2 好处
序列化的好处在于可将任何实现了Serializable接口的对象转化为字节数据,使其在保存和传输时可被还原。
序列化是远程方法调用(Remote Method Invoke)过程的参数和返回值都必须实现的机制,而RMI是JavaEE的基础,因此序列化机制是JavaEE平台的基础。
8.1.3 实现
序列化:用ObjectOutputStream类保存基本类型数据或对象的机制,因为是输出到文件里,所以是输出流。
反序列化:用ObjectInputStream类读取基本类型数据或对象的机制,因为将数据输入到内存里,所以是输入流。
8.1.4 手动序列化
进行序列化、反序列化时,虚拟机会首先试图调用对象里的writeObject和readObject方法,进行用户自定义的序列化和反序列化。
如果没有这样的方法,那么默认调用的是ObjectOutputStream的defaultWriteObject以及ObjectInputStream的defaultReadObject方法。
8.1.5 serialVersionUID
Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的。
在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常,即是InvalidCastException。
serialVersionUID有两种生成方式:默认的1L,生成一个64位的Hash字段。
8.2 ObjectInputStream
8.2.1 构造方法
1 ObjectInputStream(InputStream in);
8.2.2 常用方法
1 // 从输入流中读入一个字节。 2 int read(); 3 // 从输入流中读入到数组。 4 int read(byte[] buf); 5 // 从输入流中将len个数据读入到数组。 6 int read(byte[] buf, int off, int len); 7 // 使用UTF-8编码读取字符串。 8 String readUTF(); 9 // 读取要保存的变量。 10 Object readObject(); 11 // 默认的读取变量的方法。 12 void defaultReadObject(); 13 // 关闭输入流并释放系统资源。 14 void close();
8.2.3 反序列化实例
1 public void deserialize() { 2 try { 3 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:" + File.separator + "object.obj")); 4 System.out.println(ois.readInt()); 5 System.out.println(ois.readObject()); 6 System.out.println((Box) ois.readObject()); 7 ois.close(); 8 } catch (IOException e) { 9 e.printStackTrace(); 10 } 11 }
8.3 ObjectOutputStream
8.3.1 构造方法
1 DataOutputStream(OutputStream out);
8.3.2 常用方法
1 // 从指定字节中写出到输出流。 2 void write(int b); 3 // 从数组中写出到输出流。 4 void write(byte[] b); 5 // 从数组中将len个数据写出到输出流。 6 void write(byte[] b, int off, int len); 7 // 使用UTF-8编码写入字符串。 8 void writeUTF(String str); 9 // 写入要保存的变量。 10 void writeObject(Object obj); 11 // 默认的写入变量的方法。 12 void defaultWriteObject(); 13 // 刷新该流的缓冲。 14 void flush(); 15 // 关闭输出流并释放系统资源。 16 void close();
8.3.3 序列化实例
1 public void serialize() { 2 try { 3 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:" + File.separator + "object.obj")); 4 oos.writeInt(100); 5 oos.writeObject("String"); 6 oos.writeObject(new Box("box", 6, 8)); 7 oos.close(); 8 } catch (IOException e) { 9 e.printStackTrace(); 10 } 11 }
9 随机存取文件流
字节流,可以处理所有文件。
既可以充当输入流,又可以充当输出流。
若此将要输出文件不存在则尝试自动创建,并将内容输出到此文件中。若此将要输出的文件存在,则将对文件内容进行覆盖,默认从开头进行覆盖。
9.1 RandomAccessFile
9.1.1 构造方法
1 RandomAccessFile(File file, String mode); 2 RandomAccessFile(String name, String mode);
mode指定文件的访问模式:
r:以只读方式打开。
rw:打开以便读取和写入。
rws:还要求对文件的内容或元数据的更新都同步到底层存储设备。
rwd:还要求对文件内容的更新都同步到底层存储设备。
9.1.2 常用方法
1 // 从指定字节中写出到输出流。 2 void write(byte[] b); 3 // 从数组中写出到输出流。 4 void write(int b); 5 // 从数组中将len个数据写出到输出流。 6 void write(byte[] b, int off, int len); 7 // 从输入流中读入一个字节。 8 int read(); 9 // 从输入流中读入到数组。 10 int read(byte[] b); 11 // 从输入流中将len个数据读入到数组。 12 int read(byte[] b, int off, int len); 13 // 获取文件记录指针的当前位置。 14 long getFilePointer(); 15 // 将文件记录指针定位到pos位置。 16 void seek(long pos); 17 // 关闭流并释放系统资源。 18 void close();
9.1.3 复制文件
1 public void test() { 2 RandomAccessFile r = null; 3 RandomAccessFile w = null; 4 try { 5 r = new RandomAccessFile(new File("D:" + File.separator + "read.txt"), "r"); 6 w = new RandomAccessFile(new File("D:" + File.separator + "write.txt"), "rw"); 7 byte[] buffer = new byte[1024]; 8 int len = 0; 9 while ((len = r.read(buffer)) != -1) { 10 w.write(buffer, 0, len); 11 } 12 } catch (IOException e) { 13 e.printStackTrace(); 14 } finally { 15 if (r != null) { 16 try { 17 r.close(); 18 } catch (IOException e) { 19 e.printStackTrace(); 20 } 21 } 22 if (w != null) { 23 try { 24 w.close(); 25 } catch (IOException e) { 26 e.printStackTrace(); 27 } 28 } 29 } 30 }
9.1.4 插入内容
1 public void test() { 2 RandomAccessFile raf = null; 3 try { 4 raf = new RandomAccessFile("D:" + File.separator + "read.txt", "rw"); 5 raf.seek(3); 6 byte[] buffer = new byte[1024]; 7 int len = 0; 8 String str = ""; 9 while ((len = raf.read(buffer)) != -1) { 10 str += new String(buffer, 0, len); 11 } 12 raf.seek(3); 13 raf.write("read".getBytes()); 14 raf.write(str.getBytes()); 15 } catch (IOException e) { 16 e.printStackTrace(); 17 } finally { 18 try { 19 raf.close(); 20 } catch (IOException e) { 21 e.printStackTrace(); 22 } 23 } 24 }