Java IO 总结

概述

IO 即输入输出输出系统,常见的操作系统,需要面对的介质非常之多,常见的IO介质有:

文件

网络

内存缓存

标准输入输出

线程通信

JDK设计了一系列接口和类,使面向不同的介质的IO操作都可以通过类似的接口来实现,这类接口都源自同一个抽象概念**流

流的分类

按照数据的流向可分为:

输入流

输出流

注意:输入流输出流是一个相对的概念,一般的从程序角度来定义:如果数据从程序流向设备则是输出,反之则是输入。

按照流的处理方式又可分为:

字节流

字符流

综合来讲流,可以按照如下分类

字节流

字符流

输入流

InputStream

Reader

输出流

OutputStream

Writter

JDK类库

JDK对流的设计采用了一种名为装饰器的设计模式。以输入流为例, 常见的输出流类的继承结构如下:

InputStream UML 图

图中 ByteArrayInputStream,StringBufferInputStream,FileInputStream,PipedInputStream,StringBufferInputStream 等类直用于从不同介质读取数据,被称为原始流。而 FilterInputStream 以及他的子类都有一个输入参数为InputStream的构造函数,用于包装原始流以增加跟多的功能,这些类被称为包装类。

对于 OutputStream,Reader,Writer JDK也采用了类似的设计,这里不再赘述.

常用的字符流和字节流,原始流和包装类整理如下:

Stream

Original Stream

Wrapper

InputStream

ByteArrayInputStream

StringBufferInputStream

FileInputStream

PipedInputStream

FilterInputStream

PushbackInputStream

LineNumberInputStream

BufferedInputStream

DataInputStream

OutputStream

FileOutputStream

PipedOutputStream

ByteArrayOutputStream

FileOutputStream

BufferedOutputStream

DataOutputStream

Reader

InputStreamReader

StringReader

CharArrayReader

PipedReader

FilterReader

PushbackReader

BufferedReader

LineNumberReader

Writter

InputStreamWritter

StringWritter

CharArrayWritter

PipedWritter

FilterWritter

PushbackWritter

BufferedWritter

LineNumberWritter

经常使用的类

文件IO

private static final String FILE_NAME = "D:\\test.txt";

private static final String NONSENS_CONTENT = "Once opon a time ...";

private static void writeFile() {

File file = new File(FILE_NAME);

FileOutputStream fos = null;

try {

if (!file.exists()) {

file.createNewFile();

}

fos = new FileOutputStream(file);

fos.write(NONSENS_CONTENT.getBytes());

fos.flush();

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

} finally {

if (fos != null) {

try {

fos.close();

} catch (IOException e) {

}

}

}

}

private static void readFile() {

File file = new File(FILE_NAME);

FileInputStream fis = null;

try {

fis = new FileInputStream(file);

byte[] bytes = new byte[(int) file.length()];

int readCount = fis.read(bytes);

String content = new String(bytes);

System.out.print("readFile count:" + readCount + " content:" + content);

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

} finally {

try {

fis.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

输出结果:

readFile count:20 content:Once opon a time ...

为文件读写增加缓存

将上面读写的代码修改为写入10000000次,并一次读取64个字节,观察下写入和读取的时间:

Write

long start = System.currentTimeMillis();

byte bytes[] = NONSENS_CONTENT.getBytes();

fos = new FileOutputStream(file);

for (int i = 0; i < 10000000; i++) {

fos.write(bytes);

}

fos.flush();

long duration = System.currentTimeMillis() - start;

System.out.println("Write 10000000 strings to a file cost : " + duration);

Read

fis = new FileInputStream(file);

byte[] bytes = new byte[50];

long start = System.currentTimeMillis();

while (fis.available() > 0) {

fis.read(bytes);

}

long duration = System.currentTimeMillis() - start;

System.out.println("Read all content string cost : " + duration);

输出结果如下:

Write 10000000 strings to a file cost : 131039

Read all content string cost : 49534

对上述代码再做修改,使用 BufferedInputStream 和 BufferedOutputStream 来包装 FileOutputStream 和 FileOutputStream 代码如下:

Write

fos = new FileOutputStream(file);

bos = new BufferedOutputStream(fos, 1024);

Read

fis = new FileInputStream(file);

bis = new BufferedInputStream(fis, 1024);

输出结果如下:

Write 10000000 strings to a file cost : 3552

Read all content string cost : 11093

从测试结果看,不论是读写,速度都大大提升。

内存IO

介质为内存的IO常有的流有:StringBufferInputStream,ByteArrayInputStream,PipedInputStream 等,前几种比较简单,本章主要介绍下 PipedOutputStream 和 PipedInputStream。PipedInputStream 和 PipedOutputStream需要成对出现,用于一个线程向另外一个线程写数据,下面是一个例子:

private static class WriteThread extends Thread {

PipedOutputStream mOut;

public WriteThread(PipedOutputStream pos) {

super();

mOut = pos;

}

public void run() {

try {

mOut.write("Hello World".getBytes());

} catch (IOException e) {

e.printStackTrace();

}

}

}

private static class ReadThread extends Thread {

PipedInputStream mIn;

ReadThread(PipedInputStream pis) {

super();

mIn = pis;

}

public void run() {

try {

byte[] bytes = new byte[1024];

int readCount = mIn.read(bytes);

System.out.println("ReadCount : " + readCount + " content "

+ new String(bytes, 0, readCount));

} catch (IOException e) {

e.printStackTrace();

}

}

}

public static void main(String[] args) {

try {

PipedInputStream pis = new PipedInputStream();

PipedOutputStream pos = new PipedOutputStream(pis);

WriteThread writeThread = new WriteThread(pos);

ReadThread readThread = new ReadThread(pis);

writeThread.start();

readThread.start();

} catch (IOException e) {

e.printStackTrace();

}

}

输出结果为:

ReadCount : 11 content Hello World

可以注意到,PipedOutputStream创建时构造函数传入了一个PipedInputStream,在实际使用的过程中,也可以先创建PipedOutputStream 在将其作为参数用于创建PipedInputStream。

网络IO

网络IO一般是通过 Socket 和 HTTP 相关的API进行,流在这个过程中通常是直接通过相关对象获得,以Socket为例:

public static void main(String[] args) {

Socket socket = new Socket();

SocketAddress addr = new InetSocketAddress("pop3.163.com", 110);

OutputStream out = null;

InputStream in = null;

try {

socket.connect(addr);

in = socket.getInputStream();

String reply = readLine(in);

System.out.println("reply is " + reply);

out = socket.getOutputStream();

writeLine(out, "CAPA");

reply = readLine(in);

System.out.println("reply2 is " + reply);

} catch (IOException e) {

e.printStackTrace();

} finally {

if (in != null) {

try {

in.close();

} catch (IOException e) {

e.printStackTrace();

}

}

if (out != null) {

try {

out.close();

} catch (IOException e) {

e.printStackTrace();

}

}

try {

socket.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

private static String readLine(InputStream in) throws IOException {

int d;

StringBuilder sb = new StringBuilder();

while ((d = in.read()) != -1) {

if (d == '\r') {

continue;

} else if (d == '\n') {

break;

} else {

sb.append((char) d);

}

}

return sb.toString();

}

private static void writeLine(OutputStream out, String content) throws IOException {

if (content != null && content.length() > 0) {

out.write(content.getBytes());

out.write('\r');

out.write('\n');

}

}

上面的代码链接了163的POP3服务器,并读取两行数据,写入一行数据,最终输出如下:

reply is +OK Welcome to coremail Mail Pop3 Server (163coms[b62aaa251425b4be4eaec4ab4744cf47s])

reply2 is +OK Capability list follows

java io 内存增长_Java IO 总结相关推荐

  1. java io内存泄露_java内存泄露和OutOfMemory

    1.内存泄露: Java的内存泄漏是指某些对象不再被应用程序使用,而垃圾收集器(Garbage Collector)却没能识别它们是"不再使用的",所以没有对这些对象进行回收,或者 ...

  2. java io字符流_Java IO流字符流简介及基本使用

    Java IO流字符流简介及常用字符流的基本使用 字符流分为输入字符流(Writer)和输出字符流(Reader),这两种字符流及其子类字符流都有自己专门的功能.在编码中我们常用的输出字符流有File ...

  3. JAVA mac系统io文件流_Java IO流基础1--IO的分类体系与文件流

    什么是IO流 Java中的IO 了解什么是IO流之前,要先知道什么是IO.IO,就是in和out(即输入和输出),指应用程序和外部设备之间的数据传递,常见的外部设备包括文件.管道.网络连接等. 流的概 ...

  4. java线程内存溢出_Java常见问题分析(内存溢出、内存泄露、线程阻塞等)

    Java垃圾回收机制(GC) 1.1 GC机制作用 1.2 堆内存3代分布(年轻代.老年代.持久代) 1.3 GC分类 1.4 GC过程 Java应用内存问题分析 2.1 Java内存划分 2.2 J ...

  5. java static内存泄漏_Java中的内存泄漏

    内存泄漏是指不再使用的对象持续占有内存空间而得不到及时释放,从而造成内存空间的浪费称为内存泄漏.比如,长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄漏,尽管短生命周期对象已经不再需要,但是 ...

  6. java查看内存地址_Java内存机制和内存地址

    问题一: String str1 = "abc"; String str2 = "abc"; System.out.println(str1==str2); / ...

  7. 微服务java模块内存管理_Java 9模块服务

    微服务java模块内存管理 接线与查找 Java长期以来都有一个ServiceLoader类. 它是在1.6中引入的,但是自Java 1.2以来就使用了类似的技术. 一些软件组件使用了它,但是使用并不 ...

  8. java final内存机制_Java中的内存处理机制和final、static、final static总结

    装载自:http://blog.csdn.net/wqthaha/article/details/20923579 Java程序运行在JVM上,可以把JVM理解成Java程序和操作系统之间的桥梁,JV ...

  9. java 解决内存泄露_Java内存泄露的理解与解决

    Java内存管理机制 在C++语言中,如果需要动态分配一块内存,程序员需要负责这块内存的整个生命周期.从申请分配.到使用.再到最后的释放.这样的过程非常灵活,但是却十分繁琐,程序员很容易由于疏忽而忘记 ...

  10. java jvm内存模型_Java(JVM)内存模型– Java中的内存管理

    java jvm内存模型 Understanding JVM Memory Model, Java Memory Management are very important if you want t ...

最新文章

  1. EXECL导入(检查服务器版本.包括NPOI方式导入.可以通过配置文件信息导入EXECL)代码记录下....
  2. TPC-W安装与配置(威斯康星大学Java版)
  3. 函数计算 【题目描述】
  4. 深度学习开发者的AI Party来了!WAVE SUMMIT+2021与你相约双十二
  5. nodejs(6)express学习
  6. html5app微信登陆,基于h5+的微信登陆,hbuilder打包
  7. .NET Core + Kubernetes:StatefulSet
  8. CSS--使用伪选择器制作箭头图标
  9. HTTP API 设计指南
  10. cisco2811(Cisco2811 DHCP)
  11. Mybatis-Plus
  12. js文本框设置必填项_表单字段必填项JS代码
  13. 收到微软律师函怎么办?当接到微软律师函的处理办法
  14. AWB调试中(Tuning)的几个问题
  15. Java学习——File类
  16. 破解TA朋友圈“仅三天可见”
  17. ggplot2设置坐标轴范围_使用 ggplot2 进行高级绘图—R读书笔记(二)
  18. c++ 双人五子棋(可直接复制)
  19. 搭建自己的 CDN 的乐趣和好处
  20. Web SQL 学习笔记

热门文章

  1. css图片背景之雪碧图的使用
  2. 易捷行云EasyStack与火星高科完成产品互认证,保护云上数据
  3. Data requirement
  4. java 中介模式_java设计模式-中介者模式
  5. 穷与焦虑。文/江湖一剑客
  6. McStudio的安装和使用
  7. Hyperledger Besu环境搭建(Linux)
  8. THINKPHP6 运行出现Malformed UTF-8 characters, possibly incorrectly encoded
  9. 苹果cms8个性化设置
  10. Jmeter:java.net.URISyntaxException: Illegal character in fragment at index XX问题解决方法