IO(上)
1 输入流和输出流
输入流,数据从源数据源流入程序的过程称为输入流。可以理解为从源数据源读取数据到程序的过程。

输出流,数据从程序流出到目的地的过程称为输出流。可以理解为把数据从程序写入目的地的过程。

数据源一般指提供数据的原始媒介,一般常见有文件、数据库、云端、其他硬件等能提供数据的媒介。
2 流的分类

3 InputStream/OutputStream
InputStream 是所有字节输入流的抽象父类,提供了以下方法:
- read() 读取一个字节
- read(byte[] buf) 读取一定量的字节到缓冲区数组 buf中。
FileInputStream 文件字节输入流,是 InputStream 的一个子类,专门用于从文件中读取字节到程序内存中。
//需求:从文件读取一个字节
public static void main(String[] args) {
File file = new File("d:\\javatest\\a.txt"); // 【1】创建管道
FileInputStream in = null; try {
in = new FileInputStream(file); // 【2】从管道读取一个字节
/*
int t;
t = in.read();
t = in.read();
t = in.read();
t = in.read();
*/
// System.out.println(t); // 循环读取一个字节
int t;
StringBuilder sb = new StringBuilder();
while( (t=in.read()) != -1 ) {
sb.append((char)t);
}
System.out.println(sb.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch(IOException e) {
e.printStackTrace();
} // 【3】关闭流管道
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//一次读取多个字节
public static void main(String[] args) {
File file = new File("d:\\javatest\\a.txt"); // 【1】创建管道
FileInputStream in = null; try {
in = new FileInputStream(file); // 【2】从管道读取多个字节到缓冲区
/*
byte[] buf = new byte[5];
int len;
len = in.read(buf);
len = in.read(buf);
len = in.read(buf);
len = in.read(buf); for(byte b:buf) {
System.out.print((char)b+"\t");
}
System.out.println(len);
*/ // 通过循环读取文件
byte[] buf = new byte[5];
int len;
StringBuilder sb = new StringBuilder();
while( (len=in.read(buf)) != -1 ) {
// 读取的内容是原始二进制流,需要根据编码的字符集解码成对于字符
String str = new String(buf,0,len);
sb.append(str);
}
System.out.println(sb.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch(IOException e) {
e.printStackTrace();
} // 【3】关闭流管道
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
OutputStream 是所有字节输出流的抽象父类,提供了以下方法
- write() 写入一个字节
- write(byte[] buf) 写入一定量的字节到输出流
FileOutputStream 文件字节输出流,专门用于从内存中写入字节到文件中。
public static void main(String[] args) {
File file = new File("d:\\javatest\\c.txt");
FileOutputStream out = null;
try {
// 【1】创建输出流管道
out = new FileOutputStream(file);
// 【2】写入数据到管道中
// 一次写入一个字节
/*
out.write(97);
out.write(98);
out.write(99);
*/
// 一次写入多个字节
String str = "hello world";
// gbk
/*
byte[] buf = str.getBytes();
out.write(buf);
*/
byte[] buf = str.getBytes("UTF-8");
out.write(buf);
System.out.println("写入完成!");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// 【3】关闭流
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
注意:
- 字符串写入文件时一定会存在编码问题。
- 通过字节流写入文件时,向管道写入一个字节,该字节立即写入文件中。
InputStream/OutputStream 用于字节的读写。主要用于读写二进制文件(图片、音频、视频),较少用于读写文本型文件。对于文本型文件可以使用 Reader/Writer 类。
4 Reader/Writer
Reader 是字符输入流的抽象父类,提供了
- read() 一次读取一个字符
- read(char[] cbuf) 一次读取多个字符到字符缓冲区cbuf,返回长度表示读取的字符个数。
FileReader 文件字符输入流,专门用于读取默认字符编码文本性文件。
//需求:一次读取一个字符/多个字符到cbuf
public static void main(String[] args) throws IOException { File file = new File("d:\\javatest\\d.txt"); FileReader reader = new FileReader(file); // 【1】一次读取一个字符
/*
int c;
c = reader.read();
c = reader.read();
c = reader.read();
c = reader.read();
c = reader.read();
System.out.println((char)c);
*/ // 【2】一次读取多个字符到cbuf中
/*
char[] cbuf = new char[2];
int len;
len = reader.read(cbuf);
len = reader.read(cbuf);
len = reader.read(cbuf);
len = reader.read(cbuf);
System.out.println(Arrays.toString(cbuf));
System.out.println(len);
*/ char[] cbuf = new char[2];
int len;
StringBuilder sb = new StringBuilder();
while( (len=reader.read(cbuf)) != -1 ) {
sb.append(cbuf,0,len);
} System.out.println(sb);
}
Writer 是字符输出流的抽象父类,提供了
- write()
- write(char[] cbuf)
- write(String str)
FileWriter 文件字符输出流,专门用于写入默认字符编码的文本性文件。为了提高效率,File-Writer内部存在一个字节缓冲区,用于对待写入的字符进行统一编码到字节缓冲区,一定要在关闭流之前,调用flush方法刷新缓冲区,才能完成写入。
//需求:写入字符到文件中
public static void main(String[] args) throws IOException {
File file = new File("d:\\javatest\\f.txt"); FileWriter writer = new FileWriter(file); // 【1】一次写入一个字符
/*writer.write('中');
writer.write('国');*/ // 【2】一次写入多个字符
/*char[] cbuf = {'h','e','l','l','o','中','国'};
writer.write(cbuf);*/ // 【3】一次写入一个字符串
String str = "hello你好";
writer.write(str); // 刷新字节缓冲区
writer.flush(); // 关闭流通道
writer.close(); System.out.println("写入完成");
}
5 转换流
InputStreamReader继承于Reader,是字节流通向字符流的桥梁,可以把字节流按照指定编码 解码 成字符流。
OutputStreamWriter 继承于 Writer,是字符流通向字节流的桥梁,可以把字符流按照指定的编码 编码 成字节流。
- 把一个字符串以utf8编码写入文件
public class Test {
public static void main(String[] args) throws IOException {
String str = "hello中国";
File file = new File("d:\\javatest\\g.txt");
// 【1】创建管道
FileOutputStream out = new FileOutputStream(file);
OutputStreamWriter writer = new OutputStreamWriter(out, "utf8");
// 【2】写入管道
writer.write(str);
// 【3】刷新缓冲区
writer.flush();
// 【4】关闭管道
out.close();
writer.close();
System.out.println("写入完成");
}
}
- 读取utf8文件
public class Test01 {
public static void main(String[] args) throws IOException {
File file = new File("d:\\javatest\\g.txt");
// 【1】建立管道
FileInputStream in = new FileInputStream(file);
InputStreamReader reader = new InputStreamReader(in, "UTF-8");
char[] cbuf = new char[2];
int len;
StringBuilder sb = new StringBuilder();
while( (len=reader.read(cbuf))!=-1 ) {
sb.append(cbuf, 0, len);
}
System.out.println(sb.toString());
}
}
Windows 平台默认的 utf8 编码的文本性文件带有 BOM 标识,java 转换流写入的 utf8 文件不带 BOM 标识。所以用 java 读取手动创建的 utf8 文件会出现一点乱码(?hello中国,"?"是 BOM 标识导致的)。
6 BufferedReader/BufferedWriter
BufferedReader 继承于Reader,提供了
- read()
- read(char[] cbuf)
- readLine() 用于读取一行文本,实现对文本的高效读取。
BufferedReader 初始化时需要一个 Reader,本质上 BufferedReader 在 Reader 的基础上增加 readLine() 的功能。
//需求:读取一首诗
public static void main(String[] args) throws IOException { // 按行读取gbk文本性文件 File file = new File("d:\\javatest\\i.txt"); // 【1】创建管道
FileReader reader = new FileReader(file);
BufferedReader br = new BufferedReader(reader); // 【2】读取一行
/*
String line = br.readLine();
line = br.readLine();
line = br.readLine();
line = br.readLine();
*/ String line;
while( (line=br.readLine()) != null) {
System.out.println(line);
}
}
BufferedWriter继承于Writer,提供了
- write()
- write(char[] cbuf)
- write(String str)
- newline() 写入一个行分隔符。
//需求:以gbk编码写入一首诗到文件
public static void main(String[] args) throws IOException { File file = new File("d:\\javatest\\j.txt"); // 【1】创建gbk管道
FileWriter writer = new FileWriter(file);
BufferedWriter bw = new BufferedWriter(writer); // 【2】写入一行
bw.write("窗前明月光,");
bw.newLine(); bw.write("疑似地上霜。"); // for win
// bw.write("\r\n"); // for unix/linux/mac
// bw.write("\n"); bw.write("举头望明月,");
bw.newLine(); // 【3】flush
bw.flush(); // 【4】关闭管道
bw.close();
writer.close();
}
//需求:以utf8编码高效写入文件
public static void main(String[] args) throws IOException { File file = new File("d:\\javatest\\j-utf8.txt"); // 【1】创建utf8管道
FileOutputStream out = new FileOutputStream(file);
OutputStreamWriter writer = new OutputStreamWriter(out, "UTF-8");
BufferedWriter bw = new BufferedWriter(writer); // 【2】写入一行
bw.write("窗前明月光,");
bw.newLine(); bw.write("疑似地上霜。"); // for win
bw.write("\r\n"); // for unix/linux/mac
// bw.write("\n"); bw.write("举头望明月,");
bw.newLine(); // 【3】flush
bw.flush(); // 【4】关闭管道
bw.close();
writer.close();
}
IO(上)的更多相关文章
- 终端IO(上)
一.综述 终端IO有两种不同的工作方式: 规范方式输入处理.在这种方式中,终端输入以行为单位进行处理.对于每个读要求,终端驱动程序最多返回一行. 非规范方式输入处理.输入字符不以行为单位进行装配 如果 ...
- commons io上传文件
习惯了是用框架后,上传功能MVC框架基本都提供了.如struts2,springmvc! 可是假设项目中没有使用框架.而是单纯的使用jsp或servlet作为action,这时我们就能够使用commo ...
- 解决 docker.io 上拉取 images Get https://registry-1.docker.io/v2/: net/http: TLS handshake timeout
处理方式 使用如下命令获取 registry-1.docker.io 可用的 ip dig @114.114.114.114 registry-1.docker.io 看到如下输出结果 ; <& ...
- spartan6不能直接把时钟连到IO上
1.问题的提出:spartan6中不允许时钟信号直接连到IO口上面? 2.解决办法: ODDR2的使用 ODDR2Primitive: Double Data Rate Output D Flip-F ...
- Redis持久化磁盘IO方式及其带来的问题 有Redis线上运维经验的人会发现Redis在物理内存使用比较多,但还没有超过实际物理内存总容量时就会发生不稳定甚至崩溃的问题,有人认为是基于快照方式持
转自:http://blog.csdn.net/kaosini/article/details/9176961 一.对Redis持久化的探讨与理解 redis是一个支持持久化的内存数据库,也就是 ...
- 弃用!Github 上用了 Git.io 缩址服务的都注意了
GitHub 是面向开源及私有软件项目的托管平台,因为只支持 Git 作为唯一的版本库格式进行托管,故名 GitHub.对程序员来说,GitHub 可以说是开源精神之所系.在 GitHub 任何职业程 ...
- 关于解决python线上问题的几种有效技术
工作后好久没上博客园了,虽然不是很忙,但也没学生时代闲了.今天上博客园,发现好多的文章都是年终总结,想想是不是自己也应该总结下,不过现在还没想好,等想好了再写吧.今天写写自己在工作后用到的技术干货,争 ...
- Linux网络编程-IO复用技术
IO复用是Linux中的IO模型之一,IO复用就是进程预先告诉内核需要监视的IO条件,使得内核一旦发现进程指定的一个或多个IO条件就绪,就通过进程进程处理,从而不会在单个IO上阻塞了.Linux中,提 ...
- 如何在ASP.NET 5上搭建基于TypeScript的Angular2项目
一.前言 就在上月,公司的一个同事建议当前的前端全面改用AngularJs进行开发,而我们采用的就是ASP.NET 5项目,原本我的计划是采用TypeScript直接进行Angular2开发.所以借用 ...
- 使用Jekyll在Github上搭建博客
最近在玩github,突然发现很多说明网站或者一些介绍页面全部在一个域名是*****.github.io上. 好奇!!!真的好奇!!!怎么弄的?我也要一个~~~ 于是去网站上查询了一下,找到了http ...
随机推荐
- C++全局变量的定义和声明
编译单元 编译分为两个步骤: 第一步:将每个.cpp或.c和相应的.h文件编译乘obj文件(包含预编译,汇编.编译) 第二部:将obj文件进行Link,生成最终的可执行文件 根据该阶段错误大致可分为两 ...
- P2699 【数学1】小浩的幂次运算
原题链接 https://www.luogu.org/problemnew/show/P2699 P2699 [数学1]小浩的幂次运算 首先第一眼看这个题就知道要暴力枚举w^i 看是否在区间[l,r] ...
- codeforces555E
Case of Computer Network CodeForces - 555E Andrewid the Android is a galaxy-known detective. Now he ...
- loj541
七曜圣贤 sol:我标算还没写过,似乎分块就可以过(因为数据是随机的),我写个set可以有70~80分 //C++ #include<bits/stdc++.h> using namesp ...
- Win10 + CLion + 树莓派 + QT 远程开发调用Python
原则:能在一个机器上开发的就不在两台机器上!! 首先需要配置远程QT开发环境 配置Cmake cmake_minimum_required(VERSION 3.14) project(qt_test) ...
- python 系统模块 OS
os.system("系统命令") 调用系统命令 os.system("task kill /f /im 系统的进程") 关闭系统进程 os.listdir( ...
- Failed to execute goal maven-gpg-plugin 1.5 Sign
问题描述: 解决办法:跳过maven-gpg-plugin <build> <pluginManagement> <plugins> <plugin> ...
- spring boot通过自定义注解和AOP拦截指定的请求
一 准备工作 1.1 添加依赖 通过spring boot创建好工程后,添加如下依赖,不然工程中无法使用切面的注解,就无法对制定的方法进行拦截 <dependency> <group ...
- 最大生成树+map实现技巧
POJ2263 //#include<bits/stdc++.h> #include<iostream> #include<cstdio> #include< ...
- LC 934. Shortest Bridge
In a given 2D binary array A, there are two islands. (An island is a 4-directionally connected grou ...