Java笔记11篇原来是写java的输入输出的,但是写着写着发现太乱,没有体系,实在没法理解,所以另写一篇作为总结与复习.
File
常用方法
先复习下File相关的内容,File代表文件和文件夹.下面是一些常用方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| import java.io.File; import java.util.Date; public class TestFile { public static void main(String[] args) { File f = new File("d:/LOLFolder/LOL.exe"); System.out.println("当前文件是:" +f); System.out.println("判断是否存在:"+f.exists()); System.out.println("判断是否是文件夹:"+f.isDirectory()); System.out.println("判断是否是文件:"+f.isFile()); System.out.println("获取文件的长度:"+f.length()); long time = f.lastModified(); Date d = new Date(time); System.out.println("获取文件的最后修改时间:"+d); f.setLastModified(0); File f2 =new File("d:/LOLFolder/DOTA.exe"); f.renameTo(f2); System.out.println("把LOL.exe改名成了DOTA.exe"); System.out.println("注意: 需要在D:\\LOLFolder确实存在一个LOL.exe,\r\n才可以看到对应的文件长度、修改时间等信息"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| import java.io.File; import java.io.IOException; public class TestFile { public static void main(String[] args) throws IOException { File f = new File("d:/LOLFolder/skin/garen.ski"); f.list(); File[]fs= f.listFiles(); f.getParent(); f.getParentFile(); f.mkdir(); f.mkdirs(); f.createNewFile(); f.getParentFile().mkdirs(); f.listRoots(); f.delete(); f.deleteOnExit(); } }
|
练习
1.遍历文件夹
一般说来操作系统都会安装在C盘,所以会有一个 C:\WINDOWS目录。 遍历这个目录下所有的文件(不用遍历子目录) 找出这些文件里,最大的和最小(非0)的那个文件,打印出他们的文件名.
注意题目啊,要求是找文件而不是文件夹,文件夹用length方法结果是0.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import java.io.File; import java.util.Comparator; import java.util.TreeSet;
public class FileTraverse { static File f = new File("D:\\test");
public static void main(String[] args) { File[] fileArray = f.listFiles(); TreeSet<File> fileSet = new TreeSet<>((f1, f2) -> (f1.length() < f2.length()) ? -1 : ((f1.length() == f2.length() ? 0 : 1))); for (File file : fileArray ) { fileSet.add(file); } System.out.println(f.length()); System.out.println("min is" + fileSet.first() + ' ' + fileSet.first().length()); System.out.println("max is" + fileSet.last() + ' ' + fileSet.last().length()); }
}
|
不得不说,IDEA真的厉害,上面的是我写的原始代码,它提示我修改为下面的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import java.io.File; import java.util.Arrays; import java.util.Comparator; import java.util.TreeSet;
public class FileTraverse { static File f = new File("D:\\test");
public static void main(String[] args) { File[] fileArray = f.listFiles(); TreeSet<File> fileSet = new TreeSet<>(Comparator.comparingLong(File::length)); assert fileArray != null; fileSet.addAll(Arrays.asList(fileArray)); System.out.println(f.length()); System.out.println("min is" + fileSet.first() + ' ' + fileSet.first().length()); System.out.println("max is" + fileSet.last() + ' ' + fileSet.last().length()); }
}
|
关于方法引用和断言,我会在写一篇.
下面是不使用容器写的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| package file; import java.io.File; public class TestFile { public static void main(String[] args) { File f = new File("c:\\windows"); File[] fs = f.listFiles(); if(null==fs) return; long minSize = Integer.MAX_VALUE; long maxSize = 0; File minFile = null; File maxFile = null; for (File file : fs) { if(file.isDirectory()) continue; if(file.length()>maxSize){ maxSize = file.length(); maxFile = file; } if(file.length()!=0 && file.length()<minSize){ minSize = file.length(); minFile = file; } } System.out.printf("最大的文件是%s,其大小是%,d字节%n",maxFile.getAbsoluteFile(),maxFile.length()); System.out.printf("最小的文件是%s,其大小是%,d字节%n",minFile.getAbsoluteFile(),minFile.length()); } }
|
2.遍历子文件夹
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| package file; import java.io.File; public class TestFile { static long minSize = Integer.MAX_VALUE; static long maxSize = 0; static File minFile = null; static File maxFile = null; public static void listFiles(File file){ if(file.isFile()){ if(file.length()>maxSize){ maxSize = file.length(); maxFile = file; } if(file.length()!=0 && file.length()<minSize){ minSize = file.length(); minFile = file; } return; } if(file.isDirectory()){ File[] fs = file.listFiles(); if(null!=fs) for (File f : fs) { listFiles(f); } } }
public static void main(String[] args) { File f = new File("c:\\windows"); listFiles(f); System.out.printf("最大的文件是%s,其大小是%,d字节%n",maxFile.getAbsoluteFile(),maxFile.length()); System.out.printf("最小的文件是%s,其大小是%,d字节%n",minFile.getAbsoluteFile(),minFile.length());
} }
|
输入输出流
这张图表明了流的体系结构,斜体是基类,粗体是节点流.我们从三个方面来划分它们的种类.
以上的具体划分参见Java笔记11那篇.
以字节流的形式读取文件内容
InputStream是字节输入流,同时也是抽象类,只提供方法声明,不提供方法的具体实现。
FileInputStream 是InputStream子类,以FileInputStream为例进行文件读取.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| package stream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; public class TestStream { public static void main(String[] args) { try { File f =new File("d:/lol.txt"); FileInputStream fis =new FileInputStream(f); byte[] all =new byte[(int) f.length()]; fis.read(all); for (byte b : all) { System.out.println(b); } fis.close(); } catch (IOException e) { e.printStackTrace(); } } }
|
以字节流的形式向文件写入数据
OutputStream是字节输出流,同时也是抽象类,只提供方法声明,不提供方法的具体实现。 FileOutputStream 是OutputStream子类,以FileOutputStream 为例向文件写出数据.
注: 如果文件d:/lol2.txt不存在,写出操作会自动创建该文件。 但是如果是文件d:/xyz/lol2.txt,而目录xyz又不存在,会抛出异常.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| package stream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; public class TestStream { public static void main(String[] args) { try { File f = new File("d:/lol2.txt"); byte data[] = { 88, 89 }; FileOutputStream fos = new FileOutputStream(f); fos.write(data); fos.close(); } catch (IOException e) { e.printStackTrace(); } } }
|
练习一
1.拆分文件
找到一个大于100k的文件,按照100k为单位,拆分成多个子文件,并且以编号作为文件名结束。 比如文件 eclipse.exe,大小是309k。 拆分之后,成为
eclipse.exe-0
eclipse.exe-1
eclipse.exe-2
eclipse.exe-3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| package stream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.Arrays; public class TestStream { public static void main(String[] args) { int eachSize = 100 * 1024; File srcFile = new File("d:/eclipse.exe"); splitFile(srcFile, eachSize); }
private static void splitFile(File srcFile, int eachSize) { if (0 == srcFile.length()) throw new RuntimeException("文件长度为0,不可拆分"); byte[] fileContent = new byte[(int) srcFile.length()]; try { FileInputStream fis = new FileInputStream(srcFile); fis.read(fileContent); fis.close(); } catch (IOException e) { e.printStackTrace(); } int fileNumber; if (0 == fileContent.length % eachSize) fileNumber = (int) (fileContent.length / eachSize); else fileNumber = (int) (fileContent.length / eachSize) + 1; for (int i = 0; i < fileNumber; i++) { String eachFileName = srcFile.getName() + "-" + i; File eachFile = new File(srcFile.getParent(), eachFileName); byte[] eachContent; if (i != fileNumber - 1) eachContent = Arrays.copyOfRange(fileContent, eachSize * i, eachSize * (i + 1)); else eachContent = Arrays.copyOfRange(fileContent, eachSize * i, fileContent.length); try { FileOutputStream fos = new FileOutputStream(eachFile); fos.write(eachContent); fos.close(); System.out.printf("输出子文件%s,其大小是 %d字节%n", eachFile.getAbsoluteFile(), eachFile.length()); } catch (IOException e) { e.printStackTrace(); } } } }
|
2.合并文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| package stream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import javax.security.auth.DestroyFailedException; public class TestStream { public static void main(String[] args) { murgeFile("d:/", "eclipse.exe"); }
private static void murgeFile(String folder, String fileName) { try { File destFile = new File(folder, fileName); FileOutputStream fos = new FileOutputStream(destFile); int index = 0; while (true) { File eachFile = new File(folder, fileName + "-" + index++); if (!eachFile.exists()) break; FileInputStream fis = new FileInputStream(eachFile); byte[] eachContent = new byte[(int) eachFile.length()]; fis.read(eachContent); fis.close(); fos.write(eachContent); fos.flush(); System.out.printf("把子文件 %s写出到目标文件中%n",eachFile); } fos.close(); System.out.printf("最后目标文件的大小:%,d字节" , destFile.length()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
|
关闭流
在try中关闭
在try的作用域里关闭文件输入流,在前面的练习中都是使用这种方式,这样做有一个弊端; 如果文件不存在,或者读取的时候出现问题而抛出异常,那么就不会执行这一行关闭流的代码,存在巨大的资源占用隐患.不推荐使用.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| package stream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; public class TestStream { public static void main(String[] args) { try { File f = new File("d:/lol.txt"); FileInputStream fis = new FileInputStream(f); byte[] all = new byte[(int) f.length()]; fis.read(all); for (byte b : all) { System.out.println(b); } fis.close(); } catch (IOException e) { e.printStackTrace(); } } }
|
在finally中关闭
这是标准的关闭流的方式
- 首先把流的引用声明在try的外面,如果声明在try里面,其作用域无法抵达finally.
- 在finally关闭之前,要先判断该引用是否为空
- 关闭的时候,需要再一次进行try catch处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| package stream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; public class TestStream { public static void main(String[] args) { File f = new File("d:/lol.txt"); FileInputStream fis = null; try { fis = new FileInputStream(f); byte[] all = new byte[(int) f.length()]; fis.read(all); for (byte b : all) { System.out.println(b); } } catch (IOException e) { e.printStackTrace(); } finally { if (null != fis) try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } }
|
使用try()的方式
把流定义在try()里,try,catch或者finally结束的时候,会自动关闭这种编写代码的方式叫做try-with-resources,这是从JDK7开始支持的技术.
所有的流,都实现了一个接口叫做 AutoCloseable,任何类实现了这个接口,都可以在try()中进行实例化.并且在try, catch, finally结束的时候自动关闭,回收相关资源。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package stream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; public class TestStream { public static void main(String[] args) { File f = new File("d:/lol.txt"); try (FileInputStream fis = new FileInputStream(f)) { byte[] all = new byte[(int) f.length()]; fis.read(all); for (byte b : all) { System.out.println(b); } } catch (IOException e) { e.printStackTrace(); } } }
|
使用字符流读取文件
FileReader是Reader子类,以FileReader为例进行文件读取 .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| package stream; import java.io.File; import java.io.FileReader; import java.io.IOException; public class TestStream { public static void main(String[] args) { File f = new File("d:/lol.txt"); try (FileReader fr = new FileReader(f)) { char[] all = new char[(int) f.length()]; fr.read(all); for (char b : all) { System.out.println(b); } } catch (IOException e) { e.printStackTrace(); } } }
|
使用字符流把字符串写入到文件
FileWriter是Writer的子类,以FileWriter为例把字符串写入到文件.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| package stream; import java.io.File; import java.io.FileWriter; import java.io.IOException; public class TestStream { public static void main(String[] args) { File f = new File("d:/lol2.txt"); try (FileWriter fr = new FileWriter(f)) { String data="abcdefg1234567890"; char[] cs = data.toCharArray(); fr.write(cs); } catch (IOException e) { e.printStackTrace(); } } }
|
练习二
1.加密文件
准备一个文本文件(非二进制),其中包含ASCII码的字符和中文字符。
设计一个方法:
public static void encodeFile(File encodingFile, File encodedFile);
在这个方法中把encodingFile的内容进行加密,然后保存到encodedFile文件中。
加密算法:
- 数字:
- 如果不是9的数字,在原来的基础上加1,比如5变成6, 3变成4
- 如果是9的数字,变成0
- 字母字符:
- 如果是非z字符,向右移动一个,比如d变成e, G变成H
- 如果是z,z->a, Z-A。
- 字符需要保留大小写
- 非字母字符
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| package stream; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class TestStream {
public static void encodeFile(File encodingFile, File encodedFile) { try (FileReader fr = new FileReader(encodingFile); FileWriter fw = new FileWriter(encodedFile)) { char[] fileContent = new char[(int) encodingFile.length()]; fr.read(fileContent); System.out.println("加密前的内容:"); System.out.println(new String(fileContent)); encode(fileContent); System.out.println("加密后的内容:"); System.out.println(new String(fileContent)); fw.write(fileContent); } catch (IOException e) { e.printStackTrace(); } } private static void encode(char[] fileContent) { for (int i = 0; i < fileContent.length; i++) { char c = fileContent[i]; if (isLetterOrDigit(c)) { switch (c) { case '9': c = '0'; break; case 'z': c = 'a'; break; case 'Z': c = 'A'; break; default: c++; break; } } fileContent[i] = c; } } public static boolean isLetterOrDigit(char c) { String letterOrDigital = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; return -1 == letterOrDigital.indexOf(c) ? false : true; } public static void main(String[] args) { File encodingFile = new File("E:/project/j2se/src/Test1.txt"); File encodedFile = new File("E:/project/j2se/src/Test2.txt"); encodeFile(encodingFile, encodedFile); } }
|
2.解密文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| package stream; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class TestStream {
public static void decodeFile(File decodingFile, File decodedFile) { try (FileReader fr = new FileReader(decodingFile); FileWriter fw = new FileWriter(decodedFile)) { char[] fileContent = new char[(int) decodingFile.length()]; fr.read(fileContent); System.out.println("源文件的内容:"); System.out.println(new String(fileContent)); decode(fileContent); System.out.println("解密后的内容:"); System.out.println(new String(fileContent)); fw.write(fileContent); } catch (IOException e) { e.printStackTrace(); } } private static void decode(char[] fileContent) { for (int i = 0; i < fileContent.length; i++) { char c = fileContent[i]; if (isLetterOrDigit(c)) { switch (c) { case '0': c = '9'; break; case 'a': c = 'z'; break; case 'A': c = 'Z'; break; default: c--; break; } } fileContent[i] = c; } } public static boolean isLetterOrDigit(char c) { String letterOrDigital ="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; return -1 == letterOrDigital.indexOf(c) ? false : true; } public static void main(String[] args) { File decodingFile = new File("E:/project/j2se/src/Test2.txt"); File decodedFile = new File("E:/project/j2se/src/Test1.txt"); decodeFile(decodingFile, decodedFile); } }
|
编码问题
编码问题真的是非常烦,我总结了三点注意事项:
更多编码问题参见连接:http://how2j.cn/k/io/io-encoding/695.html#step2489
缓存流
按照前面的划分:
已经从输入输出角度和字符字节角度讲了一些,而节点流是连接物理节点的,处理流是连接节点流的.还有和特殊类别是缓存流.先看看一个通俗解释:
flush本意是冲刷,这个方法大概取自它引申义冲马桶的意思,马桶有个池子,你往里面扔东西,会暂时保存在池子里,只有你放水冲下去,东西才会进入下水道。同理很多流都有一个这样的池子,专业术语叫缓冲区,当你print或者write的时候,会暂时保存在缓冲区,并没有发送出去,这是出于效率考虑的,因为数据不会自己发送过去,必须有其他机制,而且这个很消耗资源,就像马桶你需要很多水,才能冲走,你如果扔一点东西,就冲一次水,那你水费要爆表了,同样如果你写一行文字,或者一个字节,就要马上发送出去,那网络流量,CPU使用率等等都要爆表了,所以一般只有在你真正需要发送否则无法继续的时候,调用flush,将数据发送出去。
里面提到的flush()方法是用来将缓冲强制清空的方法(不是删除数据,而是在缓冲区未满的情况下将数据提前输入/输出),关闭流时会自动调用此方法.
使用缓存流读取数据
注意,缓存流都是处理流,需要在一个现成的节点流.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| package stream; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; public class TestStream { public static void main(String[] args) { File f = new File("d:/lol.txt"); try ( FileReader fr = new FileReader(f); BufferedReader br = new BufferedReader(fr); ) { while (true) { String line = br.readLine(); if (null == line) break; System.out.println(line); } } catch (IOException e) { e.printStackTrace(); } } }
|
使用缓存流写出数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| package stream; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; public class TestStream { public static void main(String[] args) { File f = new File("d:/lol2.txt"); try ( FileWriter fw = new FileWriter(f); PrintWriter pw = new PrintWriter(fw); ) { pw.println("garen kill teemo"); pw.println("teemo revive after 1 minutes"); pw.println("teemo try to garen, but killed again"); } catch (IOException e) { e.printStackTrace(); } } }
|
数据流
为什么要用数据流?当向某个文件连续写入数字1,2,3时,如果用普通的输出流,就必须认为加上一些标识符(例如’,’用来分割数据,不至于变成123).同样的为了正确取出数据,在读入后还需要将这些标志性的字符去掉.而使用数据流就可以避免这些操作.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| package stream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class TestStream { public static void main(String[] args) { write(); read(); } private static void read() { File f =new File("d:/lol.txt"); try ( FileInputStream fis = new FileInputStream(f); DataInputStream dis =new DataInputStream(fis); ){ boolean b= dis.readBoolean(); int i = dis.readInt(); String str = dis.readUTF(); System.out.println("读取到布尔值:"+b); System.out.println("读取到整数:"+i); System.out.println("读取到字符串:"+str); } catch (IOException e) { e.printStackTrace(); } } private static void write() { File f =new File("d:/lol.txt"); try ( FileOutputStream fos = new FileOutputStream(f); DataOutputStream dos =new DataOutputStream(fos); ){ dos.writeBoolean(true); dos.writeInt(300); dos.writeUTF("123 this is gareen"); } catch (IOException e) { e.printStackTrace(); } } }
|
有几点要注意:
- DataOutputStream的文件要DataInputStream来打开,否则会产生异常
- 注意写入和读取时的顺序
对象流
对象流指的是可以直接把一个对象以流的形式传输给其他的介质,比如硬盘.一个对象以流的形式进行传输,叫做序列化。 该对象所对应的类,必须是实现Serializable接口.
练习
准备一个长度是10,类型是Hero的数组,使用10个Hero对象初始化该数组,然后把该数组序列化到一个文件heros.lol接着使用ObjectInputStream读取该文件,并转换为Hero数组,验证该数组中的内容,是否和序列化之前一样.
1 2 3 4 5 6 7 8 9 10 11
| import java.io.Serializable;
class Hero implements Serializable { private static final long serialVersionUID = 1L; String name; float hp; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| import java.io.*; import java.util.ArrayList; import java.util.List;
public class SerialFileTest { public static void main(String[] args) { int capacity = 10; List<Hero> heroes = new ArrayList<>(capacity); for (int i = 0; i < capacity; i++) { String n = "hero" + String.valueOf(i); int h = 616 + i; Hero hero = new Hero() {{ name = n; hp = h; }}; heroes.add(hero); }
File f = new File("./src/heroes.lol"); try (FileOutputStream fos = new FileOutputStream(f); ObjectOutputStream oos = new ObjectOutputStream(fos)) { oos.writeObject(heroes); } catch (IOException e) { e.printStackTrace(); }
try (FileInputStream fis = new FileInputStream(f); ObjectInputStream ois = new ObjectInputStream(fis)) { List<Hero> list = (List<Hero>) ois.readObject(); for (Hero hero : list) { System.out.println(hero.name); System.out.println(hero.hp); } } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } } }
|
标准输入输出
System.in的定义是public static final InputStream in = null;
,而System.out定义是public static final PrintStream out = null;
,所以标准输入输出是字节流.
运用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| import java.io.*; import java.util.Scanner;
public class ObjectCreate { public static void main(String[] args) throws IOException { Scanner sc = new Scanner(System.in); System.out.println("请输入类名:"); String className = sc.nextLine(); System.out.println("请输入属性类别:"); String property = sc.nextLine(); System.out.println("请输入属性名称:"); String name = sc.nextLine(); getFile(className, property, name); System.out.println("名为" + className + ".java的文件已生成,存放在d:/" + className + ".java"); }
public static void getFile(String className, String property, String name) { File outFile = new File("./src/" + className + ".java"); File inFile = new File("./src/model.txt"); try (FileReader fr = new FileReader(inFile); BufferedReader br = new BufferedReader(fr) ) { StringBuilder read = new StringBuilder(); while (true) { String s = br.readLine(); if (s == null) { break; } read.append(s).append("\r\n"); } System.out.println(read); System.out.println("这里是分割线-----------------------------------------"); String write = read.toString().replaceAll("@class@", className); write = write.replaceAll("@type@", property); write = write.replaceAll("@property@", name); char[] c = name.toCharArray(); if (c[0] >= 'a' && c[0] <= 'z') { c[0] = (char) (c[0] - 32); } name = new String(c); write = write.replaceAll("@Uproperty@", name); System.out.println(write); FileWriter fileWriter = new FileWriter(outFile); BufferedWriter bw = new BufferedWriter(fileWriter); bw.write(write); br.close(); bw.flush(); bw.close(); } catch (IOException e) { e.printStackTrace(); } } }
|
本篇中有不少东西没讲,包括RandomAccessFile,NIO,NIO.2,对象序列化都没讲,所以这部分会另开一篇.