1 public class Demo1_FileInputStream { 2 3 public static void main(String[] args) throws IOException { 4 //demo1(); 5 FileInputStream fis = new FileInputStream("a.txt"); // 内容为 abc 6 int x; 7 while((x = fis.read())!=-1) { 8 System.out.println(x); 9 } 10 } 11 12 public static void demo1() throws FileNotFoundException, IOException { 13 FileInputStream fis = new FileInputStream("a.txt"); // 内容为 abc 14 int x = fis.read(); // x = 97 15 System.out.println(x); // 当 文件中的内容读完后再读时 返回值为 -1 16 fis.close(); 17 } 18 19 }
FileOutputStream:
1 public class Demo2_FileOutputStream { 2 3 /** 4 * @param args 5 * @throws IOException 6 * close()方法:具备刷新功能,在关闭流之前会先刷新缓冲区,将数据全部刷新到文件中再关闭文件,close方法刷完后就不能再写了 7 * flush()方法:具备刷新功能,刷完之后还可以继续写 8 */ 9 public static void main(String[] args) throws IOException { 10 11 //demo1(); 12 //demo2(); 13 //demo3(); 14 //demo4(); 15 //demo5(); 16 //demo6(); 17 demo7(); 18 } 19 20 /** 21 * @throws FileNotFoundException 22 * @throws IOException 23 * 通过缓冲区再拷贝要比直接操作硬盘数据效率高的多,这种方式实质上是定义的8192个字节的数组实现的 24 * 25 * 如果定义小数组的方式的长度也是8192个字节的话,小数组的方式效率更高,因为小数组方式的读和写操作的是同一个数组,而Buffered方式操作的是两个数组 26 */ 27 public static void demo7() throws FileNotFoundException, IOException { 28 FileInputStream fis = new FileInputStream("1.png"); 29 FileOutputStream fos = new FileOutputStream("copy.png"); 30 BufferedInputStream bis = new BufferedInputStream(fis); 31 BufferedOutputStream bos = new BufferedOutputStream(fos); 32 int b; 33 while((b = bis.read()) != -1) { 34 bos.write(b); 35 } 36 bis.close(); 37 bos.close(); 38 } 39 40 /** 41 * @throws FileNotFoundException 42 * @throws IOException 43 * 通过定义长度大点的小数组实现拷贝 44 */ 45 public static void demo6() throws FileNotFoundException, IOException { 46 FileInputStream fis = new FileInputStream("a.txt"); 47 FileOutputStream fos = new FileOutputStream("y.txt"); 48 byte[] arr = new byte[1024 * 8]; //一般定义的数组长度为1024的整数倍,这样效率会高点 49 int len; 50 while((len = fis.read(arr)) != -1) { 51 fos.write(arr,0,len); 52 } 53 fis.close(); 54 fos.close(); 55 } 56 57 /** 58 * @throws FileNotFoundException 59 * @throws IOException 60 * 通过定义小数组方式拷贝 61 */ 62 public static void demo5() throws FileNotFoundException, IOException { 63 FileInputStream fis = new FileInputStream("a.txt"); 64 FileOutputStream fos = new FileOutputStream("y.txt"); 65 byte[] arr = new byte[2]; 66 int len; 67 while((len = fis.read(arr)) != -1) { 68 //fos.write(arr); 这种方式会导致写入重复数据 ,如:a.txt中数据为 abc 通过此方法写入的结果是:abab 69 fos.write(arr,0,len); 70 } 71 fis.close(); 72 fos.close(); 73 } 74 75 /** 76 * @throws FileNotFoundException 77 * @throws IOException 78 * 此种拷贝方式的效率是高点,但是可能会导致内存溢出,不推荐使用 79 */ 80 public static void demo4() throws FileNotFoundException, IOException { 81 FileInputStream fis = new FileInputStream("1.png"); 82 FileOutputStream fos = new FileOutputStream("copy.png"); 83 byte[] arr = new byte[fis.available()]; 84 fis.read(arr); 85 fos.write(arr); 86 fis.close(); 87 fos.close(); 88 } 89 90 /** 91 * @throws FileNotFoundException 92 * @throws IOException 93 * 可以实现拷贝功能,但是效率特别低,不推荐使用 94 */ 95 public static void demo3() throws FileNotFoundException, IOException { 96 FileInputStream fis = new FileInputStream("1.png"); 97 FileOutputStream fos = new FileOutputStream("copy.png"); 98 int b; 99 while((b = fis.read()) != -1) { 100 fos.write(b); 101 } 102 fis.close(); 103 fos.close(); 104 } 105 106 /** 107 * @throws FileNotFoundException 108 * @throws IOException 109 * 输出流 110 */ 111 public static void demo2() throws FileNotFoundException, IOException { 112 FileOutputStream fos = new FileOutputStream("y.txt",true); //添加上第二个参数 true 就成了追加 113 fos.write(100); 114 fos.close(); 115 } 116 117 /** 118 * @throws FileNotFoundException 119 * @throws IOException 120 * 输入流 121 */ 122 public static void demo1() throws FileNotFoundException, IOException { 123 FileOutputStream fos = new FileOutputStream("y.txt"); //当输出流对象传入的文件不存在时,会自动创建一个,如果这个文件已经存在,则会先清空文件 124 fos.write(97); //虽然输出流写入的是一个int类型的数,但是到文件中的是一个字节,会自动删除int类型的前3位全为零的数据 125 fos.close(); 126 } 127 128 }
字节流读取中文时需要注意的问题:
1 public class Demo3_Chinese { 2 3 /* 4 * 字节流读取中文的问题: 5 * 字节流在读取中文的时候有可能会读到半个中文,造成乱码 6 * 字节流写出中文的问题: 7 * 字节流直接操作的是字节,所以写出中文必须将字符串转换成字节数组 8 * 写出回车换行 write(" ".getBytes()) 9 */ 10 public static void main(String[] args) throws IOException { 11 12 //demo1(); 13 FileOutputStream fos = new FileOutputStream("c.txt"); 14 fos.write("测试一下".getBytes()); //字节流写入中文没有问题,只不过需要将要写入的内容转换为字节数组 15 fos.write(" ".getBytes()); //写入中文 16 fos.close(); 17 } 18 19 public static void demo1() throws FileNotFoundException, IOException { 20 FileInputStream fis = new FileInputStream("b.txt"); 21 byte[] arr = new byte[2]; 22 int len; 23 while((len = fis.read(arr)) != -1) { 24 System.out.println(new String(arr, 0, len)); 25 } 26 fis.close(); 27 } 28 29 }
IO流的异常处理机制 try...finally
1 public class Demo4_TryFinally { 2 /* 3 * 流的标准try ... finally 写法 4 */ 5 /** 6 * @param args 7 * @throws IOException 8 */ 9 public static void main(String[] args) throws IOException { 10 11 //demo1(); 12 demo2(); 13 14 } 15 16 /** 17 * @throws IOException 18 * @throws FileNotFoundException 19 * JDK 1.7 版本流异常处理标准 try() 小括号里面的代码是可以自动关闭的 ,流实现类AutoCloseable接口,所以它可以自动关闭 20 */ 21 public static void demo2() throws IOException, FileNotFoundException { 22 try( 23 FileInputStream fis = new FileInputStream("a.txt"); 24 FileOutputStream fos = new FileOutputStream("b.txt"); 25 ){ 26 int b; 27 while((b = fis.read()) != -1) { 28 fos.write(b); 29 } 30 } 31 } 32 33 /** 34 * @throws FileNotFoundException 35 * @throws IOException 36 * JDK 1.6 版本流异常的标准处理代码 37 */ 38 public static void demo1() throws FileNotFoundException, IOException { 39 FileInputStream fis = null; 40 FileOutputStream fos = null; 41 try { 42 fis = new FileInputStream("a.txt"); 43 fos = new FileOutputStream("copy"); 44 int b; 45 while ((b = fis.read()) != -1) { 46 fos.write(b); 47 } 48 } finally { 49 try { 50 if (fis != null) 51 fis.close(); 52 } finally { 53 if (fos != null) 54 fos.close(); 55 } 56 } 57 } 58 59 }
IO流之练习:
1 public class Demo5_Test { 2 3 public static void main(String[] args) throws IOException { 4 //demo1(); 5 //demo2(); 6 demo3(); 7 } 8 9 /** 10 * @throws IOException 11 * 功能:从键盘不断录入数据并将录入的数据写入文件中,直到录入数据为 quit 为止 12 */ 13 public static void demo3() throws IOException { 14 Scanner sc = new Scanner(System.in); 15 System.out.println("请输入数据:"); 16 FileOutputStream fos = new FileOutputStream("text.txt"); 17 while(true) { 18 String line = sc.nextLine(); 19 if("quit".equals(line)) { 20 break; 21 }else { 22 fos.write(line.getBytes()); 23 fos.write(" ".getBytes()); 24 } 25 } 26 fos.close(); 27 } 28 29 /* 30 * 需求: 31 * 从键盘录入一个文件的路径,然后判断录入的路径是否是文件路径,如果是将该文件拷贝到本项目目录下 32 * 分析: 33 * 1. 创建键盘录入对象,对录入的文件路径判断,如果是文件路径,则返回一个文件对象 34 * 2. 创建输入输出流对象,进行拷贝文件 35 */ 36 public static void demo2() throws FileNotFoundException, IOException { 37 File file = getFile(); 38 BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); 39 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file.getName())); 40 int b; 41 while((b = bis.read()) != -1) { 42 bos.write(b); 43 } 44 bis.close(); 45 bos.close(); 46 } 47 48 /** 49 * @return 50 * 提示从键盘录入一个文件路径,返回一个文件对象 51 */ 52 public static File getFile() { 53 Scanner sc = new Scanner(System.in); 54 System.out.println("请输入文件路径:"); 55 while(true) { 56 String line = sc.nextLine(); 57 File file = new File(line); 58 if(!file.exists()) { 59 System.out.println("输入的文件路径不存在,请重新输入:"); 60 }else if(file.isDirectory()) { 61 System.out.println("输入的文件路径是目录,请重新输入:"); 62 }else { 63 return file; 64 } 65 } 66 } 67 /* 68 * 通过流对图片进行加密 69 */ 70 public static void demo1() throws FileNotFoundException, IOException { 71 BufferedInputStream bis = new BufferedInputStream(new FileInputStream("1.png")); 72 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.png")); 73 int b; 74 while((b = bis.read()) != -1) { 75 bos.write(b ^ 666); //通过将读到的字节异或上一个数进行加密,解密时同样还用加密时的这个数再加一次密即可 76 } 77 bis.close(); 78 bos.close(); 79 } 80 81 }
FileReader:
1 public class Demo6_FileReader { 2 3 public static void main(String[] args) throws IOException { 4 5 FileReader fr = new FileReader("b.txt"); 6 int b; 7 while((b = fr.read()) != -1) { 8 System.out.println((char)b); //通过项目默认的码表一次读取一个字符 9 } 10 fr.close(); 11 } 12 13 }
FileWriter:
1 public class Demo7_FileWrite { 2 3 /* 4 * FileWriter可以直接将字符串写入文件 5 * 注意: 6 * Writer类中有一个2K的缓冲区,如果在向文件中写入数据后不关闭输出流,则数据不会写入文件,只会存在缓冲区中 7 * 8 * 什么时候使用字符流? 9 * 字符流可以拷贝文件,但是不推荐使用,因为读取时会把字节转换为字符,写出时还要将字符转换成字节 10 * 程序需要读取一段文本或需要写出一段文本的时候可以使用字符流 11 * 读取的时候是按照字符的大小读取的,不会出现半个中文的问题,写出的时候可以直接将字符串写出,不用转换为字节数组; 12 * 13 *注意: 14 * 字符流不能够拷贝非纯文本文件,因为读的时候会将字节转换成字符,可能找不到对应的字符,就会用?代替,写出的时候会将字符转换成字节写出去, 15 * 如果是?,直接写出,这样写出的文件就乱了,不能正常的打开了 16 */ 17 public static void main(String[] args) throws IOException { 18 19 FileWriter fw = new FileWriter("d.txt"); 20 fw.write("撸起袖子干!"); 21 fw.close(); 22 } 23 24 }
Buffered 缓冲流:
1 public class Demo8_Buffered { 2 3 /* 4 * readLine() 每次读取1行 5 * newLine() 相当于换行符 6 * 7 * newLine() 和 " "的区别 8 * newLine() 是可以跨平台的 9 * " " 是支持windows系统 10 * 11 * 注意:流对象尽量是晚开早关 12 */ 13 public static void main(String[] args) throws IOException { 14 15 //demo1(); 16 demo2(); 17 } 18 19 /** 20 * @throws FileNotFoundException 21 * @throws IOException 22 * LineNumberReader 可以实现设置行号和获取行号的功能 23 */ 24 public static void demo2() throws FileNotFoundException, IOException { 25 LineNumberReader lnr = new LineNumberReader(new FileReader("a.txt")); 26 String line; 27 lnr.setLineNumber(0); 28 while((line = lnr.readLine()) != null) { 29 System.out.println(lnr.getLineNumber() + line); 30 } 31 lnr.close(); 32 } 33 34 /** 35 * @throws FileNotFoundException 36 * @throws IOException 37 * 实现对一个文件进行反转的功能,即第一行和最后一行互换,倒数第二行与第二行互换。。。 38 */ 39 public static void demo1() throws FileNotFoundException, IOException { 40 BufferedReader br = new BufferedReader(new FileReader("a.txt")); 41 String line; 42 ArrayList<String> list = new ArrayList<>(); 43 while((line = br.readLine()) != null) { 44 list.add(line); 45 } 46 br.close(); //用完后就关,遵循晚开早关的原则 47 BufferedWriter bw = new BufferedWriter(new FileWriter("res.txt")); 48 for(int i = list.size() - 1; i >=0; i--) { 49 bw.write(list.get(i)); 50 bw.newLine(); 51 } 52 bw.close(); 53 } 54 55 }
对不同编码格式的文件进行读写处理:
1 /** 2 * @author 3 * 对不同编码格式的文件读取处理 4 * 5 */ 6 public class Demo9_TransIO { 7 8 public static void main(String[] args) throws IOException { 9 10 //demo1(); 11 //demo2(); 12 demo10(); 13 } 14 15 /** 16 * @throws IOException 17 * 使用缓冲流可以提高读写的速度 18 */ 19 public static void demo10() throws IOException { 20 BufferedReader br = 21 new BufferedReader(new InputStreamReader(new FileInputStream("utf-8.txt"), "utf-8")); 22 BufferedWriter bw = 23 new BufferedWriter(new OutputStreamWriter(new FileOutputStream("gbk.txt"), "gbk")); 24 25 int b; 26 while((b = br.read()) != -1) { 27 bw.write(b); 28 } 29 br.close(); 30 bw.close(); 31 } 32 33 /** 34 * @throws IOException 35 * 使用指定码表格式进行读取可以避免出现因编码不同导致的乱码问题 36 */ 37 public static void demo2() throws IOException { 38 InputStreamReader isr = new InputStreamReader(new FileInputStream("utf-8.txt"), "utf-8"); 39 OutputStreamWriter osr = new OutputStreamWriter(new FileOutputStream("gbk.txt"), "gbk"); 40 int a; 41 while((a = isr.read()) != -1) { 42 osr.write(a); 43 } 44 isr.close(); 45 osr.close(); 46 } 47 48 /** 49 * @throws IOException 50 * 使用默认编码格式只能处理都为GBK的编码格式的文件 51 */ 52 public static void demo1() throws IOException { 53 FileInputStream fis = new FileInputStream("utf-8.txt"); //默认为GBK编码格式,如果读写的编码不一样,会出现乱码 54 FileOutputStream fos = new FileOutputStream("gbk.txt"); //GBK编码一个汉字占2个字节,UTF-8编码一个汉字占3个字节 55 int b; 56 while((b = fis.read()) != -1) { 57 fos.write(b); 58 } 59 fis.close(); 60 fos.close(); 61 } 62 63 }
练习:
/*
* 使用流模拟使用版软件功能
* 分析:
* 1. 创建缓冲输入流对象,使用readLine()方法读取文件中的数据
* 2. 将读到的数据转换成int类型
* 3. 判断int类型的这个数,如果大于0提示还有对应的免费使用次数,否则提示购买正版软件
* 4. 关闭流
*/
1 public static void main(String[] args) throws IOException { 2 3 BufferedReader br = new BufferedReader(new FileReader("config.txt")); 4 String line = br.readLine(); 5 int times = Integer.parseInt(line); 6 if(times > 0) { 7 System.out.println("您还有" + times-- + "次使用机会!"); 8 BufferedWriter bw = new BufferedWriter(new FileWriter("config.txt")); 9 bw.write(times + ""); 10 bw.close(); 11 }else { 12 System.out.println("您的免费使用次数已经使用完毕,请购买正版软件!"); 13 } 14 br.close(); 15 }
递归:
* 递归的弊端:不能调用次数过多,可能会导致栈内存溢出
* 递归的好处:可以不用知道循环次数
*
* 构造方法不能使用递归调用;
*
* 递归调用不一定有返回值,可以有返回值,也可以没有返回值;
练习:
* 需求:
* 从键盘录入一个文件夹路径,然后输出该文件夹下所有的.java文件
* 分析:
* 先判断录入的一个文件夹路径
* 1. 录入的文件夹路径如果不是一个文件夹,则给出提示
* 2. 录入的文件夹路径如果不存在,则给出提示
* 3. 录入的文件夹路径如果是文件夹路径就返回一个文件对象
* 打印出该文件夹路径下的所有.java文件
* 1. 获取该文件夹路径下的所有文件和文件夹,存储在File数组中
* 2. 遍历数组,对每一个文件或文件夹做判断
* 3. 如果是文件并且是.java文件,则打印
* 4. 如果是文件夹,则递归调用
1 public static void main(String[] args) { 2 3 File dir = getDir(); 4 printJavaFile(dir); 5 } 6 7 /** 8 * @return 9 * 判断录入的文件夹路径是否正确,返回一个文件对象 10 */ 11 public static File getDir() { 12 Scanner sc = new Scanner(System.in); 13 System.out.println("请输入一个文件夹路径:"); 14 while(true) { 15 String line = sc.nextLine(); 16 File dir = new File(line); 17 if(!dir.exists()) { 18 System.out.println("您录入的文件夹路径不存在,请重新录入!"); 19 }else if(dir.isFile()) { 20 System.out.println("您输入的是文件,请重新输入一个文件夹路径!"); 21 }else { 22 return dir; 23 } 24 } 25 } 26 27 /** 28 * @param dir 29 * 对目录进行遍历,输出.java的文件 30 */ 31 public static void printJavaFile(File dir) { 32 File[] subDir = dir.listFiles(); 33 for (File file : subDir) { 34 if(file.isFile() && file.getName().endsWith(".java")) { 35 System.out.println(file); 36 }else if(file.isDirectory()) { 37 printJavaFile(file); 38 } 39 } 40 }
练习:
/**
* @author
*需求;统计一个文件中某个字符出现的次数,并将最终的结果写入文件times.txt中
*分析:
* 1. 先读取文件中的每个字符
* 2. 将字符存入map集合中,字符作为键,出现的次数作为值
* 3. 关闭输入流
* 4. 遍历集合将结果写入文件中
* 5. 关闭输出流
*/
1 public class Demo6_Test { 2 3 public static void main(String[] args) throws IOException { 4 5 FileReader fr = new FileReader("a.txt"); 6 Map<Character, Integer> map = new HashMap<>(); 7 int a; 8 while((a = fr.read()) != -1) { 9 char c = (char)a; 10 /*if(!map.containsKey(c)) { 11 map.put(c, 1); 12 }else { 13 map.put(c, map.get(c) + 1); 14 }*/ 15 map.put(c, !map.containsKey(c) ? 1 : map.get(c) + 1); 16 } 17 fr.close(); 18 System.out.println(map); 19 20 BufferedWriter bw = new BufferedWriter(new FileWriter("times.txt")); 21 for(Character ch : map.keySet()) { 22 switch (ch) { 23 case ' ': 24 bw.write("\t" + "=" + map.get(ch)); 25 break; 26 case ' ': 27 bw.write("\r" + "=" + map.get(ch)); 28 break; 29 case ' ': 30 bw.write("\n" + "=" + map.get(ch)); 31 break; 32 default: 33 bw.write(ch + "=" + map.get(ch)); 34 break; 35 } 36 37 bw.newLine(); 38 } 39 bw.close(); 40 } 41 42 }
java之IO流 SequenceInputStream:
1 public class Demo1_SequenceInputStream { 2 3 /* 4 * SequenceInputStream可以实现传入两个输入流对象,进行逐个读取两个文件 5 * 6 * 使用SequenceInputStream 实现这个读取两个文件,将两个文件合并到一个新文件中 7 */ 8 public static void main(String[] args) throws IOException { 9 10 FileInputStream fis1 = new FileInputStream("a.txt"); 11 FileInputStream fis2 = new FileInputStream("b.txt"); 12 SequenceInputStream sis = new SequenceInputStream(fis1, fis2); 13 FileOutputStream fos = new FileOutputStream("ab.txt"); 14 int b; 15 while((b = sis.read()) != -1) { 16 fos.write(b); 17 } 18 sis.close(); 19 fos.close(); 20 } 21 22 }
java之IO流 ByteArrayOutputStream:
1 public class Demo2_ByteArrayOutputStream { 2 3 /* 4 * 使用FileInputStream 读取中文文件内容的时候会出现乱码的情况 5 * 6 * 解决方案有两种: 7 * 1. 使用字符流 8 * 2. 使用ByteArrayOutputStream 9 */ 10 public static void main(String[] args) throws IOException { 11 12 //demo1(); 13 FileInputStream fis = new FileInputStream("b.txt"); 14 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 15 int b; 16 while((b = fis.read()) != -1) { 17 baos.write(b); 18 } 19 20 //打印结果方式1,使用toByteArray() 方法 21 byte[] arr = baos.toByteArray(); 22 System.out.println(new String(arr)); 23 24 //打印结果方式2,使用toString()方法,其实这种方法可以直接打印baos对象,不用调用toString()方法,对象会自动调用该方法 25 System.out.println(baos.toString()); 26 fis.close(); 27 } 28 29 /** 30 * @throws IOException 31 * 会出现乱码的问题 32 */ 33 public static void demo1() throws IOException { 34 FileInputStream fis = new FileInputStream("b.txt"); 35 byte[] arr = new byte[3]; 36 int b; 37 while((b = fis.read(arr)) != -1) { 38 System.out.println(new String(arr, 0, b)); 39 } 40 fis.close(); 41 } 42 43 }
java之IO流 RandomAccessFile:
1 public class Demo3_RandomAccessFile { 2 3 public static void main(String[] args) throws IOException { 4 RandomAccessFile raf = new RandomAccessFile("c.txt", "rw"); 5 //raf.write(97); 6 //System.out.println(raf.read()); 7 raf.seek(10); //设置指针的位置,之后可以在指定的位置进行读写,可以应用到多线程下载等上面 8 raf.write(99); 9 raf.close(); 10 } 11 12 }
java之IO流 ObjectOutputStream:
/* * 对象输出流,实现序列化,在写入自定义对象时需要自定义类实现Serializable接口,否则会报错误 */ public class Demo4_ObjectOutputStream { public static void main(String[] args) throws IOException { //demo1(); Student s1 = new Student("张三", 20); Student s2 = new Student("李四", 17); List<Student> list = new ArrayList<>(); list.add(s1); list.add(s2); ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("d.txt")); oos.writeObject(list); oos.close(); } /** * @throws IOException * @throws FileNotFoundException * 对象输出流写入自定义对象 */ public static void demo1() throws IOException, FileNotFoundException { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("d.txt")); Student s1 = new Student("张三", 18); Student s2 = new Student("李四", 19); oos.writeObject(s1); //要想用该对象写入对象,需要改自定义类实现Serializable接口,否则会报错 oos.writeObject(s2); oos.close(); } }
java之IO流 ObjectInputStream:
1 /* 2 * 对象输入流,实现反序列化 3 * 注意: 4 * 对读出的对象需要强制转换,因为在写入时虽然传入的是自定义对象,但是它会自动提升为Object对象存入 5 */ 6 public class Demo5_ObjectInputStream { 7 8 /** 9 * @param args 10 * @throws IOException 11 * @throws ClassNotFoundException 12 */ 13 public static void main(String[] args) throws IOException, ClassNotFoundException { 14 15 //demo1(); 16 demo2(); 17 } 18 19 /** 20 * @throws IOException 21 * @throws FileNotFoundException 22 * @throws ClassNotFoundException 23 * 对demo1中的问题优化,写入文件时先将自定义对象存入集合中,然后将集合对象写入文件 24 */ 25 public static void demo2() throws IOException, FileNotFoundException, ClassNotFoundException { 26 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d.txt")); 27 @SuppressWarnings("unchecked") 28 ArrayList<Student> list = (ArrayList<Student>) ois.readObject(); 29 for (Student student : list) { 30 System.out.println(student); 31 } 32 ois.close(); 33 } 34 35 /** 36 * @throws IOException 37 * @throws FileNotFoundException 38 * @throws ClassNotFoundException 39 * 对象输出流读取存入文件中的自定义对象 40 * 41 * 存在问题: 42 * 当读取完对象数据时再读会报文件结束异常,java.io.EOFException, 43 * 要想解决这个问题,可以将对象都存入集合中,然后写入集合对象,读取的时候可以读集合,然后遍历 44 */ 45 public static void demo1() throws IOException, FileNotFoundException, ClassNotFoundException { 46 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d.txt")); 47 Student s1 = (Student) ois.readObject(); 48 Student s2 = (Student) ois.readObject(); 49 //Student s3 = (Student) ois.readObject(); 当读取完对象数据时再读会报文件结束异常,java.io.EOFException 50 //要想解决这个问题,可以将对象都存入集合中,然后写入集合对象,读取的时候可以读集合,然后遍历 51 System.out.println(s1); 52 System.out.println(s2); 53 ois.close(); 54 } 55 56 }
java之IO流 Properties:
1 public class Demo6_Properties { 2 3 /* 4 * Properties是Hashtable的子类 5 * Properties类表示了一个持久的属性集 6 * 它可以保存在流中或从流中加载 7 * 属性列表中的每一个键及其对应的值都是一个字符串 8 * 特殊功能: 9 * public Object setProperty(String key, String value) 10 * public String getProperty(String key) 11 * public Enumeration<String> stringPropertyNames() 12 * 13 */ 14 public static void main(String[] args) throws IOException { 15 16 //demo1(); 17 Properties prop = new Properties(); 18 System.out.println("读取前:" + prop); 19 prop.load(new FileInputStream("config.properties")); 20 System.out.println("读取后" + prop); 21 prop.setProperty("tel", "18988888888"); 22 System.out.println("修改后" + prop); //虽然prop中的tel修改了,但是配置文件中的内容并未修改,如想修改,还需要用store写入 23 prop.store(new FileOutputStream("config.properties"), "修改了电话话码"); //第二个参数是描述文件列表的,可以传null 24 System.out.println("写入后" + prop); //写入后 25 26 27 28 29 } 30 31 public static void demo1() { 32 Properties prop = new Properties(); 33 prop.setProperty("name", "张三"); 34 prop.setProperty("电话", "456123789"); 35 //System.out.println(ps); {name=张三, 电话=456123789} 36 Enumeration<String> en = (Enumeration<String>) prop.propertyNames(); 37 while(en.hasMoreElements()) { 38 String key = en.nextElement(); //获取Properties中的每一个键 39 String value = prop.getProperty(key); //获取Properties中的每一个值 40 System.out.println(key + "=" + value); 41 /* 42 * name=张三 43 * 电话=456123789 44 */ 45 } 46 } 47 48 }
/*
* 需求: 从键盘录入一个文件夹,然后统计文件夹的大小
*
* 分析:
* 1. 创建Scanner对象接收键盘录入
* 2. 将录入数据封装成文件对象
* 3. 对文件对象判断,如果是文件夹返回文件对象,否则提示继续输入
* 4. 获取文件夹中的所有文件及文件夹,存入文件数组
* 5. 遍历文件数组,判断元素是否是文件,如果是则计算文件大小,否则递归调用重新判断 、计算
* 6. 返回文件夹大小
*/
1 public class Demo7_Test { 2 3 /* 4 * 需求: 从键盘录入一个文件夹,然后统计文件夹的大小 5 * 6 * 分析: 7 * 1. 创建Scanner对象接收键盘录入 8 * 2. 将录入数据封装成文件对象 9 * 3. 对文件对象判断,如果是文件夹返回文件对象,否则提示继续输入 10 * 4. 获取文件夹中的所有文件及文件夹,存入文件数组 11 * 5. 遍历文件数组,判断元素是否是文件,如果是则计算文件大小,否则递归调用重新判断 、计算 12 * 6. 返回文件夹大小 13 */ 14 public static void main(String[] args) { 15 16 File dir = getDir(); 17 long size = getDirSize(dir); 18 System.out.println(size); 19 } 20 21 /** 22 * @return File file 23 * 根据键盘录入的数据判断是否是文件夹路径,返回文件对象 24 */ 25 public static File getDir() { 26 Scanner sc = new Scanner(System.in); 27 System.out.println("请输入文件夹路径:"); 28 while(true) { 29 String line = sc.nextLine(); 30 File file = new File(line); 31 if(!file.exists()) { 32 System.out.println("您输入的文件夹路径不存在,请重新输入:"); 33 }else if(file.isFile()) { 34 System.out.println("你输入的文件夹路径是文件路径,请重新输入文件夹路径:"); 35 }else { 36 return file; 37 } 38 } 39 } 40 41 /** 42 * @param file 43 * @return long len 44 * 根据得到的文件对象,计算文件夹的大小 45 */ 46 public static long getDirSize(File file) { 47 File[] subFiles = file.listFiles(); 48 long len = 0; 49 for (File subFile : subFiles) { 50 if(subFile.isFile()) { 51 len = len + subFile.length(); 52 }else { 53 len = len +getDirSize(subFile); 54 } 55 } 56 return len; 57 } 58 }
/*
* 需求:从键盘录入两个文件夹路径,将一个文件夹中的文件及文件夹全部拷贝到另一个文件夹中
* 分析:
* 1. 获取两个文件夹路径
* 2. 在目标文件夹中创建源文件夹
* 3. 获取原文件夹中的所有文件夹及文件,存储在File数组中
* 4. 遍历数组,如果是文件则直接copy到目标文件夹中,否则递归调用
*/
1 public static void main(String[] args) throws IOException { 2 File src = Demo7_Test.getDir(); 3 File dest = Demo7_Test.getDir(); 4 //为了防止自己拷贝自己造成不断地拷贝 5 if(src.equals(dest)) { 6 System.out.println("目标文件夹是源文件夹的子文件夹"); 7 }else { 8 9 copy(src, dest); 10 } 11 12 } 13 14 /** 15 * @param src 16 * @param dest 17 * 将原文件夹中的内容拷贝到目标文件夹中 18 * @throws IOException 19 */ 20 public static void copy(File src, File dest) throws IOException { 21 File newDir = new File(dest, src.getName()); 22 newDir.mkdir(); 23 File[] subFiles = src.listFiles(); 24 for (File subFile : subFiles) { 25 if(subFile.isFile()) { 26 BufferedInputStream bis = new BufferedInputStream(new FileInputStream(subFile)); 27 BufferedOutputStream bos = 28 new BufferedOutputStream(new FileOutputStream(new File(newDir, subFile.getName()))); 29 int b; 30 while((b = bis.read()) != -1) { 31 bos.write(b); 32 } 33 bis.close(); 34 bos.close(); 35 }else { 36 copy(subFile, newDir); 37 } 38 } 39 }