「这是我参与11月更文挑战的第6天,活动详情查看:2021最后一次更文挑战」
根据数据流向不同分为:输入流和输出流。
输入流--InputStream
java.io.InputStream类是所有Java IO输入流的基类,它是以字节为单位的输出流。
类图展示
-
ByteArrayInputStream:字节数组输入流在内存中创建一个字节数组缓冲区,从输入流读取的数据保存在该字节数组缓冲区中
-
FileInputStream:从文件读取数据
-
ObjectInputStream:反序列化流,将之前使用 ObjectOutputStream 序列化的原始数据恢复为对象,以流的方式读取对象。
-
PipedInputStream管道读取流
-
FilterInputStream]是过滤输出流
-
BufferedInputStream: 提供了缓冲功能。
-
DataInputStream: 允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型。应用程序可以使用数据输出流写入稍后由数据输入流读取的数据。
-
PipedInputStream: 允许以管道的方式来处理流。当连接到一个PipedOutputStream后,它会读取后者输出到管道的数据。
-
PushbackInputStream: 允许放回已经读取的数据。
-
SequenceInputStream: 能对多个inputstream进行顺序处理。
inputStream主要api方法
-
read:读取数据流字节,存储到缓冲区数组
public abstract int read() public int read(byte[] b) public int read(byte[] b,int off,int len)
available():获取数据流字节长度大小close():关闭并且释放流资源mark(int readlimit):设置输入流的当前位置reset():重新定位输入流的位置skip(long n):跳过并丢弃输入流的n个字节
FileInputStream。
FileInputStream读取文件。
/**
* 读取filePath的文件,将文件中的数据按照行读取到String数组中
* @param filePath 文件的路径
* @return 文件中一行一行的数据
*/
public static String[] readToString(String filePath) {
File file = new File(filePath);
Long filelength = file.length(); // 获取文件长度
byte[] filecontent = new byte[filelength.intValue()];
try {
FileInputStream in =new FileInputStream(file); in .read(filecontent); in .close();
} catch(FileNotFoundException e) {
e.printStackTrace();
} catch(IOException e) {
e.printStackTrace();
}
String[] fileContentArr = new String(filecontent).split("\r\n");
return fileContentArr; // 返回文件内容,默认编码
}
输入流--outputStream
-
OutputStream类是Java IO API中所有输出流的基类。子类包括BufferedOutputStream,FileOutputStream等等。
-
OutputStream是一个典型的装饰者模式,使用的时候直接new子类。
-
utputStream可以输出到console,文件,磁盘等目标媒介中。
类图展示
-
OutputStream是以字节为单位的输出流的超类,提供了write()函数从输出流中读取字节数据。
-
ByteArrayOutputStream是字节数组输出流,写入ByteArrayOutputStream的数据被写入到一个byte数组,缓冲区会随着数据的不断写入而自动增长,可使用toByteArray()和toString()获取数据。
-
PipedOutputStream是管道输出流,和PipedInputStream一起使用,能实现多线程间的管道通信。
-
FilterOutputStream是过滤输出流,是DataOutputStream,BufferedOutputStream和PrintStream的超类
-
DataOutputStream是数据输出流,用来装饰其他的输出流,允许应用程序以与机器无关方式向底层写入基本Java数据类型。
-
BufferedOutputStream是缓冲输出流,它的作用是为另一个输出流添加缓冲功能。
-
PrintStream是打印输出流,用来装饰其他输出流,为其他输出流添加功能,方便的打印各种数据值
-
FileOutputStream是文件输出流,通常用于向文件进行写入操作。
-
ObjectOutputStream是对象输出流,它和ObjectInputStream一起对基本数据或者对象的持久存储
outputStream主要api方法
-
write():将数据写入输出流
-
public abstract void write(int b) public void write(byte[] b) public void write(byte[] b,int off,int len) -
close():关闭并且释放流资源
-
flush():刷新此输出流并强制写出所有缓冲的输出字节
代码示例:
// 模拟浏览器,给tomcat服务端发送符合http协议的请求消息
public static void main(String[] args) throws IOException
{
Socket s = new Socket("127.0.0.1", 80);
PrintWriter out = new PrintWriter(s.getOutputStream()); //这里的ture表示流会自动刷新,在后面可以不用使用flush()方法
out.println("GET /myweb/test.jsp HTTP/1.1");
out.println("Accept: */*");
out.println("Accept-Language: zh-CN");
out.println("Accept-Encoding: gzip, deflate");
out.println();
out.flush(); // 清空缓存并输出流
InputStream in = s.getInputStream();
byte b[] = new byte[1024];
int leng = 0;
while((leng = in .read(b)) != -1)
{
String str = new String(b, 0, leng);
System.out.println(str);
}
s.close();
}
FilterOutputStream类
FileOutputStream写入文件中
public static String[] readToString(String filePath1,String filePath2) {
InputStream is = new FileInputStream(filePath1);
FileOutputStream fos = new FileOutputStream(filePath2);
byte[] b = new byte[1024];
while ((is.read(b)) != -1) {
fos.write(b);// 写入数据
}
is.close();
fos.close();// 保存数据
}
ByteArrayOutputStream类
ByteArrayOutputStream在内存中创建了一个字节数组,所有发送到输出流的数据都会保存到该字节数组的缓冲区中。数据写入缓冲区以后,然后使用toByteArray()和toString()输出。
public static void main(String[] args)
{
ByteArrayOutputStream bos = null;
FileInputStream fs = null;
try
{
bos = new ByteArrayOutputStream();
fs = new FileInputStream("c:\\51gjie.txt");
int len;
while((len = fs.read()) != -1)
{
// 把读取到的数据逐个写到ByteArrayOutputStream中
bos.write(len);
}
byte[] array = bos.toByteArray();
// 指定utf-8解码的字符集
System.out.println(new String(array, "utf-8"));
fs.close();
}
catch(IOException e)
{}
finally
{
fs.close();
}
}
DataOutputStream类
DataOutputStream允许应用程序以与机器无关方式将Java基本数据类型(boolean,byte,int,long,string等)写到底层输出流。
public static void main(String[] args) throws IOException
{
FileOutputStream in = new FileOutputStream("c\\51gjie.txt");
DataOutputStream out = new DataOutputStream( in );
String string = "欢迎来到www.51gjie.com";
out.writeBytes(string);
out.writeChars(string);
out.writeUTF(string);
out.close();
System.out.println("写入成功!");
}
BufferedOutputStream类
1. 当创建BufferedOutputStream时,会创建一个内部缓冲区数组,应用程序可以向底层输出流写入字节数据,当写入数据时,可以不用每次都去调用底层方法,而是直接从缓存区获取数据。
2. BufferedOutputStream缓冲输出流在输出的时候,不是直接一个字节一个字节的操作,而是先写入内存的缓冲区内。直到缓冲区满了或者我们调用close方法或flush方法,该缓冲区的内容才会写入目标。才会从内存中转移到磁盘上,因此效率是非常高的。
public static void main(String[] args) throws IOException
{
OutputStream os = new FileOutputStream("c:/51gjie.txt");
OutputStream bs = new BufferedOutputStream(os);
byte[] buffer = "欢迎来到www.51gjie.com".getBytes();
bs.write(buffer);
bs.close();//写入文件
os.close();
}
如果文件太大,一次性读取这个大文件的所有数据,内存可能装不下,但是如果每次只读一个字节数据,会耗时太慢。因此用BufferedInputStream一次读取1024*8个字节数据,用BufferedOutputStream放入缓冲区,分批读写。代码如下:
public static void main(String[] args) throws IOException
{
BufferedInputStream bufferInput = null;
BufferedOutputStream bufferOutput = null;
try
{
// 输入缓冲流
InputStream input = new FileInputStream(new File("c:\\100MB.txt"));
bufferInput = new BufferedInputStream(input);
// 输出缓冲流
OutputStream output = new FileOutputStream(new File("c:\\100MB_test.txt"));
bufferOutput = new BufferedOutputStream(output);
// 定义个8kb字节数组,作为缓冲区流
byte[] bytes = new byte[1024 * 8];
int len = 0;
while((len = bufferInput.read(bytes)) != -1)
{
bufferOutput.write(bytes, 0, len);
}
}
catch(IOException e)
{
}
finally
{
try
{
if(bufferInput != null)
{
bufferInput.close();
}
if(bufferOutput != null)
{
bufferOutput.close();
}
}
catch(IOException e)
{
}
}
}