详解 字节输出流 与 字节输入流
(请观看本人博文——《详解 字节流》)
FileOutputStream类:
(字节型输出流)
概念:
从内存向文件 输出的流
首先,本人来展示下它的 构造方法:
- FileOutputStream(File file)
- FileOutputStream(String name)
(若是我们所传的参数所表示的文件不存在,则会自动创建一个相应的文件)
为了验证上面的讲解,本人来展示下:
首先,本人来给出一段代码:
package edu.youzg.about_io.about_file.core;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
public class Test {
public static void main(String[] args) throws FileNotFoundException {
File file = new File("test.txt");
FileOutputStream out = new FileOutputStream(file);
out.close();
}
}
现在,本人先来展示运行前的目录:
现在,本人再来展示下运行后的目录:
那么,本人在上面的讲解是正确的。
现在,本人来展示下 FileOutputStream类 的常用API:
- public void write(int b, boolean append):
写一个字节
(超过一个字节,则只录入最后一个字节)- public void write(byte[] b, boolean append):
写一个字节数组- public void write(byte[] b, int off, int len, boolean append):
写一个字节数组的一部分
在这里本人还要强调一点:
- 若是我们在参数中不写append参数,则默认append为false,则:
将原文件中的所有内容就会被删除,然后再将我们程序中设定的内容写进去- 若我们的append参数设置为true,则:
在原内容的最后一个字节处后增添新内容
那么,现在本人来展示下这三个方法的使用:
package edu.youzg.about_io.about_file.core;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
File file = new File("test.txt");
FileOutputStream out = new FileOutputStream(file);
out.write(99);
out.write(new byte[] {'b', 101, 102});
out.write(new byte[] {98, 104, 103}, 1, 1);
//流用完之后,必须释放资源
out.close(); //关闭流
}
}
那么,现在本人来展示下运行结果:
可以看到,文件中按照我们的需要录入了信息。
那么,本人再在这里啰嗦一句:
汉字在UTF-8中占3个字节;
汉字在GBK中占2个字节
现在,本人还要强调一点:
若是我们想要在输入的内容中做到换行,就要用到换行符:
换行符:
- windows ---------- \r\n
- Linux -------------- \n
- Mac ---------------- \r
那么,本人再来展示下上面两个知识点的使用:
package edu.youzg.about_io.about_file.core;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
FileOutputStream out = new FileOutputStream("test.txt");
out.write("芷若幽兰,寂静无言".getBytes());
out.write("\r\n".getBytes());//写入一个回车换行符
out.write("白芷杜若,相濡以沫".getBytes());
byte[] bytes = "白".getBytes();
System.out.println("一个汉字在UTF-8下长度为" + bytes.length + "个字节");
//流用完之后,必须释放资源
out.close(); //关闭流
}
}
现在,本人来展示下运行结果:
上图可以证明:汉字在UTF-8编码下占3个字节!
现在,本人来展示下运行后的test.txt的内容:
可以看到,我们通过代码所输入的内容换行了!
那么,现在,本人来讲解下 FileInputStream类:
FileInputStream类:
(字节输入流)
概念:
从文件 向内存 输入的流
首先,本人来展示下这个类的 构造方法:
- FileInputStream(File file)
通过打开一个到实际文件的连接来创建一个 FileInputStream,
该文件通过文件系统中的 File 对象 file 指定。- FileInputStream(FileDescriptor fdObj)
通过使用文件描述符 创建一个 FileInputStream,
该文件描述符表示到文件系统中某个实际文件的现有连接。- FileInputStream(String name)
通过打开一个到实际文件的连接来创建一个 FileInputStream,
该文件通过文件系统中的路径名 name 指定。
关于这个类的的构造方法,本人再强调一点:
若是文件不存在,就会报异常
现在,本人来展示下这个类的常用API:
- int read()
从此输入流中读取一个数据字节- int read(byte[] b)
从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中- int read(byte[] b, int off, int len)
从此输入流中将最多 len 个字节的数据读入一个 byte 数组中
(注意:每次读取后会使得流的指向变为下一个字节)
现在,本人来展示下read()方法的使用:
package edu.youzg.about_io.about_file.core;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream("test.txt");
int len = in.read();//一次读取一个字节
System.out.println(len);
byte[] bytes1 = new byte[1024];
byte[] bytes2 = new byte[1024];
//读取字节数组的一部分
//把读取到的字节的一部分,装入到缓冲区中
int len1 = in.read(bytes1, 0, 3); //从指定位置开始,读取指定长度
//返回值是 读取出来的字节数组的长度
System.out.println(len1);
int len2 = in.read(bytes2, 0, 3); //从指定位置开始,读取指定长度
//返回值是 读取出来的字节数组的长度
System.out.println(len2);
//我们将读取到的字节数组转化为字符串
String s = new String(bytes1, 0, 3);
System.out.println(s);
s = new String(bytes2, 0, 3);
System.out.println(s);
in.close();
}
}
那么,本人来展示下运行结果:
相信同学们已经对这两个类的使用了解了
那么,现在,本人现在来通过一个例子来巩固下同学们对于这两个知识点的理解:
本人现在来展示下如何用上述两个类来“复制Mp3文件”:
首先,本人先来展示一个很简单的方法——通过每次读取一个字节来完成复制:
package edu.youzg.about_io.about_file.core;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test {
public static void main(String[] args) {
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("test.mp3");
out = new FileOutputStream("copyView1.mp3");
int len=0;
long start = System.currentTimeMillis();
while ((len=in.read())!=-1){
out.write(len);
out.flush(); //清空缓存区内容,并将其输出
}
long end = System.currentTimeMillis();
System.out.println((end-start)+"毫秒"); //记录最终用时
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally { //流在使用完之后,一定要释放资源
try {
in.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
那么,本人再来展示下生成的文件和源文件:
现在,我们来看一下运行结果:
可以看到,用时很长,
那么,为了缩短用时,本人再来给出一套方案 —— 每次读取一个字节数组,来充当缓冲区,以便于我们完成复制:
package edu.youzg.about_io.about_file.core;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test {
public static void main(String[] args) {
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("test.mp3");
out = new FileOutputStream("copyView2.mp3");
//定义一个字节数组,充当缓冲区
byte[] bytes = new byte[1024 * 1024];
int len = 0;//记录每次读取到的有效字节个数
long start = System.currentTimeMillis();
while ((len = in.read(bytes)) != -1) {
out.write(bytes, 0, len);
out.flush(); //清空缓存区内容,并将其输出
}
long end = System.currentTimeMillis();
System.out.println((end - start) + "毫秒");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally { //流在使用完之后,一定要释放资源
try {
in.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
本人来展示下生成的文件和源文件:
那么,我们再来看一下用时:
可以看到,缩短和了用时!
(本人《详解 字节流》博文链接:https:////www.cnblogs.com/codderYouzg/p/12418463.html)
(本人 I/O流总集篇 博文链接:https:////www.cnblogs.com/codderYouzg/p/12418404.html)