网站建设方法冫金手指排名26,wordpress top主题,长沙百度推广运营公司,网站建设报价明细单Java进阶#xff08;下篇2#xff09;一、IO流01.File类的使用1.1、File类的实例化1.2、File类的常用方法11.3、File类的常用方法21.4、课后练习02、IO流原理及流的分类2.1、IO流原理2.2、流的分类2.3、IO 流体系03、节点流(或文件流)3.1、FileReader读入数据的基本操作3.2、…
Java进阶下篇2一、IO流01.File类的使用1.1、File类的实例化1.2、File类的常用方法11.3、File类的常用方法21.4、课后练习02、IO流原理及流的分类2.1、IO流原理2.2、流的分类2.3、IO 流体系03、节点流(或文件流)3.1、FileReader读入数据的基本操作3.2、FileReader中使用read(char[] cbuf)读入数据3.3、FileWriter写出数据的操作3.4、使用FileReader和FileWriter实现文本文件的复制3.5、使用FileInputStream不能读取文本文件的测试3.6、使用FileInputStream和FileOutputStream读写非文本文件3.7、使用FileInputStream和FileOutputStream复制文件的方法测试04、缓冲流4.1、缓冲流(字节型)实现非文本文件的复制4.2、缓冲流与节点流读写速度对比4.3、缓冲流(字符型)实现文本文件的复制5.4、缓冲流课后练习05、转换流5.1、转换流概述与InputStreamReader的使用5.2、转换流实现文件的读入和写出5.3、多种字符编码集的说明06、标准输入、输出流07、打印流08、数据流09、对象流9.1、对象序列化机制的理解9.2、对象流序列化与反序列化字符串操作9.3、自定义类实现序列化与反序列化操作9.4、serialVersionUID的理解9.5、自定义类可序列化的其它要求10.随机存取文件流10.1、RandomAccessFile实现数据的读写操作10.2、RandomAccessFile实现数据的插入操作11、NIO.2中Path、Paths、Files类的使用一、IO流
01.File类的使用
1.1、File类的实例化
P581
java.io.File类文件和文件目录路径的抽象表示形式与平台无关File 能新建、删除、重命名文件和目录但File 不能访问文件内容本身。如果需要访问文件内容本身则需要使用输入/输出流。想要在Java程序中表示一个真实存在的文件或目录那么必须有一个File对象但是Java程序中的一个File对象可能没有一个真实存在的文件或目录。File对象可以作为参数传递给流的构造器
import org.junit.Test;
import java.io.File;/*** File类的使用** 1. File类的一个对象代表一个文件或一个文件目录(俗称文件夹)* 2. File类声明在java.io包下**/
public class FileTest {/*** 1.如何创建file类的实例* File(String filePath):以filePath为路径创建File对象可以是绝对路径或者相对路径* File(String parentPath,String childPath):以parentPath为父路径childPath为子路径创建File对象。* File(File parentFile,String childPath):根据一个父File对象和子文件路径创建File对象* 2.* 相对路径相较于某个路径下指明的路径。* 绝对路径包含盘符在内的文件或文件目录的路径** 3.路径分隔符* windows:\\* unix:/* 4.Java程序支持跨平台运行因此路径分隔符要慎用。** 5.为了解决这个隐患File类提供了一个常量* public static final String separator。* 根据操作系统动态的提供分隔符。** File file1 new File(d:\\Work\\info.txt);* File file2 new File(d: File.separator Work File.separator info.txt);* File file3 new File(d:/Work);**/Testpublic void test(){//构造器1File file1 new File(hello.txt);//相对于当前moduleFile file2 new File(F:\\java\\Work2\\JavaSenior\\day08\\num.txt);System.out.println(file1);System.out.println(file2);//构造器2File file3 new File(D:\\workspace_idea1,JavaSenior);System.out.println(file3);//构造器3File file4 new File(file3,hi.txt);System.out.println(file4);}
}
1.2、File类的常用方法1
import org.junit.Test;import java.io.File;
import java.util.Date;/*** File类的使用** 1. File类的一个对象代表一个文件或一个文件目录(俗称文件夹)* 2. File类声明在java.io包下*/
public class FileTest {/*** public String getAbsolutePath()获取绝对路径* public String getPath() 获取路径* public String getName() 获取名称* public String getParent()获取上层文件目录路径。若无返回null* public long length() 获取文件长度即字节数。不能获取目录的长度。* public long lastModified() 获取最后一次的修改时间毫秒值** 如下的两个方法适用于文件目录* public String[] list() 获取指定目录下的所有文件或者文件目录的名称数组* public File[] listFiles() 获取指定目录下的所有文件或者文件目录的File数组*/Testpublic void test2(){File file new File(Hello.txt);File file2 new File(F:\\java\\Work2\\JavaSenior\\day08\\num.txt);System.out.println(file.getAbsolutePath());System.out.println(file.getPath());System.out.println(file.getName());System.out.println(file.getParent());System.out.println(file.length());System.out.println(new Date(file.lastModified()));System.out.println();System.out.println(file2.getAbsolutePath());System.out.println(file2.getPath());System.out.println(file2.getName());System.out.println(file2.getParent());System.out.println(file2.length());System.out.println(file2.lastModified());}Testpublic void test3(){//文件需存在File file new File(F:\\java\\Work2\\JavaSenior);String[] list file.list();for(String s : list){System.out.println(s);}System.out.println();File[] files file.listFiles();for(File f : files){System.out.println(f);}}/*** File类的重命名功能** public boolean renameTo(File dest):把文件重命名为指定的文件路径* 比如file1.renameTo(file2)为例* 要想保证返回true,需要file1在硬盘中是存在的且file2不能在硬盘中存在。*/Testpublic void test4(){File file1 new File(hello.txt);File file2 new File(D:\\book\\num.txt);boolean renameTo file2.renameTo(file1);System.out.println(renameTo);}
}
1.3、File类的常用方法2 import org.junit.Test;import java.io.File;
import java.io.IOException;
import java.util.Date;/*** File类的使用** 1. File类的一个对象代表一个文件或一个文件目录(俗称文件夹)* 2. File类声明在java.io包下* 3. File类中涉及到关于文件或文件目录的创建、删除、重命名、修改时间、文件大小等方法* 并未涉及到写入或读取文件内容的操作。如果需要读取或写入文件内容必须使用IO流来完成。* 4. 后续File类的对象常会作为参数传递到流的构造器中指明读取或写入的终点.*/
public class FileTest {/*** public boolean isDirectory()判断是否是文件目录* public boolean isFile() 判断是否是文件* public boolean exists() 判断是否存在* public boolean canRead() 判断是否可读* public boolean canWrite() 判断是否可写* public boolean isHidden() 判断是否隐藏*/Testpublic void test5(){File file1 new File(hello.txt);file1 new File(hello1.txt);System.out.println(file1.isDirectory());System.out.println(file1.isFile());System.out.println(file1.exists());System.out.println(file1.canRead());System.out.println(file1.canWrite());System.out.println(file1.isHidden());System.out.println();File file2 new File(D:\\book);file2 new File(D:\\book1);System.out.println(file2.isDirectory());System.out.println(file2.isFile());System.out.println(file2.exists());System.out.println(file2.canRead());System.out.println(file2.canWrite());System.out.println(file2.isHidden());}/*** 创建硬盘中对应的文件或文件目录* public boolean createNewFile() 创建文件。若文件存在则不创建返回false* public boolean mkdir() 创建文件目录。如果此文件目录存在就不创建了。如果此文件目录的上层目录不存在也不创建。* public boolean mkdirs() 创建文件目录。如果此文件目录存在就不创建了。如果上层文件目录不存在一并创建** 删除磁盘中的文件或文件目录* public boolean delete()删除文件或者文件夹* 删除注意事项Java中的删除不走回收站。*/Testpublic void test6() throws IOException {File file1 new File(hi.txt);if(!file1.exists()){//文件的创建file1.createNewFile();System.out.println(创建成功);}else{//文件存在file1.delete();System.out.println(删除成功);}}Testpublic void test7(){//文件目录的创建File file1 new File(d:\\io\\io1\\io3);boolean mkdir file1.mkdir();if(mkdir){System.out.println(创建成功1);}File file2 new File(d:\\io\\io1\\io4);boolean mkdir1 file2.mkdirs();if(mkdir1){System.out.println(创建成功2);}//要想删除成功io4文件目录下不能有子目录或文件File file3 new File(D:\\io\\io1\\io4);file3 new File(D:\\io\\io1);System.out.println(file3.delete());}
}
1.4、课后练习 1、FileTest类 import org.junit.Test;import java.io.File;
import java.io.IOException;/*** 1. 利用File构造器new一个文件目录file* 1)在其中创建多个文件和目录* 2)编写方法实现删除file中指定文件的操作*/
public class FileTest {Testpublic void test() throws IOException {File file new File(D:\\io\\io1\\hello.txt);//创建一个与file同目录下的另外一个文件文件名为haha.txtFile destFile new File(file.getParent(),haha.txt);boolean newFile destFile.createNewFile();if(newFile){System.out.println(创建成功);}}
} 2、FindJPGFileTest类 import org.junit.Test;import java.io.File;
import java.io.FilenameFilter;/*** 2.判断指定目录下是否有后缀名为.jpg的文件如果有就输出该文件名称*/
public class FindJPGFileTest {Testpublic void test(){File srcFile new File(d:\\code);String[] fileNames srcFile.list();for(String fileName : fileNames){if(fileName.endsWith(.jpg)){System.out.println(fileName);}}}Testpublic void test2(){File srcFile new File(d:\\code);File[] listFiles srcFile.listFiles();for(File file : listFiles){if(file.getName().endsWith(.jpg)){System.out.println(file.getAbsolutePath());}}}/*** File类提供了两个文件过滤器方法* public String[] list(FilenameFilter filter)* public File[] listFiles(FileFilter filter)*/Testpublic void test3(){File srcFile new File(d:\\code);File[] subFiles srcFile.listFiles(new FilenameFilter() {Overridepublic boolean accept(File dir, String name) {return name.endsWith(.jpg);}});for(File file : subFiles){System.out.println(file.getAbsolutePath());}}
} 3、ListFilesTest类 import java.io.File;/*** 3. 遍历指定目录所有文件名称包括子文件目录中的文件。* 拓展1并计算指定目录占用空间的大小* 拓展2删除指定文件目录及其下的所有文件*/
public class ListFilesTest {public static void main(String[] args) {// 递归:文件目录/** 打印出指定目录所有文件名称包括子文件目录中的文件 */// 1.创建目录对象File dir new File(E:\\teach\\01_javaSE\\_尚硅谷Java编程语言\\3_软件);// 2.打印目录的子文件printSubFile(dir);}public static void printSubFile(File dir) {// 打印目录的子文件File[] subfiles dir.listFiles();for (File f : subfiles) {if (f.isDirectory()) {// 文件目录printSubFile(f);} else {// 文件System.out.println(f.getAbsolutePath());}}}// 方式二循环实现// 列出file目录的下级内容仅列出一级的话// 使用File类的String[] list()比较简单public void listSubFiles(File file) {if (file.isDirectory()) {String[] all file.list();for (String s : all) {System.out.println(s);}} else {System.out.println(file 是文件);}}// 列出file目录的下级如果它的下级还是目录接着列出下级的下级依次类推// 建议使用File类的File[] listFiles()public void listAllSubFiles(File file) {if (file.isFile()) {System.out.println(file);} else {File[] all file.listFiles();// 如果all[i]是文件直接打印// 如果all[i]是目录接着再获取它的下一级for (File f : all) {listAllSubFiles(f);// 递归调用自己调用自己就叫递归}}}// 拓展1求指定目录所在空间的大小// 求任意一个目录的总大小public long getDirectorySize(File file) {// file是文件那么直接返回file.length()// file是目录把它的下一级的所有大小加起来就是它的总大小long size 0;if (file.isFile()) {size file.length();} else {File[] all file.listFiles();// 获取file的下一级// 累加all[i]的大小for (File f : all) {size getDirectorySize(f);// f的大小;}}return size;}// 拓展2删除指定的目录public void deleteDirectory(File file) {// 如果file是文件直接delete// 如果file是目录先把它的下一级干掉然后删除自己if (file.isDirectory()) {File[] all file.listFiles();// 循环删除的是file的下一级for (File f : all) {// f代表file的每一个下级deleteDirectory(f);}}// 删除自己file.delete();}
}
02、IO流原理及流的分类
2.1、IO流原理
I/O是Input/Output的缩写I/O技术是非常实用的技术用于处理设备之间的数据传输。如读/写文件网络通讯等。Java程序中对于数据的输入/输出操作以“流(stream)”的方式进行。java.io包下提供了各种“流”类和接口用以获取不同种类的数据并通过标准的方法输入或输出数据。输入input读取外部数据磁盘、光盘等存储设备的数据到程序内存中。输出output将程序内存数据输出到磁盘、光盘等存储设备中。
2.2、流的分类
按操作数据单位不同分为字节流(8 bit)字符流(16 bit)按数据流的流向不同分为输入流输出流按流的角色的不同分为节点流处理流 抽象基类 字节流 字符流 输入流 InputStream Reader 输出流 OutputStream Writer 1.Java的IO流共涉及40多个类实际上非常规则都是从如下4个抽象基类派生的。 2.由这四个类派生出来的子类名称都是以其父类名作为子类名后缀。 2.3、IO 流体系 03、节点流(或文件流)
3.1、FileReader读入数据的基本操作 1、读取文件【四个步骤】 1.建立一个流对象将已存在的一个文件加载进流。
FileReaderfr new FileReader(new File(“Test.txt”));2.创建一个临时存放数据的数组。
char[] ch new char[1024];3.调用流对象的读取方法将流中的数据读入到数组中。
fr.read(ch);4.关闭资源。
fr.close();import org.junit.Test;import java.io.File;
import java.io.FileReader;
import java.io.IOException;/*** 一、流的分类* 1.操作数据单位字节流、字符流* 2.数据的流向输入流、输出流* 3.流的角色节点流、处理流** 二、流的体系结构* 抽象基类 节点流或文件流 缓冲流处理流的一种* InputStream FileInputStream (read(byte[] buffer)) BufferedInputStream (read(byte[] buffer))* OutputStream FileOutputStream (write(byte[] buffer,0,len) BufferedOutputStream (write(byte[] buffer,0,len) / flush()* Reader FileReader (read(char[] cbuf)) BufferedReader (read(char[] cbuf) / readLine())* Writer FileWriter (write(char[] cbuf,0,len) BufferedWriter (write(char[] cbuf,0,len) / flush()*/
public class FileReaderWriterTest {public static void main(String[] args) {File file new File(hello.txt);//相较于当前工程System.out.println(file.getAbsolutePath());File file1 new File(day09\\hello.txt);System.out.println(file1.getAbsolutePath());}/*** 将day09下的hello.txt文件内容读入程序中并输出到控制台** 说明点* 1. read()的理解返回读入的一个字符。如果达到文件末尾返回-1* 2. 异常的处理为了保证流资源一定可以执行关闭操作。需要使用try-catch-finally处理* 3. 读入的文件一定要存在否则就会报FileNotFoundException。**/Testpublic void test(){FileReader fr null;try {//实例化File对象指明要操作的文件File file new File(hello.txt);//相较于当前的Module//2.提供具体的流fr new FileReader(file);//3.数据的读入过程//read():返回读入的一个字符。如果达到文件末尾返回-1.//方式一
// int data fr.read();
// while(data ! -1){
// System.out.print((char) data);
// data fr.read();
// }//方式二语法上针对于方式一的修改int data;while((data fr.read()) ! -1){System.out.print((char) data);}} catch (IOException e) {e.printStackTrace();}finally {//4.流的关闭操作
// try {
// if(fr ! null)
// fr.close();
// } catch (IOException e) {
// e.printStackTrace();
// }//或if(fr ! null){try {fr.close();} catch (IOException e) {e.printStackTrace();}}}}
}
3.2、FileReader中使用read(char[] cbuf)读入数据
import org.junit.Test;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;public class FileReaderWriterTest {//对read()操作升级使用read的重载方法Testpublic void test2(){FileReader fr null;try {//1.File类的实例化File file new File(hello.txt);//2.FileReader流的实例化fr new FileReader(file);//3.读入的操作//read(char[] cbuf):返回每次读入cbuf数组中的字符的个数。如果达到文件末尾返回-1char[] cbuf new char[5];int len;fr.read(cbuf);while((len fr.read(cbuf)) ! -1){//方式一//错误的写法
// for(int i 0;i cbuf.length;i){
// System.out.print(cbuf[i]);
// }//正确的写法
// for(int i 0;i len;i){
// System.out.print(cbuf[i]);
// }//方式二//错误的写法,对应着方式一的错误的写法
// String str new String(cbuf);
// System.out.print(str);//正确的写法String str new String(cbuf,0,len);System.out.print(str);}} catch (IOException e) {e.printStackTrace();}finally {if(fr ! null){//4.资源的关闭try {fr.close();} catch (IOException e) {e.printStackTrace();}}}}
}
3.3、FileWriter写出数据的操作 1、写入文件 1.创建流对象建立数据存放文件
FileWriterfw new FileWriter(new File(“Test.txt”));2.调用流对象的写入方法将数据写入流 fw.write(“atguigu-songhongkang”);3.关闭流资源并将流中的数据清空到文件中。
fw.close();import org.junit.Test;
import java.io.*;public class FileReaderWriterTest {/*** 从内存中写出数据到硬盘的文件里。** 说明* 1.输出操作对应的File可以不存在的。并不会报异常* 2.* File对应的硬盘中的文件如果不存在在输出的过程中会自动创建此文件。* File对应的硬盘中的文件如果存在* 如果流使用的构造器是FileWriter(file,false) / FileWriter(file):对原有文件的覆盖* 如果流使用的构造器是FileWriter(file,true):不会对原有文件覆盖而是在原有文件基础上追加内容*/Testpublic void test3(){ FileWriter fw null;try {//1.提供File类的对象指明写出到的文件File file new File(hello1.txt);//2.提供FileWriter的对象用于数据的写出fw new FileWriter(file,false);//3.写出的操作fw.write(I have a dream!\n);fw.write(you need to have a dream!);} catch (IOException e) {e.printStackTrace();} finally {//4.流资源的关闭if(fw ! null){try {fw.close();} catch (IOException e) {e.printStackTrace();}}}}
}
3.4、使用FileReader和FileWriter实现文本文件的复制
import org.junit.Test;
import java.io.*;public class FileReaderWriterTest {Testpublic void test4() {FileReader fr null;FileWriter fw null;try {//1.创建File类的对象指明读入和写出的文件File srcFile new File(hello1.txt);File srcFile2 new File(hello2..txt);//不能使用字符流来处理图片等字节数据
// File srcFile new File(爱情与友情.jpg);
// File srcFile2 new File(爱情与友情1.jpg);//2.创建输入流和输出流的对象fr new FileReader(srcFile);fw new FileWriter(srcFile2);//3.数据的读入和写出操作char[] cbuf new char[5];int len;//记录每次读入到cbuf数组中的字符的个数while((len fr.read(cbuf)) ! -1){//每次写出len个字符fw.write(cbuf,0,len);}} catch (IOException e) {e.printStackTrace();} finally {//4.关闭流资源//方式一
// try {
// if(fw ! null)
// fw.close();
// } catch (IOException e) {
// e.printStackTrace();
// }finally{
// try {
// if(fr ! null)
// fr.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }//方式二try {if(fw ! null)fw.close();} catch (IOException e) {e.printStackTrace();}try {if(fr ! null)fr.close();} catch (IOException e) {e.printStackTrace();}}}
}
3.5、使用FileInputStream不能读取文本文件的测试
import org.junit.Test;import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;/*** 测试FileInputStream和FileOutputStream的使用** 结论* 1. 对于文本文件(.txt,.java,.c,.cpp)使用字符流处理* 2. 对于非文本文件(.jpg,.mp3,.mp4,.avi,.doc,.ppt,...)使用字节流处理*/
public class FileIOPutTest {//使用字节流FileInputStream处理文本文件可能出现乱码。Testpublic void testFileInputStream(){FileInputStream fis null;try {//1.造文件File file new File(hello.txt);//2.造流fis new FileInputStream(file);//3.读数据byte[] buffer new byte[5];int len;//记录每次读取的字节的个数while((len fis.read(buffer)) ! -1){String str new String(buffer,0,len);System.out.print(str);}} catch (IOException e) {e.printStackTrace();}finally {if(fis ! null) {//4.关闭资源try {fis.close();} catch (IOException e) {e.printStackTrace();}}}}
}
3.6、使用FileInputStream和FileOutputStream读写非文本文件
import org.junit.Test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;public class FileIOPutTest {/*** 实现对图片的复制操作*/Testpublic void testFileInputOutputStream() {FileInputStream fis null;FileOutputStream fos null;try {//1.造文件File srcFile new File(爱情与友情.jpg);File destFile new File(爱情与友情2.jpg);//2.造流fis new FileInputStream(srcFile);fos new FileOutputStream(destFile);//3.复制的过程byte[] buffer new byte[5];int len;//4.读数据while((len fis.read(buffer)) ! -1){fos.write(buffer,0,len);}System.out.println(复制成功);} catch (IOException e) {e.printStackTrace();} finally {if(fos ! null){//5.关闭资源try {fos.close();} catch (IOException e) {e.printStackTrace();}}if(fis ! null){try {fis.close();} catch (IOException e) {e.printStackTrace();}}}}
}
3.7、使用FileInputStream和FileOutputStream复制文件的方法测试
import org.junit.Test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;public class FileIOPutTest {//指定路径下文件的复制public void copyFile(String srcPath,String destPath){FileInputStream fis null;FileOutputStream fos null;try {//File srcFile new File(srcPath);File destFile new File(destPath);//fis new FileInputStream(srcFile);fos new FileOutputStream(destFile);//复制的过程byte[] buffer new byte[1024];int len;while((len fis.read(buffer)) ! -1){fos.write(buffer,0,len);}} catch (IOException e) {e.printStackTrace();} finally {if(fos ! null){//try {fos.close();} catch (IOException e) {e.printStackTrace();}}if(fis ! null){try {fis.close();} catch (IOException e) {e.printStackTrace();}}}}Testpublic void testCopyFile(){long start System.currentTimeMillis();// String srcPath C:\\Users\\29433\\Desktop\\164.jpg;
// String destPath C:\\Users\\29433\\Desktop\\164.jpg;String srcPath hello.txt;String destPath hello3.txt;copyFile(srcPath,destPath);long end System.currentTimeMillis();System.out.println(复制操作花费的时间为 (end - start));//1}
}
04、缓冲流
为了提高数据读写的速度Java API提供了带缓冲功能的流类在使用这些流类时会创建一个内部缓冲区数组缺省使用8192个字节(8Kb)的缓冲区。 缓冲流要“套接”在相应的节点流之上根据数据操作单位可以把缓冲流分为 BufferedInputStream和BufferedOutputStream BufferedReader和BufferedWriter当读取数据时数据按块读入缓冲区其后的读操作则直接访问缓冲区当使用BufferedInputStream读取字节文件时BufferedInputStream会一次性从文件中读取8192个(8Kb)存在缓冲区中直到缓冲区装满了才重新从文件中读取下一个8192个字节数组。向流中写入字节时不会直接写到文件先写到缓冲区中直到缓冲区写满BufferedOutputStream才会把缓冲区中的数据一次性写到文件里。使用方法flush()可以强制将缓冲区的内容全部写入输出流关闭流的顺序和打开流的顺序相反。只要关闭最外层流即可关闭最外层流也会相应关闭内层节点流flush()方法的使用手动将buffer中内容写入文件如果是带缓冲区的流对象的close()方法不但会关闭流还会在关闭流之前刷新缓冲区关闭后不能再写出。
4.1、缓冲流(字节型)实现非文本文件的复制
import org.junit.Test;import java.io.*;/*** 处理流之一缓冲流的使用** 1.缓冲流* BufferedInputStream* BufferedOutputStream* BufferedReader* BufferedWriter*/
public class BufferedTest {/*** 实现非文本文件的复制*/Testpublic void BufferedStreamTest(){BufferedInputStream bis null;BufferedOutputStream bos null;try {//1.造文件File srcFile new File(爱情与友情.jpg);File destFile new File(爱情与友情3.jpg);//2.造流//2.1 造节点流FileInputStream fis new FileInputStream((srcFile));FileOutputStream fos new FileOutputStream(destFile);//2.2 造缓冲流bis new BufferedInputStream(fis);bos new BufferedOutputStream(fos);//3.复制的细节读取、写入byte[] buffer new byte[10];int len;while((len bis.read(buffer)) ! -1){bos.write(buffer,0,len);
// bos.flush();//刷新缓冲区}} catch (IOException e) {e.printStackTrace();} finally {//4.资源关闭//要求先关闭外层的流再关闭内层的流if(bos ! null){try {bos.close();} catch (IOException e) {e.printStackTrace();}}if(bis ! null){try {bis.close();} catch (IOException e) {e.printStackTrace();}}//说明关闭外层流的同时内层流也会自动的进行关闭。关于内层流的关闭我们可以省略.
// fos.close();
// fis.close();}}
}
4.2、缓冲流与节点流读写速度对比
import org.junit.Test;
import java.io.*;
/*** 处理流之一缓冲流的使用** 1.缓冲流* BufferedInputStream* BufferedOutputStream* BufferedReader* BufferedWriter** 2.作用提供流的读取、写入的速度* 提高读写速度的原因内部提供了一个缓冲区** 3. 处理流就是“套接”在已有的流的基础上。**/
public class BufferedTest {//实现文件复制的方法public void copyFileWithBuffered(String srcPath,String destPath){BufferedInputStream bis null;BufferedOutputStream bos null;try {//1.造文件File srcFile new File(srcPath);File destFile new File(destPath);//2.造流//2.1 造节点流FileInputStream fis new FileInputStream((srcFile));FileOutputStream fos new FileOutputStream(destFile);//2.2 造缓冲流bis new BufferedInputStream(fis);bos new BufferedOutputStream(fos);//3.复制的细节读取、写入byte[] buffer new byte[1024];int len;while((len bis.read(buffer)) ! -1){bos.write(buffer,0,len);}} catch (IOException e) {e.printStackTrace();} finally {//4.资源关闭//要求先关闭外层的流再关闭内层的流if(bos ! null){try {bos.close();} catch (IOException e) {e.printStackTrace();}}if(bis ! null){try {bis.close();} catch (IOException e) {e.printStackTrace();}}//说明关闭外层流的同时内层流也会自动的进行关闭。关于内层流的关闭我们可以省略.
// fos.close();
// fis.close();}}Testpublic void testCopyFileWithBuffered(){long start System.currentTimeMillis();String srcPath C:\\Users\\29433\\Desktop\\book.flv;String destPath C:\\Users\\29433\\Desktop\\book1.flv;copyFileWithBuffered(srcPath,destPath);long end System.currentTimeMillis();System.out.println(复制操作花费的时间为 (end - start));//1}}
4.3、缓冲流(字符型)实现文本文件的复制
import org.junit.Test;
import java.io.*;public class BufferedTest {/*** 使用BufferedReader和BufferedWriter实现文本文件的复制*/Testpublic void test4(){BufferedReader br null;BufferedWriter bw null;try {//创建文件和相应的流br new BufferedReader(new FileReader(new File(dbcp.txt)));bw new BufferedWriter(new FileWriter(new File(dbcp1.txt)));//读写操作//方式一使用char[]数组
// char[] cbuf new char[1024];
// int len;
// while((len br.read(cbuf)) ! -1){
// bw.write(cbuf,0,len);
// // bw.flush();
// }//方式二使用StringString data;while((data br.readLine()) ! null){//方法一
// bw.write(data \n);//data中不包含换行符//方法二bw.write(data);//data中不包含换行符bw.newLine();//提供换行的操作}} catch (IOException e) {e.printStackTrace();} finally {//关闭资源if(bw ! null){try {bw.close();} catch (IOException e) {e.printStackTrace();}}if(br ! null){try {br.close();} catch (IOException e) {e.printStackTrace();}}}}
}
5.4、缓冲流课后练习 1、练习2 package git;import org.junit.Test;import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;public class PicTest {//图片的加密Testpublic void test() {FileInputStream fis null;FileOutputStream fos null;try {fis new FileInputStream(爱情与友情.jpg);fos new FileOutputStream(爱情与友情secret.jpg);byte[] buffer new byte[20];int len;while ((len fis.read(buffer)) ! -1) {//字节数组进行修改//错误的// for(byte b : buffer){// b (byte) (b ^ 5);// }//正确的for (int i 0; i len; i) {buffer[i] (byte) (buffer[i] ^ 5);}fos.write(buffer, 0, len);}} catch (IOException e) {e.printStackTrace();} finally {if (fos ! null) {try {fos.close();} catch (IOException e) {e.printStackTrace();}}if (fis ! null) {try {fis.close();} catch (IOException e) {e.printStackTrace();}}}}//图片的解密Testpublic void test2() {FileInputStream fis null;FileOutputStream fos null;try {fis new FileInputStream(爱情与友情secret.jpg);fos new FileOutputStream(爱情与友情4.jpg);byte[] buffer new byte[20];int len;while ((len fis.read(buffer)) ! -1) {//字节数组进行修改//错误的// for(byte b : buffer){// b (byte) (b ^ 5);// }//正确的for (int i 0; i len; i) {buffer[i] (byte) (buffer[i] ^ 5);}fos.write(buffer, 0, len);}} catch (IOException e) {e.printStackTrace();} finally {if (fos ! null) {try {fos.close();} catch (IOException e) {e.printStackTrace();}}if (fis ! null) {try {fis.close();} catch (IOException e) {e.printStackTrace();}}}}
} 2、练习3 import org.junit.Test;import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;/*** 练习3:获取文本上字符出现的次数,把数据写入文件** 思路* 1.遍历文本每一个字符* 2.字符出现的次数存在Map中** MapCharacter,Integer map new HashMapCharacter,Integer();* map.put(a,18);* map.put(你,2);** 3.把map中的数据写入文件*/
public class WordCount {/*** 说明如果使用单元测试文件相对路径为当前module* 如果使用main()测试文件相对路径为当前工程*/Testpublic void testWordCount() {FileReader fr null;BufferedWriter bw null;try {//1.创建Map集合MapCharacter, Integer map new HashMapCharacter, Integer();//2.遍历每一个字符,每一个字符出现的次数放到map中fr new FileReader(dbcp.txt);int c 0;while ((c fr.read()) ! -1) {//int 还原 charchar ch (char) c;// 判断char是否在map中第一次出现if (map.get(ch) null) {map.put(ch, 1);} else {map.put(ch, map.get(ch) 1);}}//3.把map中数据存在文件count.txt//3.1 创建Writerbw new BufferedWriter(new FileWriter(wordcount.txt));//3.2 遍历map,再写入数据SetMap.EntryCharacter, Integer entrySet map.entrySet();for (Map.EntryCharacter, Integer entry : entrySet) {switch (entry.getKey()) {case :bw.write(空格 entry.getValue());break;case \t://\t表示tab 键字符bw.write(tab键 entry.getValue());break;case \r://bw.write(回车 entry.getValue());break;case \n://bw.write(换行 entry.getValue());break;default:bw.write(entry.getKey() entry.getValue());break;}bw.newLine();}} catch (IOException e) {e.printStackTrace();} finally {//4.关流if (fr ! null) {try {fr.close();} catch (IOException e) {e.printStackTrace();}}if (bw ! null) {try {bw.close();} catch (IOException e) {e.printStackTrace();}}}}
}
05、转换流
5.1、转换流概述与InputStreamReader的使用 import org.junit.Test;import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;/*** 处理流之二转换流的使用* 1.转换流属于字符流* InputStreamReader将一个字节的输入流转换为字符的输入流* OutputStreamWriter将一个字符的输出流转换为字节的输出流** 2.作用提供字节流与字符流之间的转换** 3.解码字节、字节数组 ---字符数组、字符串* 编码字符数组、字符串 --- 字节、字节数组** 4.字符集*/
public class InputStreamReaderTest {/*** 此时处理异常的话仍然应该使用try-catch-finally* InputStreamReader的使用实现字节的输入流到字符的输入流的转换*/Testpublic void test() throws IOException {FileInputStream fis new FileInputStream(dbcp.txt);
// InputStreamReader isr new InputStreamReader(fis);//使用系统默认的字符集//参数2指明了字符集具体使用哪个字符集取决于文件dbcp.txt保存时使用的字符集InputStreamReader isr new InputStreamReader(fis,UTF-8);//使用系统默认的字符集char[] cbuf new char[20];int len;while((len isr.read(cbuf)) ! -1){String str new String(cbuf,0,len);System.out.print(str);}isr.close();}}
5.2、转换流实现文件的读入和写出
import org.junit.Test;import java.io.*;/*** 处理流之二转换流的使用* 1.转换流属于字符流* InputStreamReader将一个字节的输入流转换为字符的输入流* OutputStreamWriter将一个字符的输出流转换为字节的输出流** 2.作用提供字节流与字符流之间的转换** 3.解码字节、字节数组 ---字符数组、字符串* 编码字符数组、字符串 --- 字节、字节数组** 4.字符集*/
public class InputStreamReaderTest {/*** 此时处理异常的话仍然应该使用try-catch-finally* 综合使用InputStreamReader和OutputStreamWriter*/Testpublic void test2() throws IOException {//1.造文件、造流File file1 new File(dbcp.txt);File file2 new File(dbcp_gbk.txt);FileInputStream fis new FileInputStream(file1);FileOutputStream fos new FileOutputStream(file2);InputStreamReader isr new InputStreamReader(fis,utf-8);OutputStreamWriter osw new OutputStreamWriter(fos,gbk);//2.读写过程char[] cbuf new char[20];int len;while((len isr.read(cbuf)) ! -1){osw.write(cbuf,0,len);}//3.关闭资源isr.close();osw.close();}
}
5.3、多种字符编码集的说明 1、编码表的由来 计算机只能识别二进制数据早期由来是电信号。为了方便应用计算机让它可以识别各个国家的文字。就将各个国家的文字用数字来表示并一一对应形成一张表。这就是编码表。 2、常见的编码表 /*** 4.字符集* ASCII美国标准信息交换码。* 用一个字节的7位可以表示。* ISO8859-1拉丁码表。欧洲码表* 用一个字节的8位表示。* GB2312中国的中文编码表。最多两个字节编码所有字符* GBK中国的中文编码表升级融合了更多的中文文字符号。最多两个字节编码* Unicode国际标准码融合了目前人类使用的所有字符。为每个字符分配唯一的字符码。所有的文字都用两个字节来表示。* UTF-8变长的编码方式可用1-4个字节来表示一个字符。*/ 说明 Unicode不完美这里就有三个问题 一个是我们已经知道英文字母只用一个字节表示就够了 第二个问题是如何才能区别Unicode和ASCII计算机怎么知道两个字节表示一个符号而不是分别表 示两个符号呢 第三个如果和GBK等双字节编码方式一样用最高位是1或0表示两个字节和一个字节就少了很多值无法用于表示字符不够表示所有字符。Unicode在很长一段时间内无法推广直到互联网的出现。面向传输的众多UTFUCS Transfer Format标准出现了顾名思义**UTF-8就是每次8个位传输数据而UTF-16就是每次16个位。**这是为传输而设计的编码并使编码无国界这样就可以显示全世界上所有文化的字符了。Unicode只是定义了一个庞大的、全球通用的字符集并为每个字符规定了唯一确定的编号具体存储成什么样的字节流取决于字符编码方案。推荐的Unicode编码是UTF-8和UTF-16。 06、标准输入、输出流 import org.junit.Test;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;/*** 其他流的使用* 1.标准的输入、输出流* 2.打印流* 3.数据流*/
public class OtherStreamTest {/*** 1.标准的输入、输出流* 1.1* System.in:标准的输入流默认从键盘输入* System.out:标准的输出流默认从控制台输出* 1.2* System类的setIn(InputStream is) / setOut(PrintStream ps)方式重新指定输入和输出的流。** 1.3练习* 从键盘输入字符串要求将读取到的整行字符串转成大写输出。然后继续进行输入操作* 直至当输入“e”或者“exit”时退出程序。** 方法一使用Scanner实现调用next()返回一个字符串* 方法二使用System.in实现。System.in --- 转换流 --- BufferedReader的readLine()*/Testpublic void test(){BufferedReader br null;try {InputStreamReader isr new InputStreamReader(System.in);br new BufferedReader(isr);while (true) {System.out.println(请输入字符串);String data br.readLine();if (e.equalsIgnoreCase(data) || exit.equalsIgnoreCase(data)) {System.out.println(程序结束);break;}String upperCase data.toUpperCase();System.out.println(upperCase);}} catch (IOException e) {e.printStackTrace();} finally {if (br ! null) {try {br.close();} catch (IOException e) {e.printStackTrace();}}}}
}
07、打印流 import org.junit.Test;
import java.io.*;public class OtherStreamTest {/*** 2. 打印流PrintStream 和PrintWriter* 2.1 提供了一系列重载的print() 和 println()* 2.2 练习*/Testpublic void test2(){PrintStream ps null;try {FileOutputStream fos new FileOutputStream(new File(D:\\IO\\text.txt));// 创建打印输出流,设置为自动刷新模式(写入换行符或字节 \n 时都会刷新输出缓冲区)ps new PrintStream(fos, true);if (ps ! null) {// 把标准输出流(控制台输出)改成文件System.setOut(ps);}for (int i 0; i 255; i) { // 输出ASCII字符System.out.print((char) i);if (i % 50 0) { // 每50个数据一行System.out.println(); // 换行}}} catch (FileNotFoundException e) {e.printStackTrace();} finally {if (ps ! null) {ps.close();}}}
}
08、数据流 boolean readBoolean() byte readByte()
char readChar() float readFloat()
double readDouble() short readShort()
long readLong() int readInt()
String readUTF() void readFully(byte[s] b)
DataOutputStream中的方法 将上述的方法的read改为相应的write即可。
import org.junit.Test;
import java.io.*;public class OtherStreamTest { /*** 3.数据流* 3.1 DataInputStream 和 DataOutputStream* 3.2 作用用于读取或写出基本数据类型的变量或字符串** 练习将内存中的字符串、基本数据类型的变量写出到文件中。** 注意处理异常的话仍然应该使用try-catch-finally.*/Testpublic void test3() throws IOException {//1.DataOutputStream dos new DataOutputStream(new FileOutputStream(data.txt));//2.dos.writeUTF(刘刚);dos.flush();//刷新操作将内存中的数据写入文件dos.writeInt(23);dos.flush();dos.writeBoolean(true);dos.flush();//3.dos.close();}/*** 将文件中存储的基本数据类型变量和字符串读取到内存中保存在变量中。** 注意点读取不同类型的数据的顺序要与当初写入文件时保存的数据的顺序一致*/Testpublic void test4() throws IOException {//1.DataInputStream dis new DataInputStream(new FileInputStream(data.txt));//2.String name dis.readUTF();int age dis.readInt();boolean isMale dis.readBoolean();System.out.println(name name);System.out.println(age age);System.out.println(isMale isMale);//3.dis.close();}
}
09、对象流
9.1、对象序列化机制的理解 9.2、对象流序列化与反序列化字符串操作
import org.junit.Test;import java.io.*;/*** 对象流的使用* 1.ObjectInputStream 和 ObjectOutputStream* 2.作用用于存储和读取基本数据类型数据或对象的处理流。它的强大之处就是可以把Java中的对象写入到数据源中也能把对象从数据源中还原回来。*/
public class ObjectTest {/*** 序列化过程将内存中的java对象保存到磁盘中或通过网络传输出去* 使用ObjectOutputStream实现*/Testpublic void test(){ObjectOutputStream oos null;try {//创造流oos new ObjectOutputStream(new FileOutputStream(object.dat));//制造对象oos.writeObject(new String(秦始皇陵欢迎你));//刷新操作oos.flush();} catch (IOException e) {e.printStackTrace();} finally {if(oos ! null){//3.关闭流try {oos.close();} catch (IOException e) {e.printStackTrace();}}}}/*** 反序列化将磁盘文件中的对象还原为内存中的一个java对象* 使用ObjectInputStream来实现*/Testpublic void test2(){ObjectInputStream ois null;try {ois new ObjectInputStream(new FileInputStream(object.dat));Object obj ois.readObject();String str (String) obj;System.out.println(str);} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();} finally {if(ois ! null){try {ois.close();} catch (IOException e) {e.printStackTrace();}}}}}
9.3、自定义类实现序列化与反序列化操作 1、Person类 import java.io.Serializable;/*** Person需要满足如下的要求方可序列化* 1.需要实现接口Serializable*/
public class Person implements Serializable {public static final long serialVersionUID 475463534532L;private String name;private int age;public Person() {}public Person(String name, int age) {this.name name;this.age age;}Overridepublic String toString() {return Person{ name name \ , age 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;}
} 2、测试类 import org.junit.Test;import java.io.*;/*** 对象流的使用* 1.ObjectInputStream 和 ObjectOutputStream* 2.作用用于存储和读取基本数据类型数据或对象的处理流。它的强大之处就是可以把Java中的对象写入到数据源中也能把对象从数据源中还原回来。** 3.要想一个java对象是可序列化的需要满足相应的要求。见Person.java** 4.序列化机制* 对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流从而允许把这种* 二进制流持久地保存在磁盘上或通过网络将这种二进制流传输到另一个网络节点。* 当其它程序获取了这种二进制流就可以恢复成原来的Java对象。**/
public class ObjectTest {/*** 序列化过程将内存中的java对象保存到磁盘中或通过网络传输出去* 使用ObjectOutputStream实现*/Testpublic void test(){ObjectOutputStream oos null;try {//创造流oos new ObjectOutputStream(new FileOutputStream(object.dat));//制造对象oos.writeObject(new String(秦始皇陵欢迎你));//刷新操作oos.flush();oos.writeObject(new Person(李时珍,65));oos.flush();} catch (IOException e) {e.printStackTrace();} finally {if(oos ! null){//3.关闭流try {oos.close();} catch (IOException e) {e.printStackTrace();}}}}/*** 反序列化将磁盘文件中的对象还原为内存中的一个java对象* 使用ObjectInputStream来实现*/Testpublic void test2(){ObjectInputStream ois null;try {ois new ObjectInputStream(new FileInputStream(object.dat));Object obj ois.readObject();String str (String) obj;Person p (Person) ois.readObject();System.out.println(str);System.out.println(p);} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();} finally {if(ois ! null){try {ois.close();} catch (IOException e) {e.printStackTrace();}}}}}
9.4、serialVersionUID的理解 1、Person类 import java.io.Serializable;/*** Person需要满足如下的要求方可序列化* 1.需要实现接口Serializable* 2.当前类提供一个全局常量serialVersionUID* 3.除了当前Person类需要实现Serializable接口之外还必须保证其内部所有属性* 也必须是可序列化的。默认情况下基本数据类型可序列化*** 补充ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量*/
public class Person implements Serializable {public static final long serialVersionUID 475463534532L;private String name;private int age;private int id;public Person() {}public Person(String name, int age, int id) {this.name name;this.age age;this.id id;}Overridepublic String toString() {return Person{ name name \ , age age , id id };}public int getId() {return id;}public void setId(int id) {this.id id;}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;}
} 2、测试类 import org.junit.Test;import java.io.*;/*** 对象流的使用* 1.ObjectInputStream 和 ObjectOutputStream* 2.作用用于存储和读取基本数据类型数据或对象的处理流。它的强大之处就是可以把Java中的对象写入到数据源中也能把对象从数据源中还原回来。** 3.要想一个java对象是可序列化的需要满足相应的要求。见Person.java** 4.序列化机制* 对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流从而允许把这种* 二进制流持久地保存在磁盘上或通过网络将这种二进制流传输到另一个网络节点。* 当其它程序获取了这种二进制流就可以恢复成原来的Java对象。**/
public class ObjectTest {/*** 序列化过程将内存中的java对象保存到磁盘中或通过网络传输出去* 使用ObjectOutputStream实现*/Testpublic void test(){ObjectOutputStream oos null;try {//创造流oos new ObjectOutputStream(new FileOutputStream(object.dat));//制造对象oos.writeObject(new String(秦始皇陵欢迎你));//刷新操作oos.flush();oos.writeObject(new Person(李时珍,65,0));oos.flush();} catch (IOException e) {e.printStackTrace();} finally {if(oos ! null){//3.关闭流try {oos.close();} catch (IOException e) {e.printStackTrace();}}}}/*** 反序列化将磁盘文件中的对象还原为内存中的一个java对象* 使用ObjectInputStream来实现*/Testpublic void test2(){ObjectInputStream ois null;try {ois new ObjectInputStream(new FileInputStream(object.dat));Object obj ois.readObject();String str (String) obj;Person p (Person) ois.readObject();System.out.println(str);System.out.println(p);} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();} finally {if(ois ! null){try {ois.close();} catch (IOException e) {e.printStackTrace();}}}}}
9.5、自定义类可序列化的其它要求 1、Person类 import java.io.Serializable;/*** Person需要满足如下的要求方可序列化* 1.需要实现接口Serializable* 2.当前类提供一个全局常量serialVersionUID* 3.除了当前Person类需要实现Serializable接口之外还必须保证其内部所有属性* 也必须是可序列化的。默认情况下基本数据类型可序列化*** 补充ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量**/
public class Person implements Serializable{public static final long serialVersionUID 475463534532L;private String name;private int age;private int id;private Account acct;public Person(String name, int age, int id) {this.name name;this.age age;this.id id;}public Person(String name, int age, int id, Account acct) {this.name name;this.age age;this.id id;this.acct acct;}Overridepublic String toString() {return Person{ name name \ , age age , id id , acct acct };}public int getId() {return id;}public void setId(int id) {this.id id;}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 Person(String name, int age) {this.name name;this.age age;}public Person() {}
}class Account implements Serializable{public static final long serialVersionUID 4754534532L;private double balance;Overridepublic String toString() {return Account{ balance balance };}public double getBalance() {return balance;}public void setBalance(double balance) {this.balance balance;}public Account(double balance) {this.balance balance;}
} 2、测试类 import org.junit.Test;import java.io.*;/*** 对象流的使用* 1.ObjectInputStream 和 ObjectOutputStream* 2.作用用于存储和读取基本数据类型数据或对象的处理流。它的强大之处就是可以把Java中的对象写入到数据源中也能把对象从数据源中还原回来。** 3.要想一个java对象是可序列化的需要满足相应的要求。见Person.java** 4.序列化机制* 对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流从而允许把这种* 二进制流持久地保存在磁盘上或通过网络将这种二进制流传输到另一个网络节点。* 当其它程序获取了这种二进制流就可以恢复成原来的Java对象。*/
public class ObjectTest {/*** 序列化过程将内存中的java对象保存到磁盘中或通过网络传输出去* 使用ObjectOutputStream实现*/Testpublic void test(){ObjectOutputStream oos null;try {//创造流oos new ObjectOutputStream(new FileOutputStream(object.dat));//制造对象oos.writeObject(new String(秦始皇陵欢迎你));//刷新操作oos.flush();oos.writeObject(new Person(李时珍,65));oos.flush();oos.writeObject(new Person(张学良,23,1001,new Account(5000)));oos.flush();} catch (IOException e) {e.printStackTrace();} finally {if(oos ! null){//3.关闭流try {oos.close();} catch (IOException e) {e.printStackTrace();}}}}/*** 反序列化将磁盘文件中的对象还原为内存中的一个java对象* 使用ObjectInputStream来实现*/Testpublic void test2(){ObjectInputStream ois null;try {ois new ObjectInputStream(new FileInputStream(object.dat));Object obj ois.readObject();String str (String) obj;Person p (Person) ois.readObject();System.out.println(str);System.out.println(p);} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();} finally {if(ois ! null){try {ois.close();} catch (IOException e) {e.printStackTrace();}}}}}
10.随机存取文件流 10.1、RandomAccessFile实现数据的读写操作
import org.junit.Test;import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;/*** RandomAccessFile的使用* 1.RandomAccessFile直接继承于java.lang.Object类实现了DataInput和DataOutput接口* 2.RandomAccessFile既可以作为一个输入流又可以作为一个输出流* 3.如果RandomAccessFile作为输出流时写出到的文件如果不存在则在执行过程中自动创建。* 如果写出到的文件存在则会对原有文件内容进行覆盖。默认情况下从头覆盖*/
public class RandomAccessFileTest {Testpublic void test(){RandomAccessFile raf1 null;RandomAccessFile raf2 null;try {raf1 new RandomAccessFile(new File(爱情与友情.jpg),r);raf2 new RandomAccessFile(new File(爱情与友情1.jpg),rw);byte[] buffer new byte[1024];int len;while((len raf1.read(buffer)) ! -1){raf2.write(buffer,0,len);}} catch (IOException e) {e.printStackTrace();} finally {if(raf1 ! null){try {raf1.close();} catch (IOException e) {e.printStackTrace();}}if(raf2 ! null){try {raf2.close();} catch (IOException e) {e.printStackTrace();}}}}Testpublic void test2() throws IOException {RandomAccessFile raf1 new RandomAccessFile(hello.txt,rw);raf1.write(xyz.getBytes());raf1.close();}}
10.2、RandomAccessFile实现数据的插入操作
import org.junit.Test;import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;/*** RandomAccessFile的使用* 1.RandomAccessFile直接继承于java.lang.Object类实现了DataInput和DataOutput接口* 2.RandomAccessFile既可以作为一个输入流又可以作为一个输出流* 3.如果RandomAccessFile作为输出流时写出到的文件如果不存在则在执行过程中自动创建。* 如果写出到的文件存在则会对原有文件内容进行覆盖。默认情况下从头覆盖** 4.可以通过相关的操作实现RandomAccessFile“插入”数据的效果*/
public class RandomAccessFileTest {/*** 使用RandomAccessFile实现数据的插入效果*/Testpublic 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();//思考将StringBuilder替换为ByteArrayOutputStream}}
11、NIO.2中Path、Paths、Files类的使用 import java.io.File;File file new File(“index.html”);
但在Java7 中我们可以这样写
import java.nio.file.Path;
import java.nio.file.Paths;
Path path Paths.get(“index.html”); 1、Path接口 2、Files 类