一切文件(文本、图片、视频)在存储时,都是以二进制的形式存储,都可以通过使用字节流传输,字节流在顶层抽象类为InputStream和OutputStream
InputStream:字节输入流
public abstract class InputStream implements Closeable
InputStream是字节流的顶层抽象类
流操作步骤:
//第一步:打开流
FileInputStream fis = new FileInputStream(path);
//第二步:通过read读数据
byte[] bytes = new byte[5];
// int read = fis.read(bytes,0,5);
// int read1 = fis.read(bytes,2,2);
// int read1 = fis.read(bytes,2,5);//IndexOutOfBoundsException
int len;
while((len = fis.read(bytes,0,5)) != -1){
System.out.println(new String(bytes,0,len));
}
//第三步:对流关闭
fis.close();
该类提供了核心方法:
public abstract int read() throws IOException;
//每次读取一个字节的数据,为int类型,读取到文件末尾是返回-1
public int read(byte b[]) throws IOException //每次读取的数据到字节数组中,返回读取到有效字节的个数,读取到文件末尾是返回-1
public int read(byte b[], int off, int len) throws IOException //每次读取数据到字节数组中,从偏移量off开始,长度为len,返回结果是读取到有效字节的个数,读取到文件末尾是返回-1
以实现类为例,介绍FileInputStream,读取文件的字节输入流
FileInputStream构造函数主要有:
public FileInputStream(String name) throws FileNotFoundException
public FileInputStream(File file) throws FileNotFoundException
当传入的文件不存在时,运行会抛出FileNotFoundException异常
read()方法读取:
/**
* int read() 每次读取一个字节
* 返回结果表示读取的数据类型是int类型值
* 数据读取到结尾返回-1
*
*/
int read = fis.read();
int c;
//如果内容读取,多内容循环读
while((c = fis.read()) != -1){
System.out.print((char) c);
}
read(byte[])
/**
* int read(byte b[]) throw IOException
* 将数据读取到byte数组
* 返回结果表示读取的数据个数
*
* 数据读取到结尾返回-1
*
*/
byte[] bytes = new byte[2];
int len;
while((len = fis.read(bytes))!= -1){
String s = new Stri/**
* int read(byte b[], int off, int len) throws IOException
* 将数据读取到byte数组,从byte数组的off位置偏移,最多偏移len位置
* off + len <= b.length
* 返回结果表示读取的数据个数
*
* 数据读取到结尾返回-1
*
*/
byte[] bytes = new byte[5];
// int read = fis.read(bytes,0,5);
// int read1 = fis.read(bytes,2,2);
// int read1 = fis.read(bytes,2,5);//IndexOutOfBoundsException
int len;
while((len = fis.read(bytes,0,5)) != -1){
System.out.println(new String(bytes,0,len));
}rintln(s);
}
使用数组读取,每次可以读取多个字节,减少了系统间IO的操作次数,从而提高了效率,建议使用
read(byte[],int off,int len)
/**
* int read(byte b[], int off, int len) throws IOException
* 将数据读取到byte数组,从byte数组的off位置偏移,最多偏移len位置
* off + len <= b.length
* 返回结果表示读取的数据个数
*
* 数据读取到结尾返回-1
*
*/
byte[] bytes = new byte[5];
// int read = fis.read(bytes,0,5);
// int read1 = fis.read(bytes,2,2);
// int read1 = fis.read(bytes,2,5);//IndexOutOfBoundsException
int len;
while((len = fis.read(bytes,0,5)) != -1){
System.out.println(new String(bytes,0,len));
}
OutputStream:字节输出流
OutputStream是字节输出流的顶层抽象类
//Flushable接口提供了flush()方法
public abstract class OutputStream implements Closeable, Flushable
以FileOutputStream为例介绍OutputStream核心方法:
public abstract void write(int b) throws IOException;//将int值写入到输出流中
public void write(byte b[]) throws IOException
//将字节数组写入到输出流中
public void write(byte b[], int off, int len) throws IOException //将字节数组从偏移量off开始,写入len个长度到输出流中
public void flush() throws IOException//刷新输出流并强制缓冲字节被写出
write(int b)
/**
* void writr(int b) throws IOException
* 每次写入一个int类型的字符
*/
fos.write(97);
write(byte[] )
byte[] bytes = {'h','e','l','l','o'};
fos.write(bytes);
fos.write("hello".getBytes());
write(byte[],int off,int len)
byte[] bytes = {'h','e','l','l','o'};
fos.write(bytes,1,4);
主要实现类:文件字节流
文件输入流:FileInputStream
public FileInputStream(String name) throws FileNotFoundException
public FileInputStream(File file) throws FileNotFoundException
文件输出流:FileOutputStream
字符流
字符流封装了更加适合操作文本字符的方法
Reader:字符输入流
Reader是Java中IO库提供的另一个输入流接口,和InputStream的区别:InputStream是一个字节流,以byte为单位读取,而Reader是一个字符流,以char为单位读取
Reader主要用来读取文本字符
以实现类FileReader为例介绍
核心方法:
//第一步:打开流
fileReader = new FileReader(path);
//第二步:流的读操作
/**
* int read() throws IOException
* 每次读取一个字符,返回类型是int,范围是0~65535
* 如果读取到文件结尾:返回-1
*/
// int read = fileReader.read();
// System.out.println((char)read);
/**
* int read(char cbuf[]) throws IOException
* 将输入流读取到char数组中
* 返回结果表示读取的数据个数
* 如果读取到文件末尾,返回-1
*/
// char[] chars = new char[3];
// int read = fileReader.read(chars);
// System.out.println(new String(chars,0,read));
/**
* int read(char cbuf[], int offset, int length) throws IOException
* 批量读取数据
* 将数据读取到char数组中,从offset位置开始,读取length长度
* 范围:offest + length <= char.length
* 返回值表示数据的个数,返回-1
*/
// char[] chars = new char[3];
// int read = fileReader.read(chars,0,3);
//
// System.out.println(new String(chars,0,read));
/**
* int read(java.nio.CharBuffer target) throws IOException
* 将数据读取到CharBuffer中
*/
CharBuffer buffer = CharBuffer.allocate(100);
// CharBuffer wrap = CharBuffer.wrap(new char[100]);
//从fileReader将内容读取到buffer中
int read = fileReader.read(buffer);
//读写模式切换
buffer.flip();
char[] chars1 = new char[read];
//将buffer中数据读取到char类型数组中
buffer.get(chars1);
//读取内容
String info = new String(chars1);
System.out.println(info);
}catch(FileNotFoundException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
} finally {
//第三步:关闭流
if(fileReader != null){
try{
fileReader.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
public abstract class Reader implements Readable, Closeable
Writer:字符输出流
是字符输出流,和OutputStream类似,不同点在于OutputStream是操作byte字节流,而writer是操作char字符流
public abstract class Writer implements Appendable, Closeable, Flushable
//实现Appendable接口时,该类具有内容追加功能
//实现Flushable接口,说明该类具有Flush功能,强制将缓冲数据刷入磁盘或发送至网络
以实现类FileWriter为例:
//写内容
/**
* void write(int c)
* 每次写入单个字符
*/
fileWriter.write('c');
char[] chars = new char[]{'c','h','i','n','a'};
/**
* oid write(char cbuf[])
* 写入char数组
*/
fileWriter.write(chars);
/**
* void write(char cbuf[], int off, int len)
* 写入char数组,从off开始,读取len长度写入
*/
fileWriter.write(chars,0,chars.length);
/**
* void write(String str)
* 写入字符串到字符输出流
*/
fileWriter.write("hello");
/**
* void write(String str, int off, int len)
* 写入字符串数组
* 从off位置开始,写入len长度
*
*/
String s = "hello xiaoxu";
fileWriter.write(s,0,s.length());
//追加内容
/**
* Writer append(char c)
* 追加内容到输出流中
*/
fileWriter
.append('a')
.append('b')
.append('c');
/**
* Writer append(CharSequence csq)
*/
//创建一个buffer
CharBuffer buffer = CharBuffer.allocate(100);
//往buffer中写入内容
buffer.put("hello");
//读写模式切换
buffer.flip();
//将数据从charSequence 中写入字节输出流
fileWriter.append(buffer).append('d');