一切文件数据(文本、图片、视频等)在存储时,都是以二进制的形式保存,传输时同样如此。所以字节流可以传输任意数据。 在操作流的时候,无论使用什么样的流对象,底层传输的始终为二进制数据。
根据数据的流向分为:输入流 和 输出流
根据数据的类型分为:字节流 和 字符流。
另外还有:缓冲流、转换流、序列流、打印流。
简述:java.io.OutputStream 抽象类是表示字节输出流的所有类的父类(超类),将指定的字节信息写到目的地。
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 类是文件输出流,用于将数据写出到文件。
public FileOutputStream(File file) // 创建文件输出流以写入由指定的 File对象表示的文件。
public FileOutputStream(String name) // 创建文件输出流以指定的名称写入文件
public static void main(String[] args) throws IOException {
FileOutputStream fos1 = new FileOutputStream("E:\\test\\abc.txt");
FileOutputStream fos2 = new FileOutputStream(new File("E:\\test\\abc.txt"));
// 写入单个字节
fos1.write(97);
// 写入字节数组
byte[] bytesArray = "你好".getBytes();
System.out.println(Arrays.toString(bytesArray)); // [-28, -67, -96, -27, -91, -67]
fos2.write(bytesArray);
// 释放资源
fos1.close();
fos2.close();
}
简述:java.io.InputStream 抽象类是表示字节输入流的所有类的父类(超类),可以读取字节信息到内存中。
public void close() // 关闭此输入流并释放与此流相关联的任何系统资源。
public abstract int read() // 从输入流读取数据的下一个字节。
public int read(byte[] b) // 从输入流中读取一些字节数,并将它们存储到字节数组 b中
简述:java.io.FileInputStream类是文件输入流,从文件中读取字节。
# 文件的复制
FileInputStream fis = new FileInputStream("E:\\test\\a\\1.jpg");
FileOutputStream fos = new FileOutputStream("E:\\test\\b\\1.jpg");
int len = 0;
byte[] bytes = new byte[1024];
while ((len = fis.read(bytes)) != -1) {
fos.write(bytes, 0, len);
}
// 释放资源
fos.close();
fis.close();
简述:当使用字节流读取文本文件时,可能会有一个小问题。就是遇到中文字符时,可能不会显示完整的字符,因为一个中文字符占用多个字节存储(GBK占用两个字节,UTF-8占用三个字节)。所以JAVA提供了字符流类,以字符为单位读写数据,专门用于处理文本文件。
简述:java.io.Reader抽象类是字符流最顶层的父类(超类),可以读取字符信息到内存中。
public void close() // 关闭此流并释放与此流相关联的任何系统资源。
public int read() //从输入流读取一个字符。
public int read(char[] cbuf) // 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中 。
FileReader fr1 = new FileReader("E:\\test\\a.txt");
FileReader fr2 = new FileReader("E:\\test\\b.txt");
// 读取一个字符
int len = 0;
while ((len = fr1.read()) != -1) {
System.out.println(len);
}
// 读取多个字符
int len =0;
char[] cs = new char[1024];
while ((len = fr1.read(cs)) != -1) {
System.out.println("长度" + len);
System.out.println(new String(cs, 0, len));
}
// 释放资源
fr1.close();
fr2.close();
简述:java.io.Writer 字符输出流,是所有字符输出流的父类,是一个抽象类。
FileWriter fw1 = new FileWriter("E:\\test\\c.txt");
FileWriter fw2 = new FileWriter("E:\\test\\c.txt", false);
// 写入数据
fw1.write(97);
char[] cs = {
'a', 'b', 'c', 'd', 'e' };
fw1.write(cs);
fw1.write(cs, 1, 3);
// 换行: windows:\r\n Linux:/n Unix: /r
for (int i = 0; i < 10; i++) {
fw1.write("HelloWorld" + i + "\r\n"); // 换行写入
}
// 将缓冲区的数据刷新到硬盘
fw1.flush();
// 释放资源
fw1.close();
简述: 功能更强大的流,能够高效读写的缓冲流,能够转换编码的转换流,能够持久化存储对象的序列化流等等。这些都是在基本的流对象基础之上创建而来的,是对基本流对象的一种增强
public void close()
public void flush()
public void write(byte[] b)
public void write(byte[] b, int off, int len)
public abstract void write(int b)
FileOutputStream fos = new FileOutputStream("E:\\test\\c.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
bos.write("把数据写到缓冲区中".getBytes());
bos.flush();
bos.close();
FileInputStream fis = new FileInputStream("E:\\test\\c.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
byte[] cs = new byte[1024];
int len = 0;
while ((len = bis.read(cs)) != -1) {
System.out.println(new String(cs, 0, len));
}
bis.close();
void newLine() 写入一个行分隔符。会根据不同的操作系统,获取不同的行分隔符
BufferedWriter bw = new BufferedWriter(new FileWriter("E:\\test\\b.txt"));
for (int i = 0; i < 10; i++) {
bw.write("啦啦啦");
bw.newLine();
}
bw.flush();
bw.close();
String readline() 读取一行数据
返回值:包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回null
BufferedReader br = new BufferedReader(new FileReader("E:\\test\\b.txt"));
String line; // 创建读取的文本行,结尾返回null
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
public static void main(String[] args) throws IOException {
long currentTimeMillis = System.currentTimeMillis();
// FileOutputStream
FileInputStream fis1 = new FileInputStream("E:\\test\\a\\a.jpg");
FileOutputStream fos1 = new FileOutputStream("E:\\test\\b\\a.jpg");
byte[] bytes = new byte[1024];
int len = 0; // 读取到的有效字节个数
while ((len = fis1.read(bytes)) != -1) {
fos1.write(bytes, 0, len);
}
fos1.close();
fis1.close();
long doneTimeMillis = System.currentTimeMillis();
System.out.println("File 复制文件使用了:" + (doneTimeMillis - currentTimeMillis) + "毫秒");
// BufferedOutputStream
long currentTimeMillis2 = System.currentTimeMillis();
BufferedInputStream bis1 = new BufferedInputStream(new FileInputStream("E:\\test\\a\\b.jpg"));
BufferedOutputStream bos1 = new BufferedOutputStream(new FileOutputStream("E:\\test\\b\\b.jpg"));
byte[] bytes2 = new byte[1024];
int len1 = 0;
while ((len1 = bis1.read(bytes2)) != -1) {
bos1.write(bytes2, 0, len1);
}
bos1.close();
bis1.close();
long doneTimeMillis2 = System.currentTimeMillis();
System.out.println("Buffered 复制文件使用了:" + (doneTimeMillis2 - currentTimeMillis2) + "毫秒");
}
# 输出
File 复制文件使用了:38毫秒
Buffered 复制文件使用了:8毫秒
简述:在文件的读取和写入中如果编码不一致有可能导致乱码的问题。转换流中可以指定编码。
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("E:\\test\\utf-8.txt"), "UTF-8");
osw.write("你好");
osw.flush();
osw.close();
是字节流通向字符流的桥梁,它使用指定的charset读取字节将其解码为字符
InputStreamReader isr = new InputStreamReader(new FileInputStream("E:\\test\\utf-8.txt"), "UTF-8");
String line;
int len=0;
while ((len = isr.read()) != -1) {
System.out.print((char) len);
}
isr.close();
PS:编码换成“GBK”则会乱码
把对象以流的方式写入到文件中
# Person类
public class Person implements Serializable {
private String name;
private int age;
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
# main
public static void main(String[] args) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:\\test\\obj.txt"));
oos.writeObject(new Person("赵丽颖", 18));
oos.close();
}
注意:Person类需要implements Serializable 类才能序列和反序列化
简述:把文件中保存的对象以流的方式读取出来
// 读取上个练习存入的对象(重写了toString方法)
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:\\test\\obj.txt"));
Object readObject = ois.readObject();
ois.close();
System.out.println(readObject);
// 将读取出来的对象强转成Person类型,然后进行使用
Person p = (Person) readObject;
System.out.println(p.getName() + ", " + p.getAge());
# 输出
Person [name=赵丽颖, age=18]
赵丽颖, 18
简述:平时我们调用 print 和 println 方法完成的,这两个方法都来自于 java.io.PrintStream 该类能够方便地打印各种数据类型的值,是一种便捷的输出方式。
PrintStream(File file) // 输出的目的地是一个文件
PrintStream(OutputStream out) // 输出的目的地是一个字节输出流
PrintStream(String fileName) // 输出的目的地是一个文件路径
public static void main(String[] args) throws FileNotFoundException {
PrintStream ps = new PrintStream("E:\\test\\p.txt");
ps.write(97);// 使用继承的write方法写入,结果:a
ps.println(97); // 97
ps.println("HelloWorld");
ps.println(8.8);
ps.println(true);
// 释放资源
ps.close();
}
PrintStream p2 = new PrintStream("E:\\test\\p.txt");
System.out.println("在控制台输出");
System.setOut(p2); // 把输出语句的目的地改变为打印流的目的地
System.out.println("在打印流的目的地输出");
// 释放资源
p2.close();