一.字节流
特点:任何类型的数据都可以使用字节流
1.字节输入流FileInputStream
构造方法:
可以直接传入一个文件,也可以传入具体的文件路径
1.FileInputStream(File file) 表示从file指向的文件中读取
2.FileInputStream(String name) 表示文件的路径名(路径+文件名)
读取方法:
1.int read():调用一次读到一个数据字节,返回的int值就是读到的数据(返回的是ASCII码值),如果已到达文件末尾,则返回 -1。
2.int read(byte[]b):调用一次本方法表示可以读取多个数据,读到的内容保存传入的byte数组b中,返回的是本次调用方法读到的数据字节数
3.int read(byte[] b, int off, int len) :和上面的第二个类似,可以指定从b数组什么位置开始装
为了读取的结果出现乱码,我们一般使用第三种,设置的数组大小不能太小
try {
//缓存数组,不能太小防止读取的文件出现乱码问题
byte[] bytes = new byte[1024];
//循环读取
while ((len=fileInputStream.read(bytes))!=-1){
System.out.println(new String(bytes,0,len));
}
}catch (IOException e){
e.printStackTrace();
}finally {
fileInputStream.close();
}
乱码问题:
中文乱码的问题 ,一个中文是两个数据字节, read() 一次读到的是一个数据字节,期待后面的字符流,定义临时读取的数组的长度问题,适当大小即可,最好不要想一次读完。
2.字节输入流FileOutputStream
构造方法:
我们一般使用后面两种方式,前两种每次写文件都会把以前的覆盖地掉,我们想要的结果一般是追加文件类容。
FileOutputStream(File file) //覆盖
FileOutputStream(String name)//覆盖
FileOutputStream(File file, boolean append)
FileOutputStream(String name, boolean append)
写出方法:
void write(int b) 调用一次写入一个数据字节
void write(byte[] b) 调用一次,可以把一个byte数组中的数据写入
void write(byte[] b, int off, int len) 调用一次,把b数组中的一部分数据写入
综合案例:
这里我们直接和字节输入流结合,实现一个文件复制的功能。
public static void main(String[] args) throws FileNotFoundException {
FileInputStream input = new FileInputStream("G:\\测试文件\\新建文件夹\\新建文件夹\\13.txt");
FileOutputStream output = new FileOutputStream("G:\\测试文件\\新建文件夹\\新建文件夹\\12.txt",true);
int len;
//先读取再写入
try {
byte[] bytes = new byte[1024];
while ((len=input.read(bytes))!=-1){
output.write(bytes,0,len);
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
//先开的流后关
try {
output.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
try {
input.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
读写乱码:
编码:
String s ="sadasda";
Byte[] bytes = s.getBytes(charset);
byte[] getBytes() 使用平台的默认字符集将此 String编码成byte[] getBytes(Charset charset) 使用指定的字符编码来编码字符串
byte[] getBytes(String charsetName) 使用指定的字符编码来编码字符串
解码:
byte[] ---> String
String(byte[] bytes) 通过使用平台的默认字符集解码指定的 byte 数组
String(byte[] bytes, Charset charset) 使用指定的字符集来解码指定的byte数组
String(byte[] bytes, String charsetName) 使用指定的字符集来解码指定的byte数组
常见的字符编码
二.字符流
使用提供字符流的好处就是不用担心中文乱码问题,但是其他类型的文件使用字节流(图片、视频、音频)
字符流的构造方法和字节流一样,这里不过多叙述了。
1.字符输入流FileReader
int read() throws IOException:读取单个字符并返回其 ASCII 值。如果已到达文件末尾,则返回 -1。
int read(char[] cbuf) throws IOException:将字符读入数组,并返回读取的字符数。如果已到达文件末尾,则返回 -1。
void close() throws IOException:关闭文件流。
Reader r = new FileReader("D:/123.txt");
char[] cbuf = new char[3];
int len;
while((len = r.read(cbuf))!=-1){
System.out.println(new String(cbuf,0,len));
}
r.close();
2.字符输出流FileWrite
综合案例:文件复制
void write(String str) 写入字符串。
void write(String str, int off, int len) 写入字符串的一部分
public static void main(String[] args) throws IOException {
FileReader reader = new FileReader("G:\\测试文件\\新建文件夹\\新建文件夹\\13.txt");
FileWriter writer = new FileWriter("G:\\测试文件\\新建文件夹\\新建文件夹\\12.txt",true);
char[] chars = new char[1024];
int len;
while ((len =reader.read(chars))!=-1){
writer.write(chars,0,len);
}
try {
writer.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
try {
reader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
三.字符流和字节流的区别
1.操作单位不同,一个是字节,一个是字符
2.字符流适合用于文本操作,字节流使用范围更加广泛:图片、视频、文本
3.字符流有字节写字符串的方法,字节流需要先转成byte[]
4.字节流不关闭流也能给文件写入数据,但是字符流不行,必须关闭和刷新缓存