黑马程序员技术交流社区
标题: 【石家庄校区】IO技术交流! [打印本页]
作者: 念初。 时间: 2018-8-7 12:53
标题: 【石家庄校区】IO技术交流!
本帖最后由 小石姐姐 于 2018-8-9 11:06 编辑
IO流技术交流!
字节流
IO流,input/output stream
stream:数据(字符,字节)1个字节 = 8个二进制位
顶级父类:
java.io.OutputStream:此抽象类是表示输出字节流的所有类的超类
定义了一些子类共性的成员方法
[AppleScript] 纯文本查看 复制代码
- public void close() :关闭此输出流并释放与此流相关联的任何系统资源。
- public void flush() :刷新此输出流并强制任何缓冲的输出字节被写出。
- public void write(byte[] b):将 b.length字节从指定的字节数组写入此输出流。
- public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。
- public abstract void write(int b) :将指定的字节输出流。
java.io.FileOutputStream extends OutputStream
FileOutputStream:文件字节输出流
作用:把内存中的数据写入到硬盘的文件中
构造方法:
[AppleScript] 纯文本查看 复制代码
FileOutputStream(String name):创建一个向具有指定名称的文件中写入数据的文件输出流
参数为文件路径
FileOutputStream(File file):创建一个向指定File对象表示的文件中写入数据的文件输出流
参数为文件
作用:
1.创建一个FileOutputStream对象
2.会根据构造方法中传递的文件/文件夹路径,创建一个空的文件
3.会把FileOutputStream对象指向创建好的文件
写入数据的原理(内存 --> 硬盘)
java程序 --> JVM --> OS --> OS调用写数据的方法 --> 把数据写入到文件中
使用步骤:
1.创建一个FileOutputStream对象,构造方法中传递写入数据的目的地
2.调用FileOutputStream对象中的方法write,把数据写入到文件中
3.释放资源(流使用会占用一定的内存,使用完毕要把内存请空,提高程序的效率)
[Java] 纯文本查看 复制代码
public static void main(String[] args) throws IOException {
//1.创建一个FileOutputSteam对象,构造方法中传递写入数据的目的地
FileOutputStream fos = new FileOutputStream("practise-code\\src\\whatever\\a.txt");
//2.调用FileOutputStream对象中的方法write,把数据写入到文件中
//public abstract void write(int b)
fos.write(97);
//3.释放资源
fos.close();
写数据的时候,会把10进制的整数97,转换为二进制整数1100001
当使用记事本打开时,查询ASCII表可知,1100001为小写字母a
public void write(byte[] b):将b.length字节从指定的字节数组写入此输出流
一次写多个字节:
如果写的第一个字节是正数(0 - 127),那么显示的时候会查询ASCII表
public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。
追加写/续写:使用两个参数的构造方法
[AppleScript] 纯文本查看 复制代码
FileOutputStream(String name, boolean append) 创建一个向指定name的文件中写入数据的输出文件流
FileOutputStream(File file, boolean append) 创建一个向指定File对象表示的文件中写入数据的文件输出流
参数:
[AppleScript] 纯文本查看 复制代码
String name, File files:写入数据的目的地
boolean append:追加写开关
true:创建对象不会覆盖原文件,继续在文件的末尾追加写数据
false:创建一个新文件,覆盖源文件
写换行
windows:\r\n
linux:\n
macos:\r
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("practise-code\\src\\whatever\\c.txt", true);
for (int i = 0; i < 10; i++) {
fos.write("你好\n".getBytes());
}
fos.close();
}
java.io.InputStream:此抽象类是表示字节输入流的所有类的超类
public abstract int read():从输入流读取输入流的下一个字节
public void Close():关闭此输入流并释放资源
public int read(byte[] b):从输入流中读取一些字节数,并将它们存储到字节数组b中
java.io.FileInputStream extends InputStream
把硬盘文件中的数据读取到内存中使用
构造方法:
[Java] 纯文本查看 复制代码
FileInputStream(String name)
FileInputStream(File file)6
读取数据的原理(硬盘 --> 内存)
FileInputStream:
使用步骤:
创建FileInputStream对象,构造方法中绑定要读取的数据源
使用FileInputStream对象中的方法read,读取文件
释放资源
[Java] 纯文本查看 复制代码
public static void main(String[] args) throws IOException {
long start = System.currentTimeMillis();
FileInputStream fis = new FileInputStream("practise-code\\src\\whatever\\1.jpg");
FileOutputStream fos = new FileOutputStream("practise-code\\src\\whatever\\1copy.jpg");
byte[] bytes = new byte[1024*10];
int len;
while((len = fis.read(bytes)) != -1) {
fos.write(bytes, 0, len);
}
fos.close();
fis.close();
long end = System.currentTimeMillis();
System.out.println(end - start);
}
字符流
Java提供一些字符流类,以字符为单位读写数据,专门用于处理文本文件。
字符输入流【Reader】
java.io.Reader 抽象类是表示用于读取字符流的所有类的超类
基本共性功能方法。
public void close() :关闭此流并释放与此流相关联的任何系统资源。
public int read() : 从输入流读取一个字符。
public int read(char[] cbuf) : 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中 。
FileReader类
java.io.FileReader 类是读取字符文件的便利类,。构造时使用系统默认的字符编码和默认字节缓冲区。
java.io.FileReader extends InputStreamReader extends Reader (多继承关系)
字符编码:字节与字符的对应规则。
Windows系统的中文编码默认是GBK编码表。idea中UTF-8
构造方法
FileReader(File file) 一个文件 : 创建一个新的 FileReader ,给定要读取的File对象。
FileReader(String fileName) 文件路径: 创建一个新的 FileReader ,给定要读取的文件的名称。
使用字符数组读取: read(char[] cbuf) ,每次读取一个字节
代码使用演示:
[Java] 纯文本查看 复制代码
public class FRRead {
public static void main(String[] args) throws IOException {
1.// 使用文件名称创建流对象
FileReader fr = new FileReader("read.txt");
2.// 定义变量,保存有效字符个数
int len ;
char[] cbuf = new char[2];
3.//定义字符数组,作为装字符数据的容器 ,数组起缓冲作用,读取内容存储到数组,下一次读取内容覆盖上一次在数组中存储的内容!数组长度建议是1024的整数倍
4.//循环读取
while ((len = fr.read(cbuf))!=‐1) {
System.out.println(new String(cbuf , 0 , len));
}
5.// 关闭资源
fr.close();
6. // 关闭资源
fr.close();
}
}
}
}
字符输出流【Writer】
方法:
[AppleScript] 纯文本查看 复制代码
void write(int c) 写入单个字符。
void write(char[] cbuf) 写入字符数组。
Abstract void write(char[] cbuf, int off, int len) 写入字符数组的某一部分,o 数组的开始索引,len写的字符个数。
void write(String str, int off, int len) 写入字符串的某一部分,o 字符串的开始索引,len写的字符个数。
void flush() 刷新该流的缓冲。
void close() 关闭此流,但要先刷新它。
FileWriter类
java.io.FileWriter 类是写出字符到文件的便利类。
构造方法
[Java] 纯文本查看 复制代码
FileWriter(File file) : 创建一个新的 FileWriter,给定要读取的File对象。
FileWriter(String fileName) : 创建一个新的 FileWriter,给定要读取的文件的名称。
虽然参数为int类型四个字节,但是只会保留一个字符的信息写出。
flush close 两个的区别
flush :刷新缓冲区,流对象可以继续使用。
close : 先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了。
写出其他数据
写出字符数组 : write(char[] cbuf) 和 write(char[] cbuf, int off, int len) ,每次可以写出字符数组中的数据,用法类似FileOutputStream,代码使用演示:
[Java] 纯文本查看 复制代码
public class FWWrite {
public static void main(String[] args) throws IOException {
// 使用文件名称创建流对象
FileWriter fw = new FileWriter("fw.txt"); // 字符串转换为字节数
char[] chas = "黑马程序员".toCharArray();// 写出字符数组
fw.write(chars); // 黑马程序员
Fw.write(b,2,2); // 写出从索引2开始,2个字节。索引2是'程',两个字节,也就是'程序'。
// 关闭资源
fos.close();
}
}
写出字符串: write(String str) 和 write(String str, int off, int len) ,每次可以写出字符串中的数据,更为方便,代码使用演示:
[Java] 纯文本查看 复制代码
public class FWWrite {
public static void main(String[] args) throws IOException {
1.// 使用文件名称创建流对象
FileWriter fw = new FileWriter("fw.txt"); // 字符串
String msg = "黑马程序员";
2.// 写出字符数组
fw.write(msg);
3.//黑马程序员
4.// 写出从索引2开始,2个字节。索引2是'程',两个字节,也就是'程序'。
fw.write(msg,2,2); // 程序
5. // 写出换行
fw.write("\r\n");
6.// 关闭资源
fos.close();
}
}
缓冲流,转换流
缓冲流
字节缓冲流
[AppleScript] 纯文本查看 复制代码
|_ BufferedInputStream # 缓冲字节输入流
|_ BufferedOutputStream # 缓冲字节输出流
java.io.BufferedOutputStream类: 缓冲字节输出流
// 构造方法
[Java] 纯文本查看 复制代码
BufferedOutputStream(OutputStream out): 使用基本流创建一个缓冲字节输出流
BufferedOutputStream(OutputStream out, int size): 使用基本流创建一个缓冲字节输出流, 设置缓冲区大小
BufferedOutputStream使用步骤:
1.创建FileOutputStream对象, 构造方法中绑定要输出的目的地
2.创建BufferedOutputStream对象, 构造方法中传递FileOutputStream对象, 提高FileOutputStream效率
3.使用BufferedOutputStream对象中的方法 write(), 把数据写入到内部缓冲区中
4.使用BufferedOutputStream对象中的方法 flush(), 把内部缓冲区中的数据,刷新到文件中
5.释放资源(会先调用flush方法刷新数据, 第4步可以省略)
java.io.BufferedInputStream类: 缓冲字节输入流
// 构造方法
[Java] 纯文本查看 复制代码
BufferedInputStream(InputStream in): 使用基本流创建一个缓冲字节输入流
BufferedInputStream(InputStream in, int size): 使用基本流创建一个缓冲字节输入流, 设置缓冲区大小
使用步骤:
1.创建FileInputStream对象, 构造方法中绑定要读取的数据源
2.创建BufferedInputStream对象, 构造方法中传递FileInputStream对象, 提高FileInputStream效率
3.使用BufferedInputStream对象中的方法 read(), 读取文件
字符缓冲流
[AppleScript] 纯文本查看 复制代码
|_ BufferedReader # 缓冲字符输入流
|_ BufferedWriter # 缓冲字符输出流
java.io.BufferedWriter类:缓冲字符输出流
// 构造方法
[Java] 纯文本查看 复制代码
BufferedWriter(Writer out): 使用基本流创建一个缓冲字符输出流
BufferedWriter(Writer out, int size): 使用基本流创建一个缓冲字符输出流,设置缓冲区大小
// 特有方法
[Java] 纯文本查看 复制代码
void newLine(): 写入一个换行符, 换行符自动根据当前系统确定
java.io.BufferedReader类: 缓冲字符输入流
// 构造方法
[Java] 纯文本查看 复制代码
BufferedReader(Reader in): 使用基本流创建一个缓冲字符输入流
BufferedReader(Reader in, int size): 使用基本流创建一个缓冲字符输入流, 设置缓冲区大小
// 特有方法
String readLine(): 一次读一行字符串, "不包含换行符". 读到文件末尾返回null
转换流
字符编码和字符集
编码表: 字符和二进制数字的对应规则
字符集和编码表: 字符集包含编码表
ASCII字符集
ASCII编码表
ISO-8859-1字符集:
ANSI: 表示使用系统默认编码表
乱码原理: 字符流和转换流的关系
java.io.Reader
|_ InputStreamReader: 转换字符输入流 读 char char[] byte -> char 97 -> 'a'
|_ FileReader byte -UTF-8-> char
java.io.Writer char char[] String
|_ OutputStreamWriter: 转换字符输出流 char char[] String -> byte
|_ FileWriter char -UTF-8-> byte
FileReader=InputStreamReader+FileInputStream, 只不过固定按照IDEA中的UTF-8来将读取的字节转换为字符
FileWriter=OutputStreamWriter+FileOutputStream, 只不过固定按照IDEA中的UTF-8来将写出的字符转换为字节
字符流 = 字节流 + 编码表
转换流InputStreamReader, OutputStreamWriter在读写时, 可以指定按照哪个编码表来进行转
java.io.OutputStreamWriter类: 输出转换流. 字符流通往字节流的桥梁
// 构造方法
[AppleScript] 纯文本查看 复制代码
OutputStreamWriter(OutputStream out): 使用默认编码表创建转换流
OutputStreamWriter(OutputStream out, String charsetName): 使用指定编码表创建转换流
write('a') -> "GBK" -> 97 OutputStream out -> 文件
// 使用默认UTF-8
[AppleScript] 纯文本查看 复制代码
OutputStreamWriter o = new OutputStreamWriter(new FileOutputStream("a.txt"));
// 使用指定的GBK
OutputStreamWriter o = new OutputStreamWriter(new FileOutputStream("a.txt"), "GBK");
o.write("你") -> GBK -> 7676 -> 文件
写数据: 字符流 -------> 字节流
[AppleScript] 纯文本查看 复制代码
java.io.InputStreamReader类: 输入转换流. 字节流通往字符流的桥梁
// 构造方法
[Java] 纯文本查看 复制代码
InputStreamReader(InputStream in): 使用默认编码表创建转换流
InputStreamReader(InputStream in, String charsetName): 使用指定编码表创建转换流
// 使用默认UTF-8
[Java] 纯文本查看 复制代码
InputStreamReader r = new InputStreamReader(new FileInputStream("a.txt"));
// 使用指定的GBK
[AppleScript] 纯文本查看 复制代码
InputStreamReader r = new InputStreamReader(new FileInputStream("a.txt"), "GBK");
bbb int ch = r.read() <------GBK----------- 字节byte 989898
r.read(chs)
序列化流(对象流)
1.ObjectOutputStream类: 对象字节输出流
构造方法:
ObjectOutputStream(OutputStream out)
参数:
OutputStream out:字节输出流
特有成员方法:
void writeObject(Object obj): 将对象写出
使用步骤:
1.创建ObjectOutputStream流对象,构造方法中传递字节输出流
2.使用ObjectOutputStream对象中的方法writeObject,把对象写入到文件中
3.释放资源
使用步骤:
1.创建ObjectInputStream对象,构造方法中传递细节输入流
2.使用ObjectInputStream对象的readObject方法读取保存对象的文件
3.释放资源
4.使用读取出来的对象
readObject()声明抛出了ClassNotFoundException(class文件找不到异常)
当不存在对象的class文件时抛出此异常
反序列化的前提:
1.类必须实现Serializable
2.必须存在类对应的class文件
3.对象序列化的前提:
1.该类要实现java.io.Serializable接口以启用启序列化功能。未实现此接口的类将无法使其进行任何序列化或反序列化。
2.该类的所有属性必须是可序列化的(实现了java.io.Serializable接口)。如果有一个属性不需要可序列化的,则该属性必须注明是瞬态的,使用transient 关键字修饰。
Serializable接口:
也叫做标记型接口
序列化和反序列化的时候,如果不实现此接口,则会抛出NotSerializableException没有序
打印流
1.PrintStream类: 字节打印流
构造方法:
[Java] 纯文本查看 复制代码
PrintStream(File file): 创建字节打印流, 输出到一个文件
PrintStream(Output tream out): 创建字节打印流, 输出到一个字节输出流
PrintStream(String fileName): 创建字节打印流, 输出到一个文件路径
PrintStream特点:
1. 只有输出流, 没有输入流
2. PrintStream永远不会抛出IOException
3. 有特殊方法 print(), println(), 可以输出任意类型的值
2.java.lang.System类:
静态方法:
[AppleScript] 纯文本查看 复制代码
static void setOut(PrintStream out): 设置System.out的输出目的地为参数的打印流
-
121.jpg
(852.78 KB, 下载次数: 15)
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |