黑马程序员---高级网络编程 io 输入,输出流

时间:2022-12-16 10:59:29
IO 流  java.io.*;
流的定义: 好比一个管道。 设备与程序之间嫁接起来的一根用于数据传输的管道,中间有个管道,管道上会有很多个按纽,
每调用一次方法,也就是按着不同的按纽进行操作。

流的分类:文件流 缓冲流 转换流 数据流 Print流 Object流
节点流也叫原始流 可以从一个特定的数据源(节点) 读写数据 (如内存,文件).
处理流也叫包裹流 处理流是连接在以存在的流(节点流或处理流)之上,为程序提供更为强大的读写功能.

流的使用:
1:四大基本抽象流
字节流 字符流
输入流 InputStream Reader
输出流 OutputStream Writer
读一个字节 读2个字节
输出一个字节 输出2个字节
这4个抽象流都是抽象类,通常我们使用他们的子类对象。

InputStream :
|--流中的常用方法: throws IOException
public int read();
|--读取一个字节并以整数形式返回
|--如果读取到输入流的末尾则返回-1
public int read(byte[] b); throws IOException
例子:
FileInputStream fis =new FileInputStream("d:\\share\\errrlog.txt");
len=fis.read(buf);
从fis流所指向D盘文件中读取数据,并将读取出来的数据写入buf数组中,返回值是实际写入buf数组的字节个数
如果读取到的文件结尾,则返回-1;

2:文件流
/*
文件流:
|--FileInputStream FileOutputStream 字节流
|--FileReader FileWriter 字符流

例子:读取一个文件的内容并将其输出到显示器上。并统计读取出来的字节的个数

思路:指定一个文件,
读取内容
输出屏幕上
最后统计字节的个数
步骤: 1:通过FileInputStream(File file)构造函数 打开一个实际文件的连接
2:文件流调用父类的方法read();读取一个字节
3:定义2个变量,用cnt记录字节的个数 ch记录读出来的字节
*/
import java.io.*;
class TestRead
{
public static void main(String[] args)
{
FileInputStream fis = null;
try
{
fis = new FileInputStream("d:\\1\\TestRead.java");
int cnt=0;
int ch;
ch=fis.read();
while(-1 !=ch)
{
System.out.print((char)ch);
++cnt;
ch=fis.read();
}
System.out.println("从本文件读取出来的字节个数是:"+cnt);
}
catch (FileNotFoundException e)
{
System.out.println("找不到文件");
System.exit(-1);
}
catch (IoException e)
{
System.out.println("文件读取失败");
System.exit(-1);
}

}
}


/*
利用FileInputStream 和FileOutputStream 可以完成所有格式文件的赋值
因为字节是不需要解码和编码的,
将字节转换成字符才存在解码的问题

本程序完成了视频文件的复制

思路:
1: 定义FileInputStream 和FileOutputStream 空指针
2: 实例输出流和输入流 从一个文件读 复制到另一个指定文件
3: 输出流掉用读的方法,判断不是文件结尾就一直读, 读出来的字节写入输入流中.
4:捕捉文件找不到异常,和文件读写失败异常,终止虚拟机
5:一定要输出的语句: 关闭文件
*/
import java.io.*;
class TestRead
{
public static void main(String[] args)
{
FileInputStream fis =null;
FileOutputStream fos =null;

try
{
fis =new FileInputStream("C:\\Documents and Settings\\All Users\\Documents\\My Music\\示例音乐\\1.wma");
fos =new FileOutputStream("d:/yinyue.jddd");
int ch;
ch = fis.read();
while(-1 !=ch)
{
fos.write(ch);
ch = fis.read();
}
}
catch (FileNotFoundException e)
{
System.out.println("文件找不到");
System.exit(-1); //终止当前运行的JVM虚拟机
}
catch (IOException e)
{
System.out.println("文件读写失败");
System.exit(-1); //终止当前运行的JVM虚拟机
}
finally
{
try
{
if(null !=fis)
{ fis.close();
fis=null;}

if(null !=fos)
{ fos.close();
fos=null;}
}
catch (Exception e)
{
e.printStackTrace();
System.exit(-1);
}
}
System.out.println("文件复制成功");
}
}

FileReader 和 FileWriter 只可以完成文本文件的复制,却无法完成视频格式文件的复制
3:缓冲流
BufferedInputStream
BufferedOutputStream
BufferedWriter
BufferedReader
缓冲流本身就是处理流 也叫包裹流,它里面包着节点流. 包裹流在外层.
//包裹字节流输入:构造方法:BufferedInputStream(InputStream in)
BufferedInputStread bis = new BufferedInputStream(new FileInputStream("d:\\chenlihong.java"));
//包裹字节流输出:构造方法:BufferedOutputStream(OutputStream out)
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("c:/chenlihong.heihei"));
//定义一个字节数组 buf用来存储读到的字节
byte[] buf = new byte[1024];
//文件的长度
int len;
//字节流读取字符 写到buf里面 返回是一个整型数字 write(byte[] b, int off, int len)
len = bis.read(buf,0,len);
//判断下一个字节是否有效 有效字符写入此缓冲流的 (bos 是个缓冲区流)
while(-1 !=len)
{
bos.write(buf);
len = bis.read(buf);
}
//刷新缓冲输出流
bos.flush();
//关闭文件
bis.close();
bos.close();

BufferedReader流中有readLine是个非常有用的方法
BufferedReader是个要经常使用的流
使用BufferedReader和BufferedWriter可以提高读写文本文件内容的速度

/*
BufferedOutputStream 带缓冲输出流,允许一次向硬盘写入多个字节的数据
BufferedInputStream 带缓冲的输入流,允许一次向程序中读入多个字节的数据
都是包裹流,必须依附于OutputStream 和InputStream

例子:使用缓冲输入,输出流 完成大量文件的复制
思路:
1:输入和输出流 2个空指针
2:实例输入流和输出流 子类对象
3:用一个数组记录缓冲区中的字节
*/
import java.io.*;

class TestRead
{
public static void main(String[] args)
{
BufferedInputStream bis =null;
BufferedOutputStream bos =null;
try
{
bis = new BufferedInputStream(new FileInputStream("D:\\java\\第8天\\黑马程序员_毕向东_Java基础视频教程第08天-01-面向对象(多态-概念).avi"));
bos = new BufferedOutputStream(new FileOutputStream("c:/wenjian.heihei"));
byte[] by =new byte[1024];
int len =bis.read(by,0,1024);
while(-1 !=len)
{
bos.write(by,0,len);//不是写入by数组,而是将by数组中下标从0开始的到len-1为止的所有数据写入c:/wenjian.heihei
len =bis.read(by); //bis.read(buf); 等价于 bis.read(buf, 0, buf.length);
}
bos.flush();//刷新缓冲区
bos.close();
bis.close(); //关闭文件
}
catch (FileNotFoundException e)
{
System.out.println("没有找到文件!");
System.exit(-1);
}
catch (IOException e)
{
System.out.println("文件读写错误!");
System.exit(-1);
}

System.out.println("文件复制成功!");
}
}

4:转换流
OutputStreamWriter 流是把OutputStream流 转换成Writer 流的流
InputStreamReader 是把InputStream 转化成Reader
OutputStreamWriter 和InputStreamReader 都是包裹流

编程:如何将键盘输入的字符 组成字符串直接付给String对象
5:数据流
一共有2个 数据流
1:DataInputStream
2: DataOutputStream


6:Print流 好好看一下API Print
Print 流只有输出,没有输入
分类: PrintWriter 输出字节
PrintStream 输出字节
他们关系一般不大,一般都用下面这个
Writer 的write方法 可以写入:
|-- 一个字符
|-- 一个字符数组
|-- 一个字符数组的一部分
|-- 一个字符串
|-- 一个字符的一部分
OutputStream 的writer方法可以写入:
|-- 一个字符
|-- 一个字符数组
|-- 一个字符数组的一部分
DataOutputStream 流可以写入
|-- 一个字符
|-- 一个字符数组(继承自OutputStream)
|-- 一个字符数组的一部分
所有的基本类型数据的二进制代码
如:writeDouble(8。8);写入的是8。8的二进制代码,共占8个字节
PrintStream 流的print可以写入
所有基本类型数据的字符串形式表示
如:print(8。8);写入的是'8'.'8'这三个字符 共占3个字节

7:Object流

4大基本流到底是什么关系?
方法名字一样不一样?
方法型参一样不一样?
方法到底有什么用途?

学了很多类,你一定要知道类里有什么样的方法,为啥我用这个类?为啥我不用那个类?