date: 2020-06-14 14:42:22

updated: 2020-08-21 17:35:45

Java IO相关使用

1. 文件

创建 File 对象的三种方式

  • 一个路径名:File(String pathname)
  • 一个父路径名和子路径名:File(File parent, String child)File(String parent, String child)
  • 一个URI (统一资源标识符):File(URI uri)

有文件时覆盖,无文件时创建。

通过 f.getAbsolutePath()f.getCanonicalPath() 可获取文件的绝对路径和规范路径

f.delete() 会立即删除文件,而 f.deleteOnExit() 会延迟删除,直到JVM调用该方法

File 对象不可变,始终表示文件的路径名。文件经过创建、删除后,File 对象依旧是原始的路径名,并不代表实际的文件。

2. 输入字节流

抽象基类是 InputStream 类,结构关系如下:

InputStream

|

+--FileInputStream

|

+--ByteArrayInputStream

|

+--PipedInputStream

|

+--FilterInputStream

|

+--BufferedInputStream

|

+--PushbackInputStream

|

+--DataInputStream

|

+--ObjectInputStream

基类的基本方法如下:

方法 描述
read() 读取一个字节并将读取的字节作为int返回。当到达输入流的结尾时,它返回-1。
read(byte[] buffer) 读取最大值直到指定缓冲区的长度。它返回在缓冲区中读取的字节数。如果到达输入流的结尾,则返回-1。
read(byte[] buffer,int offset, int length) 读取最大值到指定长度字节。数据从偏移索引开始写入缓冲区。它返回读取的字节数,如果到达输入流的结束它返回-1。
close() 关闭输入流
available() 返回可以从此输入流读取但不阻塞的估计字节数。

2.1 BufferedInputStream

通过缓冲数据向输入流添加功能。维护一个内部缓冲区以存储从底层输入流读取的字节。

import java.io.*;

public static void main(String[] args) throws IOException {
String filePath = "/Users/mxxct/Desktop/md_meter.java";
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filePath));
byte[] buffer = new byte[1024]; // 长度为1024个字节的缓冲区
int len = -1; // 偏移量,或本次读取的字节数
StringBuilder content = null;
// 此次读取的字节数赋值给 len,如果等于 -1 说明已经读完了
while((len = bis.read(buffer)) != -1){
content.append(new String(buffer, 0, len));
}
System.out.println(content);
bis.close();
}

3. 输出字节流

FileOutputStream fos = new FileOutputStream(destFile); 创建一个 FileOutputStream 对象,如果文件不存在,会尝试创建文件,但必须处理异常 FileNotFoundException,需要放在 try-catch 里面。

如果文件包含数据,数据会被覆盖。如果要追加,需要添加一个第二个参数,true 表示追加。

fos.write(int b)

fos.write(byte[] b)

fos.write(byte[] b, int off, int len)

由于输出的是字节流,所以只能 write int 或 byte[],如果是字符串的话,通过 getBytes() 方法可以返回字节数组

通过 fos.flush() 方法刷新输出流:将 write 里的字节缓存清出,写入到目标处。

4. 管道

管道IO基于生产者--消费者模式,PipedOutputStream 负责把数据写入到管道里,相当于生产者, PipedInputStream 负责读取管道里的数据

两种连接管道的方式

PipedInputStream pis  = new PipedInputStream();
PipedOutputStream pos = new PipedOutputStream();
pis.connect(pos); /* Connect the two ends */ PipedInputStream pis = new PipedInputStream();
PipedOutputStream pos = new PipedOutputStream(pis, 2048); // 缓冲区容量为2048字节
当创建管道时,可以设置管道容量。 如果管道的缓冲区已满,则尝试在管道上写入将会被阻止。

5. 字符输入流

Reader是所有的输入字符流的父类,它是一个抽象类

FilterReader是所有自定义具体装饰流的父类,其子类PushbackReader对Reader对象进行装饰,会增加一个行号

InputStreamReader是一个连接字节流和字符流的桥梁,它将字节流转变为字符流。FileReader可以说是一个达到此功能、常用的工具类,在其源代码中明显使用了将FileInputStream转变为Reader的方法。我们可以从这个类中得到一定的技巧。Reader中各个类的用途和使用方法基本和InputStream中的类使用一致。后面会有Reader与InputStream的对应关系。

BufferedReader reader = new BufferedReader(new FileReader(filePath));
String str;
while((str=reader.readLine())!=null){
System.out.println(str);
}

6. 字符输出流

问:字节流与字符流有什么区别?

答:计算机中的一切最终都是以二进制字节形式存在的,对于我们经常操作的字符串,在写入时其实都是先将字符转成对应的字节,然后将字节写入到输出流,在读取时其实都是先读到的是字节,然后将字节直接使用或者转换为字符给我们使用。由于对于字节和字符两种操作的需求比较广泛,所以 Java 专门提供了字符流与字节流相关IO类。

对于程序运行的底层设备来说永远都只接受字节数据,所以当我们往设备写数据时无论是字节还是字符最终都是写的字节流。字符流是字节流的包装类,所以当我们将字符流向字节流转换时要注意编码问题(因为字符串转成字节数组的实质是转成该字符串的某种字节编码)。

字符流和字节流的使用非常相似,但是实际上字节流的操作不会经过缓冲区(内存)而是直接操作文本本身的,而字符流的操作会先经过缓冲区(内存)然后通过缓冲区再操作文件。

1、字节流在操作的时候本身是不会用到缓冲区(内存)的,是与文件本身直接操作的,而字符流在操作的时候是使用到缓冲区的

2、字节流在操作文件时,即使不关闭资源(close方法),文件也能输出,但是如果字符流不使用close方法的话,则不会输出任何内容,说明字符流用的是缓冲区,并且可以使用flush方法强制进行刷新缓冲区,这时才能在不close的情况下输出内容

3、Reader类的read()方法返回类型为int :作为整数读取的字符(占两个字节共16位),范围在 0 到 65535 之间 (0x00-0xffff),如果已到达流的末尾,则返回 -1

inputStream的read()虽然也返回int,但由于此类是面向字节流的,一个字节占8个位,所以返回 0 到 255 范围内的 int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。因此对于不能用0-255来表示的值就得用字符流来读取!比如说汉字.

4、字节流与字符流主要的区别是他们的的处理方式

字节流:处理字节和字节数组或二进制对象;

字符流:处理字符、字符数组或字符串。

问:什么是缓冲区?有什么作用?

答:缓冲区就是一段特殊的内存区域,很多情况下当程序需要频繁地操作一个资源(如文件或数据库)则性能会很低,所以为了提升性能就可以将一部分数据暂时读写到缓存区,以后直接从此区域中读写数据即可,这样就显著提升了性能。

对于 Java 字符流的操作都是在缓冲区操作的,所以如果我们想在字符流操作中主动将缓冲区刷新到文件则可以使用 flush() 方法操作。

问:如何选择字节流和字符流?

答:如果是文本文件通常使用字符流,而像视频,图片,音频等文件都是二进制数据使用字节流。当然文本文件也可以使用字节流来操作,字节流更通用。

如果只是复制纯文本文件不做显示操作,哪个流都可以,如果要显示纯文本就用字符流。

问:为什么对于字符流中都有flush方法,但是字节流中没有?

字节流的操作不会经过缓冲区(内存)而是直接操作文本本身的,而字符流的操作会先经过缓冲区(内存)然后通过缓冲区再操作文件。

Java IO相关使用的更多相关文章

  1. Java IO入门

    目录 一. 数据源(流) 二. 数据传输 三. 总结 我们从两个方面来理解Java IO,数据源(流).数据传输,即IO的核心就是对数据源产生的数据进行读写并高效传输的过程. 一. 数据源(流) 数据 ...

  2. 文件IO 相关的包:java.io文件——API

    文件IO 相关的包:java.io文件——API 1.Java.io.File类的使用(1)两种路径绝对路径:相对于当前路径:当前为 “工程名”(2)File类创建,对象为一个文件/目录,可能存在或不 ...

  3. java IO流详解

    流的概念和作用 学习Java IO,不得不提到的就是JavaIO流. 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...

  4. Java IO流学习总结

    Java流操作有关的类或接口: Java流类图结构: 流的概念和作用 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...

  5. java.lang.IndexOutOfBoundsException at java.io.FileOutputStream.writeBytes(Native Method)

    ss available : /usr/linkapp/data/linkapp/ddn_1440639847758_temp java.lang.IndexOutOfBoundsException ...

  6. java IO流 之 字节流

    一.file类的常用操作 File file=new File("E:\\test\\javaIo"); System.out.println(file.isDirectory() ...

  7. [Java IO]02_字节流

    概要 字节流有两个核心抽象类:InputStream 和 OutputStream.所有的字节流类都继承自这两个抽象类. InputStream 负责输入,OutputStream 负责输出. 字节流 ...

  8. 【转】java NIO 相关知识

    原文地址:http://www.iteye.com/magazines/132-Java-NIO Java NIO(New IO)是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的 ...

  9. Java IO设计模式彻底分析 (转载)

    一.引子(概括地介绍Java的IO) 无论是哪种编程语言,输入跟输出都是重要的一部分,Java也不例外,而且Java将输入/输出的功能和使用范畴做了很大的扩充.它采用了流的 机制来实现输入/输出,所谓 ...

随机推荐

  1. 《Mybatis进阶》肝了30天专栏文章,整理成册,免费获取!!!

    持续原创输出,点击上方蓝字关注我吧 目录 前言 简介 如何获取? 总结 前言 Mybatis专栏文章写到至今已经有一个月了,从基础到源码详细的介绍了每个知识点,没什么多余的废话,全是工作.面试中常用到 ...

  2. kali一些基础工具

    目录 netcat netcat https://blog.csdn.net/fageweiketang/article/details/82833193 网络工具当中的瑞士军刀 -nc指令,nc可以 ...

  3. PYG2010-02-精装友情通讯录再分析

  4. 你在开发过程中使用Git Rebase还是Git Merge?

    摘要:在git里面经常的一个争论是到底用rebase还是用merge? 1. 痛苦吗?代码历史中的迷失羔羊 我们先来看一个真实的代码提交历史图形化截图: 图片源自 https://storage.kr ...

  5. GAN在seq2seq中的应用 Application to Sequence Generation

    Improving Supervised Seq-to-seq Model 有监督的 seq2seq ,比如机器翻译.聊天机器人.语音辨识之类的 . 而 generator 其实就是典型的 seq2s ...

  6. 027 01 Android 零基础入门 01 Java基础语法 03 Java运算符 07 逻辑“与”运算符

    027 01 Android 零基础入门 01 Java基础语法 03 Java运算符 07 逻辑"与"运算符 本文知识点:Java中的逻辑"与"运算符 逻辑运 ...

  7. Matlab中num2str函数的用法

    转载:https://blog.csdn.net/SMF0504/article/details/51836062 函数功能: 把数值转换成字符串, 转换后可以使用fprintf或disp函数进行输出 ...

  8. Object.assign()的使用

    一.Object.assign()对象的拷贝 1 Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象.它将返回目标对象. 2 Object.assign(ta ...

  9. Linux为STDOUT的关键字设置颜色

    echo "颜色测试aaa实测" | perl -pe 's/(aaa|实|测)/\e[1;31m$1\e[0m/g'

  10. 【Jenkins】远程调用jenkins进行构建方式!

    前提:jenkins支持远程调用(具体设置自行百度)1.在我的个人中心--configure--API TOKEN--如果没有,则添加一个token,并生成,再复制并记录下来2.在你的job上面加上你 ...