File类:
- 字符流 :Reader / Writer
- 字节流:InputStream / OutputStream
-
构造:
-
构造File对象时,既可以传入绝对路径,也可以传入相对路径。绝对路径是以根目录开头的完整路径,例如:
//相对: File f = new File("src/com/company/IO/露中生.txt"); //绝对路径: File f = new File("C:UsersASUSDesktopJavasrccomcompanyIO露中生.txt")
-
可以用.表示当前目录,..表示上级目录。
-
-
路径获取与文件 *** 作:
-
File对象有3种形式表示的路径
//相对路径: src/com/company/IO/露中生.txt f.getPath(); //绝对路径:C:UsersASUSDesktopJavasrccomcompanyIO露中生.txt f.getAbsolutePath(); //规范路径:把.或..转换成路径名的绝对路径 f.getCanonicalPath();
-
用File对象获取到一个文件时,还可以进一步判断文件的权限和大小
boolean canRead():是否可读; boolean canWrite():是否可写; boolean canExecute():是否可执行; long length():文件字节大小。
-
创建和删除
boolean createNewFile() 创建 boolean delete() 删除
-
File对象如果表示一个目录,可以通过以下方法创建和删除目录:
boolean mkdir():创建当前File对象表示的目录; boolean mkdirs():创建当前File对象表示的目录,并在必要时将不存在的父目录也创建出来; boolean delete():删除当前File对象表示的目录,当前目录必须为空才能删除成功。
-
-
read方法使用:
-
缓冲:
在读取流的时候,一次读取一个字节并不是最高效的方法。很多流支持一次性读取多个字节到缓冲区,对于文件和网络流来说,利用缓冲区一次性读取多个字节效率往往要高很多。InputStream提供了两个重载方法来支持读取多个字节:
- int read(byte[] b):读取若干字节并填充到byte[]数组,返回读取的字节数
- int read(byte[] b, int off, int len):指定byte[]数组的偏移量和最大填充数
利用上述方法一次读取多个字节时,需要先定义一个byte[]数组作为缓冲区,read()方法会尽可能多地读取字节到缓冲区, 但不会超过缓冲区的大小。read()方法的返回值不再是字节的int值,而是返回实际读取了多少个字节。如果返回-1,表示没有更多的数据了。
public void readFile() throws IOException { try (InputStream input = new FileInputStream("src/readme.txt")) { // 定义1000个字节大小的缓冲区: byte[] buffer = new byte[1000]; int n; while ((n = input.read(buffer)) != -1) { // 读取到缓冲区 System.out.println("read " + n + " bytes."); } } }
-
try(resourse)使用:
public void readFile() throws IOException { try (InputStream input = new FileInputStream("src/readme.txt")) { int n; while ((n = input.read()) != -1) { System.out.println(n); } } // 编译器在此自动为我们写入finally并调用close() }OutputStream
-
flush方法:
将缓冲区的数据输出,一般在网络编程,类似于聊天的功能力会使用
-
Jdk9 transferTo方法:
try(FileInputStream fi = new FileInputStream("input.txt"); FileOutputStream fp = new FileOutputStream("output.txt")) { fi.transferTo(fp); }
等价于
try(FileInputStream fi = new FileInputStream("input.txt"); FileOutputStream fp = new FileOutputStream("o.txt")) { byte[] bytes = new byte[1024]; int len; while ((len = fi.read(bytes)) != -1) { fp.write(bytes, 0, len); } }
图片复制:
try(//输入: FileInputStream fi = new FileInputStream("C:\Users\ASUS\Desktop\壁纸\x1.jpg"); //输出路径,如果没有则新建一个 FileOutputStream fp = new FileOutputStream("src/com/company/IO/x2.jpg")) { byte[] bytes = new byte[1024]; int len; while ((len = fi.read(bytes)) != -1) { fp.write(bytes, 0, len); } }字符流:
-
如果我们读取一个纯ASCII编码的文本文件,上述代码工作是没有问题的。但如果文件中包含中文,就会出现乱码,因为FileReader默认的编码与系统相关,例如,Windows系统的默认编码可能是GBK,打开一个UTF-8编码的文本文件就会出现乱码。
要避免乱码问题,我们需要在创建FileReader时指定编码:
Reader reader = new FileReader("...".StabdardCharsets.UTF-8);
-
Reader(Writer)和InputStream(OutputStream)有什么关系?
除了特殊的CharArrayReader和StringReader,普通的Reader实际上是基于InputStream构造的,因为Reader需要从InputStream中读入字节流(byte),然后,根据编码设置,再转换为char就可以实现字符流。如果我们查看FileReader的源码,它在内部实际上持有一个FileInputStream。
既然Reader本质上是一个基于InputStream的byte到char的转换器,那么,如果我们已经有一个InputStream,想把它转换为Reader,是完全可行的。InputStreamReader就是这样一个转换器,它可以把任何InputStream转换为Reader。
Reader reader = new InputStreamReader(new FileInputStream("...", "UTF-8")); Writer writer = new OutputStreamWriter(new FileOutputStream("...", "UTF-8"));
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)