字节流
字节流是指传输过程中,传输数据的最基本单位是字节的流,一个不包含边界数据的连续流;字节流是由字节组成的,主要用在处理二进制数据。
OutputStream字节输出流
常用方法
这个抽象类是所有表示字节输出流的类的超类。具体方法如下:
- write(int b)
将指定的字节写入此输出流 - write(byte b[])
将指定字节数组中的b.length个字节写入此输出流 - write(byte b[], int off, int len)
将指定字节数组中的len个字节从偏移量off开始写入此输出流。 write(b, off, len)的一般约定是将数组b中的某些字节按顺序写入输出流; 元素b[off]是写入的第一个字节, b[off+len-1]是此操作写入的最后一个字节 - flush()
刷新此输出流并强制写出任何缓冲的输出字节 - close()
关闭此输出流并释放与此流关联的任何系统资源
FileOutputStream
FileOutputStream继承OutputStream,有两个常用构造方法
FileOutputStream(File file)
对文件file进行覆盖写入FileOutputStream(File file, boolean append)
append:true 代表追加写入写入举例
覆盖写入
public static void write() throws IOException { File f = new File("d:" + File.separator + "test.txt"); //如果文件不存在会自动创建 OutputStream out = new FileOutputStream(f); String str = "Hello World\nsddgdgdf"; //因为是字节流,所以要转化成字节数组进行输出 byte[] b = str.getBytes(); out.write(b); out.close(); }
追加写入
public static void continueWrite() throws IOException { File f = new File("d:" + File.separator + "test.txt"); //如果文件不存在会自动创建 OutputStream out = new FileOutputStream(f,true); String str = "Hello World\nsddgdgdf3434"; //因为是字节流,所以要转化成字节数组进行输出 byte[] bytes = str.getBytes(); for (byte b: bytes){ out.write(b); } out.close(); }
InputStream字节输入流
这个抽象类是表示字节输入流的所有类的超类
常用方法
read()
从输入流中读取下一个字节的数据。 值字节以0到255范围内的int形式返回。 如果由于已到达流末尾而没有可用字节,则返回值-1 。 此方法会阻塞,直到输入数据可用、检测到流结束或抛出异常为止read(byte b[])
从输入流中读取一定数量的字节并将它们存储到缓冲区数组b 。 实际读取的字节数作为整数返回。 此方法会阻塞,直到输入数据可用、检测到文件结尾或抛出异常。
如果b的长度为零,则不读取字节并返回0 ; 否则,将尝试读取至少一个字节。 如果由于流位于文件末尾而没有可用字节,则返回值-1 ; 否则,至少读取一个字节并将其存储到b 。
读取的第一个字节存储到元素b[0] ,下一个存储到b[1] ,依此类推。 读取的字节数最多等于b的长度。 令k为实际读取的字节数; 这些字节将存储在元素b[0]到b[ k -1] ,而元素b[ k ]到b[b.length-1]不受影响。read(byte b[], int off, int len)
从输入流中读取最多len个字节的数据到一个字节数组中。 尝试读取多达len个字节,但可能会读取较小的数字。 实际读取的字节数作为整数返回。
读取的第一个字节存储到元素b[off] ,下一个存储到b[off+1] ,依此类推skip(long n)
跳过并丢弃此输入流中的n字节数据,在跳过n个字节之前到达文件末尾, 返回实际跳过的字节数并抛出异常。 如果n为负,则InputStream类的skip方法始终返回 0available()
返回当前可以跳过的最大值close()
markSupported()
如果此流实例支持标记和重置方法,则为true ; 否则为falsemark(int readlimit)
标记此输入流中的当前位置。 对reset方法的后续调用将此流重新定位在最后标记的位置,以便后续读取重新读取相同的字节。reset()
将此流重新定位到上次在此输入流上调用mark方法时的位置
读取举例
- 文件大小确定
```java
public static void read() throws IOException {
File f = new File("d:" + File.separator + "test.txt");
InputStream inputStream = new FileInputStream(f);
//可以根据文件的大小设置字节数组的长度
long length = f.length();
byte[] bytes = new byte[(int) length];
int len = inputStream.read(bytes);
inputStream.close();
String s = new String(bytes, 0, len);
System.out.println(s);
}
```
文件大小不确定
public static void readNoSize2() throws IOException { File f = new File("d:" + File.separator + "test.txt"); InputStream inputStream = new FileInputStream(f); StringBuilder builder = new StringBuilder(); byte[] bytes = new byte[6]; int temp = 0, len = 0; //-1文件读取完毕 while ((temp = inputStream.read()) != -1) { bytes[len] = (byte) temp; len++; if (len == 6) { builder.append(new String(bytes)); len = 0; } } builder.append(new String(bytes, 0, len)); inputStream.close(); System.out.println(builder); }
字符流
字节流就是普通的二进制流,读出来的是bit,而字节流不便于处理Unicode形式存储的信息。字符流就是在字节流的基础按照字符编码处理,处理的是char。
Reader
常用方法
read()
read(char cbuf[])
read(char cbuf[], int off, int len)
skip(long n)
ready():告诉这个流是否准备好被读取
markSupported()
mark(int readAheadLimit)
reset()
close()
字符流读取举例
- 文件大小确定
public static void read() throws IOException { File f = new File("d:" + File.separator + "test.txt"); Reader out = new FileReader(f); char[] chars = new char[(int) f.length()]; int len = out.read(chars); out.close(); System.out.println(new String(chars, 0, len)); }
- 文件大小不确定
```java
public static void readNoSize() throws IOException {
File f = new File("d:" + File.separator + "test.txt");
Reader out = new FileReader(f);
char[] arrs = new char[6];
StringBuilder builder = new StringBuilder();
int len = 0;
int temp = 0;
while ((temp = out.read()) != -1) {
arrs[len] = (char) temp;
len++;
if (len == 6) {
builder.append(arrs);
len = 0;
}
}
builder.append(arrs, 0, len);
out.close();
System.out.println(builder);
}
```
Writer
用于写入字符流的抽象类;内置一个保存字符串和单个字符写入的临时缓冲,大小为1024
常用方法
- write(char cbuf[])
- write(char cbuf[], int off, int len)
- write(String str) :写入一个字符串
- write(String str, int off, int len)
- append(CharSequence csq):将指定的字符序列附加到此编写器
- append(CharSequence csq, int start, int end)
- append(char c)
- flush()
冲洗流。 如果流已将来自各种 write() 方法的任何字符保存在缓冲区中,则立即将它们写入其预期目的地。 然后,如果该目标是另一个字符或字节流,则刷新它。 因此,一次 flush() 调用将刷新 Writers 和 OutputStreams 链中的所有缓冲区 - close()
字符流写入举例
public static void writer() throws IOException {
File f = new File("d:" + File.separator + "test.txt");
//覆盖原有的
Writer out = new FileWriter(f);
String str = "Hello World";
out.write(str);
out.close();
}
字符流和字节流区别
- 字节流可用于任何类型的对象,包括二进制对象,而字符流只能处理字符或者字符串;
- 字节流提供了处理任何类型的IO操作的功能,但它不能直接处理Unicode字符,而字符流就可以
- 字节流默认不使用缓冲区;字符流使用缓冲区
- 在硬盘上的所有文件都是以字节形式存在的(图片,声音,视频),而字符值在内存中才会形成。