定义 | 处理对象 | 使用 | |
字节流 | 按照字节(8byte)为单位,读取数据,可能会乱码,没有缓冲区 ,直接输入,字节流不调用colse()方法时,信息已经输出了, |
所有类型的数据 | 图片,音频视频优先考虑 |
字符流 |
字符流是基于字节流读取时,查了指定的码表,
一次可以读取多个字节,效率高,不会乱码,
有缓冲区,
而字符流只有在调用
close()
方法关闭缓冲区时,信息才出。
要想字符流在未关闭时输出信息,则需要手动调用flush()方法。
|
只能处理字符类型的数据 | 纯文本优先考虑 |
1.流式部分: IO的主体部分;
2.非流式部分: 主要包含一些辅助流式部分的类,如:File类、RandomAccessFile类和FileDescriptor等类;
3.其他类: 文件读取部分的与安全相关的类,如:SerializablePermission类,以及与本地操作系统相关的文件系统的类,如:FileSystem类和Win32FileSystem类和WinNTFileSystem类。
4.File(文件特征与管理):用于文件或者目录的描述信息,例如生成新目录,修改文件名,删除文件,判断文件所在路径等。
5.InputStream(二进制格式操作):抽象类,基于字节的输入操作,是所有输入流的父类。定义了所有输入流都具有的共同特征。
6.OutputStream(二进制格式操作):抽象类。基于字节的输出操作。是所有输出流的父类。定义了所有输出流都具有的共同特征。
4. Reader(文件格式操作):抽象类,基于字符的输入操作。
5. Writer(文件格式操作):抽象类,基于字符的输出操作。
6. RandomAccessFile(随机文件操作):它的功能丰富,可以从文件的任意位置进行存取(输入输出)操作。
InputStream 为字节输入流,它本身为一个抽象类,必须依靠其子类实现各种功能,此抽象类是表示字节输入流的所有类的超类。 继承自InputStream 的流都是向程序中输入数据的,且数据单位为字节(bit);
InputStream是输入字节数据用的类,所以InputStream类提供了3种重载的read方法.
Inputstream类中的常用方法:
(1) public abstract int read( ):读取一个byte的数据,返回值是高位补0的int类型值。若返回值=-1说明没有读取到任何字节读取工作结束。
(2) public int read(byte b[ ]):读取b.length个字节的数据放到b数组中。返回值是读取的字节数。该方法实际上是调用下一个方法实现的
(3) public int read(byte b[ ], int off, int len):从输入流中最多读取len个字节的数据,存放到偏移量为off的b数组中。
(4) public int available( ):返回输入流中可以读取的字节数。注意:若输入阻塞,当前线程将被挂起,如果InputStream对象调用这个方法的话,它只会返回0,这个方法必须由继承InputStream类的子类对象调用才有用,
(5) public long skip(long n):忽略输入流中的n个字节,返回值是实际忽略的字节数, 跳过一些字节来读取
(6) public int close( ) :我们在使用完后,必须对我们打开的流进行关闭.
1) FileInputStream把一个文件作为InputStream,实现对文件的读取操作
2) ByteArrayInputStream:把内存中的一个缓冲区作为InputStream使用
3) StringBufferInputStream:把一个String对象作为InputStream
4) PipedInputStream:实现了pipe的概念,主要在线程中使用
5) SequenceInputStream:把多个InputStream合并为一个InputStream
1) ByteArrayOutputStream:把信息存入内存中的一个缓冲区中
2) FileOutputStream:把信息存入文件中
3) PipedOutputStream:实现了pipe的概念,主要在线程中使用
4) SequenceOutputStream:把多个OutStream合并为一个OutStream
流结束的判断:方法read()的返回值为-1时;readLine()的返回值为null时。
也可以使用一个文件对象来创建一个输入流对象来读取文件。我们首先得使用 File() 方法来创建一个文件对象:
构造方法摘要 | |
---|---|
FileInputStream(File file) 通过打开一个到实际文件的连接来创建一个 FileInputStream ,该文件通过文件系统中的 File 对象 file 指定。 |
|
FileInputStream(FileDescriptor fdObj) 通过使用文件描述符 fdObj 创建一个FileInputStream ,该文件描述符表示到文件系统中某个实际文件的现有连接。 |
|
FileInputStream(String name) 通过打开一个到实际文件的连接来创建一个 FileInputStream ,该文件通过文件系统中的路径名 name 指定。 |
方法摘要 | |
---|---|
int |
available() 返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取(或跳过)的估计剩余字节数。 |
void |
close() 关闭此文件输入流并释放与此流有关的所有系统资源。 |
protected void |
finalize() 确保在不再引用文件输入流时调用其 close 方法。 |
FileChannel |
getChannel() 返回与此文件输入流有关的唯一 FileChannel 对象。 |
FileDescriptor |
getFD() 返回表示到文件系统中实际文件的连接的 FileDescriptor 对象,该文件系统正被此FileInputStream 使用。 |
int |
read() 从此输入流中读取一个数据字节。 |
int |
read(byte[] b) 从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。 |
int |
read(byte[] b, int off, int len) 从此输入流中将最多 len 个字节的数据读入一个 byte 数组中。 |
long |
skip(long n) 从输入流中跳过并丢弃 n 个字节的数据。 |
其中read()
返回的是读入的一个字节所对应的int值(0-255),而read(byte[] b)
和read(byte[] b, int off, int len)
返回的是读入的字节数
FileOutputStream用于将字节数据写出到文件。继承自OutputStream类
使用字符串类型的文件名来创建一个输出流对象:
也可以使用一个文件对象来创建一个输出流来写文件。我们首先得使用File()方法来创建一个文件对象:
构造方法摘要 | |
---|---|
FileOutputStream(File file) 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。 |
|
FileOutputStream(File file, boolean append) 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。 |
|
FileOutputStream(FileDescriptor fdObj) 创建一个向指定文件描述符处写入数据的输出文件流,该文件描述符表示一个到文件系统中的某个实际文件的现有连接。 |
|
FileOutputStream(String name) 创建一个向具有指定名称的文件中写入数据的输出文件流。 |
|
FileOutputStream(String name, boolean append) 创建一个向具有指定 name 的文件中写入数据的输出文件流。 |
方法摘要 | |
---|---|
void |
close() 关闭此文件输出流并释放与此流有关的所有系统资源。 |
protected void |
finalize() 清理到文件的连接,并确保在不再引用此文件输出流时调用此流的 close 方法。 |
FileChannel |
getChannel() 返回与此文件输出流有关的唯一 FileChannel 对象。 |
FileDescriptor |
getFD() 返回与此流有关的文件描述符。 |
void |
write(byte[] b) 将 b.length 个字节从指定 byte 数组写入此文件输出流中。 |
void |
write(byte[] b, int off, int len) 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。 |
void |
write(int b) 将指定字节写入此文件输出流。 |
/** * 复制文件内容到指定文件(FileInputStream/FileOutPutStream) * * @param file1 源文件 * @param file2 目标文件 */ public static void copyFileToFile(String file1, String file2) { FileInputStream fis = null; FileOutputStream fos = null; File _file1 = new File(file1); File _file2 = new File(file2); if (_file1.exists() && _file1.isFile() && _file2.exists() && _file2.isFile()) { try { fis = new FileInputStream(_file1); fos = new FileOutputStream(_file2); byte[] bytes = new byte[1024]; int lg = 0; while ((lg = fis.read(bytes)) != -1) { fos.write(bytes, 0, lg); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (fis != null) { fis.close(); } if (fos != null) { fos.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
write(String str) //写入字符串。当执行完此方法后,字符数据还并没有写入到目的文件中去。此时字符数据会保存在缓冲 区中。此时在使用刷新方法就可以使数据保存到目的文件中去。
viod flush() //刷新该流中的缓冲。将缓冲区中的字符数据保存到目的文件中去。
viod close() //关闭此流。在关闭前会先刷新此流的缓冲区。在关闭后,再写入或者刷新的话,会抛IOException异常。
/**
* FileWriter 字符文件输入流 通过此IO流向指定file添加字符串内容
*
* @param path 文件的绝对路径
*/
public static void fileWriterToFile(String path) {
String content = "Are you ok!hao are your?";
if (!TextUtils.isEmpty(path)) {
File file = new File(path);
if (file.exists() && file.isFile()) {
FileWriter fileWriter = null;
try {
fileWriter = new FileWriter(file, true);
// fileWriter.append(content);//通过追加字符串
fileWriter.write(content.toCharArray(), 0, content.getBytes().length);//通过字节数组写入
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileWriter != null) {
try {
fileWriter.flush();
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
主要方法
int read(); // 读取单个字符。返回作为整数读取的字符,如果已达到流末尾,则返回 -1。
int read(char []cbuf);//将字符读入数组。返回读取的字符数。如果已经到达尾部,则返回-1。
void close();//关闭此流对象。释放与之关联的所有资源。
通过字符流FileRead/FileWriter拷贝文件内容
/** * FileWriter/FileRead 拷贝文件内容(FileRead/FileWriter) * * @param path1 源文件的绝对路径 * @param path2 目标文件的绝对路径 */ public static void copyFileToFile1(String path1, String path2) { File file1 = new File(path1); File file2 = new File(path2); if (file1.exists() && file1.isFile() && file2.exists() && file2.isFile()) { FileWriter fileWriter = null; FileReader fileReader = null; try { fileReader = new FileReader(file1); fileWriter = new FileWriter(file2); char[] bytes = new char[1024]; int index; while ((index = fileReader.read(bytes)) != -1) { fileWriter.write(bytes, 0, index); } } catch (IOException e) { e.printStackTrace(); } finally { if (fileWriter != null) { try { fileReader.close(); fileWriter.flush(); fileWriter.close(); } catch (IOException e) { e.printStackTrace(); } } } } }ByteArrayInputStream
接收字节数组作为参数创建:
ByteArrayInputStream bArray = new ByteArrayInputStream(byte [] a);
另一种创建方式是接收一个字节数组,和两个整形变量 off、len,off表示第一个读取的字节,len表示读取字节的长度。
ByteArrayInputStream bArray = new ByteArrayInputStream(byte []a, int off, int len)
成功创建字节数组输入流对象后,可以参见以下列表中的方法,对流进行读操作或其他操作。
序号 | 方法描述 |
---|---|
1 | public int read() 从此输入流中读取下一个数据字节。 |
2 | public int read(byte[] r, int off, int len) 将最多 len 个数据字节从此输入流读入字节数组。 |
3 | public int available() 返回可不发生阻塞地从此输入流读取的字节数。 |
4 | public void mark(int read) 设置流中的当前标记位置。 |
5 | public long skip(long n) 从此输入流中跳过 n 个输入字节。 |
字节数组输出流在内存中创建一个字节数组缓冲区,所有发送到输出流的数据保存在该字节数组缓冲区中。创建字节数组输出流对象有以下几种方式。
下面的构造方法创建一个32字节(默认大小)的缓冲区。
OutputStream bOut = new ByteArrayOutputStream();
另一个构造方法创建一个大小为n字节的缓冲区。
OutputStream bOut = new ByteArrayOutputStream(int a)
成功创建字节数组输出流对象后,可以参见以下列表中的方法,对流进行写操作或其他操作。
序号 | 方法描述 |
---|---|
1 | public void reset() 将此字节数组输出流的 count 字段重置为零,从而丢弃输出流中目前已累积的所有数据输出。 |
2 | public byte[] toByteArray() 创建一个新分配的字节数组。数组的大小和当前输出流的大小,内容是当前输出流的拷贝。 |
3 | public String toString() 将缓冲区的内容转换为字符串,根据平台的默认字符编码将字节转换成字符。 |
4 | public void write(int w) 将指定的字节写入此字节数组输出流。 |
5 | public void write(byte []b, int off, int len) 将指定字节数组中从偏移量 off 开始的 len 个字节写入此字节数组输出流。 |
6 | public void writeTo(OutputStream outSt) 将此字节数组输出流的全部内容写入到指定的输出流参数中。 |
从文件中读取二进制数据,全部存储到ByteArrayOutputStream中。
FileInputStream fis=new FileInputStream("test");
BufferedInputStream bis=new BufferedInputStream(fis);
ByteArrayOutputStream baos=new ByteArrayOutputStream();
int c=bis.read();//读取bis流中的下一个字节
while(c!=-1){
baos.write(c);
c=bis.read();
}
bis.close();
byte retArr[]=baos.toByteArray();