关于IO流的一些细节

关于IO流的一些细节,第1张

关于IO流的一些细节 IO流:
  • 字符流 :Reader / Writer
  • 字节流:InputStream / OutputStream
File类:
  1. 构造:

    • 构造File对象时,既可以传入绝对路径,也可以传入相对路径。绝对路径是以根目录开头的完整路径,例如:

          //相对:
          File f = new File("src/com/company/IO/露中生.txt");
      	//绝对路径:
      	File f = new File("C:UsersASUSDesktopJavasrccomcompanyIO露中生.txt")
      
    • 可以用.表示当前目录,..表示上级目录。

  2. 路径获取与文件 *** 作:

    • 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对象表示的目录,当前目录必须为空才能删除成功。
      
InputStream
  • read方法使用:

    1. 这个方法会读取输入流的下一个字节,并返回字节表示的int值(0~255)。如果已读到末尾,返回-1表示不能继续读取了。

    2. 缓冲:

      在读取流的时候,一次读取一个字节并不是最高效的方法。很多流支持一次性读取多个字节到缓冲区,对于文件和网络流来说,利用缓冲区一次性读取多个字节效率往往要高很多。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
  1. flush方法:

    将缓冲区的数据输出,一般在网络编程,类似于聊天的功能力会使用

  2. 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);
            }
        }
字符流:
  1. 如果我们读取一个纯ASCII编码的文本文件,上述代码工作是没有问题的。但如果文件中包含中文,就会出现乱码,因为FileReader默认的编码与系统相关,例如,Windows系统的默认编码可能是GBK,打开一个UTF-8编码的文本文件就会出现乱码。

    要避免乱码问题,我们需要在创建FileReader时指定编码:

     Reader reader = new FileReader("...".StabdardCharsets.UTF-8);
    
  2. 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"));
    

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4660960.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-06
下一篇 2022-11-06

发表评论

登录后才能评论

评论列表(0条)

保存