一、I/O家族
下图为java自带的IO操作的整体家族树状图,整体分为字节流和字符流两大类,它们的区别在于:
- 字节流是以字节为单位来传输数据,它按照输入/输出方向不同分为了两个大父类:InputStream和OutputStream
- 字符流是以多个字节为单位来传输数据,它按照输入/输出方向不同分为了两个大父类:Reader和Writer
⚠️ 注:本文仅讲字节流常用的几种读写数据的方式以及好用的nio api,其余想要详细了解可以网上查阅具体的资料。
二、如何利用字节流读写数据?
2.1:写
我们现在写一个程序,让它新建一个文件,命名为a.txt
,如果文件已经存在,则不再创建,然后通过程序往它的里面写入一句话:”Java是世界上坠吼滴语言!“:
代码块11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public static void main(String[] args) throws IOException { File aFile; OutputStream os = null; try { aFile = new File("/Users/sunqinwen/Documents/a.txt"); if (!aFile.exists()) { if (!aFile.createNewFile()) { System.out.println("创建文件失败!"); return; } } os = new FileOutputStream(aFile); os.write("Java是世界上坠吼滴语言!".getBytes(StandardCharsets.UTF_8)); System.out.println("执行完毕!"); } finally { if (os != null) { os.close(); } } }
|
2.2:读
上方运行结果就是a文件被创建了出来,并且顺利将那段文本写了进去,现在我们再来写一个程序,把这个文件里的信息读入到程序中,这时就要借助我们的输入流InputStream
了:
代码块21 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
| public static void main(String[] args) throws IOException { File aFile; InputStream is = null; try { aFile = new File("/Users/sunqinwen/Documents/a.txt"); if (!aFile.exists()) { System.out.println("文件不存在!"); return; } is = new FileInputStream(aFile); byte[] msg = new byte[1024]; StringBuilder sb = new StringBuilder(); int n; while ((n = is.read(msg)) > 0) { sb.append(new String(msg, 0, n, StandardCharsets.UTF_8)); } System.out.println(sb); } catch (IOException e) { e.printStackTrace(); } finally { if (is != null) { is.close(); } } }
|
通过上面的方式,利用FileInputStream
,可以将文件里的信息读出来。
对于文件读写、创建,理论上掌握一种方式就可以,但是你会发现上面的写法真的很啰嗦,java有没有更好的读写文件的方法呢?来看下一节。
三、利用JAVA NIO API创建&读写文件
不知道你发现了没,Mac系统的文件路径是正斜杠划分,而Windows系统却是反斜杠,这就意味着你上面的代码对于文件路径这一块在双系统下是不兼容的,而且上面的代码很繁琐,于是Java提供了更好用的NIO API,让我们来改造下上面的代码。
3.1:写
将”Java是世界上坠吼滴语言!“写入同路径的b.txt文件:
代码块31 2 3 4 5 6 7 8
| public static void main(String[] args) throws IOException { Path path = Paths.get("/Users", "sunqinwen", "Documents", "b.txt"); if (!Files.exists(path)) { Files.createFile(path); } Files.write(path, "Java是世界上坠吼滴语言!".getBytes(StandardCharsets.UTF_8)); System.out.println("执行完毕!"); }
|
这里用Path来组装路径,利用Path组装后的路径会智能转成符合当前操作系统的路径模式。然后利用Files完成文件的创建和写入。
3.2:读
现在将这句话从文件里读出来,相比2.2
,真的简化了好多:
代码块41 2 3 4
| public static void main(String[] args) throws IOException { Path path = Paths.get("/Users", "sunqinwen", "Documents", "b.txt"); System.out.println(Files.readString(path, StandardCharsets.UTF_8)); }
|
同样利用Path组装路径,然后利用Files读取数据。
Files读取数据时,我们可以详细探索下,它是很有用的一个工具类: