流:一维的 单方向的
流的基础类:InputStream和OutputStream
InputStream和OutputStream:字节读取流(把外界的输入当作字节的流)
FileInputStream和FileOutputStream:文件读取流
以【程序】为基准来看,input是从外部文件中读取,“进入”程序中
output是从程序内部“输出”到外部设备(包括输出到屏幕、文件、打印机等)
1、InputStream★
InputStream特点:
1、所有输入字节流的超类
2、每次只能读一个字节(1 Byte)=(8 bit)
输入流读取步骤
1、创建字节输入流的子类对象
2、对象的read()换行
3、关闭输入流 释放资源
例一:
InputStream is=new FileInputStream("d:\\IOTest.txt");//创建输入流子类对象,绑定数据目的(输入文件)
int i=is.read();//int read() 从输入流中读取数据的下一个字节
System.out.println((char)(i));
is.close();//close()关闭输入流 释放资源
例二:
InputStream is=new FileInputStream("d:\\IOTest.txt");//创建输入流子类对象,绑定数据目的(输入文件)
int nextByte=is.read();
while (nextByte!=-1)
{
System.out.print((char) nextByte);
nextByte=is.read();
}
is.close();//close()关闭输入流 释放资源
例三:
读取方法采用数组 int read(byte[] b)
InputStream is=new FileInputStream("d:\\IOTest.txt");//1、创建输入流子类对象,绑定数据目的(输入文件)
byte[] b=new byte[2];
int len=is.read(b);// int read(byte[] b) 从此输入流中将b.length()字节的数据读入一个 byte 数组中
System.out.println(len);//读了几个字符
System.out.println(new String(b)); //输出b字符数组中的字符
len=is.read(b);
System.out.println(len);
System.out.println(new String(b));
len=is.read(b);
System.out.println(len);
System.out.println(new String(b));
len=is.read(b);
System.out.println(len);//返回-1表明没有字符可读了
System.out.println(new String(b));
byte[] bt=new byte[2];
int len=is.read(b);
while (len!=-1)
{
System.out.print(new String(b,0,len));
// String(byte[] bytes, int offset, int length) 传入起始位置和长度 构造一个新的 String
len=is.read(b);
}
is.close();//3、close()关闭输入流 释放资源
2、OutputStream★
OutPutStream特点:
1、是子类输出流的超类
2、子类中的构造方法必须绑定输出文件(输出目的)
创建输出流的步骤:
1、创建输出流子类对象,绑定数据目的(输出文件)
2、调用输出流对象的写(Write)方法
3、close()关闭输出流,释放资源
方法:
OutputStream os=new FileOutputStream("d:\\IOTest.txt",true);//创建输出流子类对象,绑定数据目的(输出文件)
//若不想每次写入的数据被新数据覆盖 在后面加上true
//void write (int b) 将指定的字节写入此输出流
os.write(97);//传入的int值为二进制编码 其实保存的也是二进制编码 只是打开文本文件的时候会自动找ASCII编码表 解析
os.write(98);
os.write(99);
//write(byte[] b) 将 b.length 个字节(全部字节)从指定的 byte 数组写入此输出流
byte[] bytes={49,50,51};
os.write(bytes);
//write(byte[] b, int off, int len) 将指定 byte 数组中从 off 开始的 len 个字节写入此输出流
os.write(bytes,0,1);
String s="HelloPiconjo\r\n";//'\r'回车 使光标到行首 '\r'换行 使光标下移一格
os.write(s.getBytes());//getBytes()方法 将String字符串转换成byte数组
os.close();//close()关闭输出流 释放资源
每次输入结束必须close()关闭输出流 节省内存空间
3、BufferedInputStream/BufferedOutputStream缓冲区
例:
//1、明确源文件和目的文件
File srcFile=new File("d:\\InputOutputTest.txt");//要被复制内容的文件
File desFile=new File("d:\\ Copy_InputOutputTest.txt");//复制的内容存放的文件
//2、明确字节输入流和源文件关联 输出流和目的文件关联
InputStream is=new FileInputStream(srcFile);//关联输入流和源文件
OutputStream os=new FileOutputStream(desFile);//关联输出流和目的文件
//3、使用java提供的缓冲区 BufferedXXputStream
BufferedInputStream bis=new BufferedInputStream(is);
BufferedOutputStream bos=new BufferedOutputStream(os);
int len=0;
while ((len=is.read())!=-1)
{
os.write(len);//输出流将b里的文件输出
}
//3、自己定义一个缓冲区 1kb=1024B
byte[] b=new byte[1024];//输入流将源文件里的字符一次读取1024个Byte读到b缓冲区里
int len=0;
while ((len=is.read(b))!=-1)
{
os.write(b,0,len);//输出流将b里的文件输出
}
//4、关闭资源
is.close();
os.close();
4、读写全步骤(思路清晰版)
//1、明确源文件和目的文件
File srcFile=new File("d:\\timg.jpg");//要被复制内容的文件
File desFile=new File("d:\\iKun1.jpeg");//复制的内容存放的文件
//2、明确字节输入流和源文件关联 输出流和目的文件关联
InputStream is=new FileInputStream(srcFile);//关联输入流和源文件
OutputStream os=new FileOutputStream(desFile);//关联输出流和目的文件
//3、使用输入流的读取方式读取字节 并将字节写入到目的文件
int myByte=0;
while ((myByte=is.read())!=-1)
{
os.write(myByte);//写入到目的文件
}
//4、关闭资源
is.close();
os.close();
5、FileReader/FileWriter字符流
FileReader 字符读取流
FileReader 创建字符流对象
FileReader fileReader=new FileReader("file\\a.txt");
调用字符流对象的read()方法读取文件数据
int charr=fileReader.read();
System.out.println(charr);
读取后的是ASCII码 因此需要类型转换
System.out.println((char)charr);
FileWriter 字符输入流
FileWriter 创建字符输出流对象
FileWriter fw=new FileWriter("file\\b.txt");
创建字符数组
char[] myChar={'a','b','c','d','e'};
字符输入到文件
fw.write(myChar);
6、InputStreamReader【字节流通向字符流的桥梁】★
无论是输入流还是输出流 底层用的编码表都是GBK
InputStreamReader是字节流通向字符流的桥梁 所以可以传递字节流
语法:
InputStreamReader(InputStream in, Charset cs)
创建使用给定字符集的 InputStreamReader
用法:制定字符集→GBK
InputStreamReader isr=new InputStreamReader(fr,"GBK");
例:
1、创建基础流输入流对象:字节流 ★
FileInputStream fis=new FileInputStream("file\\a.txt");
2、创建字符流输出流字符对象 与目的文件相关联
FileWriter fw=new FileWriter("file\\b.txt");
字节流通向字符流的【桥梁】 ★
//InputStreamReader(InputStream in, Charset cs) 创建使用给定字符集的 InputStreamReader
InputStreamReader isr=new InputStreamReader(fis,"GBK");//fis是字节流 isr是字符流
创建字符缓冲流 ★
BufferedReader br=new BufferedReader(isr);//isr是字符流
readLine() 读取一个文本行 ★
//用write()方法将读取的字符流写入目的文件
fw.write(br.readLine());
4、关闭输入流和输出流
关闭字节流
fis.close();
fr.close();
fw.close();
7、LineNumberReader跟踪行号的流
例:
创建输入流字符流
FileReader fr=new FileReader("file\\c.txt");
让文件有行号
LineNumberReader 跟踪行号的输入流
LineNumberReader lnr=new LineNumberReader(fr);
lnr.setLineNumber(99);//设置行号从第几行还是(设置99 从100开始)
String s=null;
while ((s=lnr.readLine())!=null)
{
System.out.println("行号:"+lnr.getLineNumber()+" 内容:"+s);//getLineNumber()方法 获取行号
}
关闭流
lnr.close();
8、PrintStream打印流
例:
1、创建基础输出字节流
FileOutputStream fos=new FileOutputStream("file\\e.txt");
2、保证数据值的一致性(不要输入的是97 打开文件发现是ASCII码表对应的字符a)
PrintStream ps=new PrintStream(fos);
ps.print(97);
fos.close();
9、SequenceStream合并流
public static void main(String[] args) throws IOException {
connectFiles();
}
private static void connectFiles() throws IOException {
List<FileInputStream> list=new ArrayList<FileInputStream>();
list.add(new FileInputStream("file\\a.txt"));
list.add(new FileInputStream("file\\b.txt"));
list.add(new FileInputStream("file\\c.txt"));
合并多个文件 成为一个源文件
Enumeration<FileInputStream> en= Collections.enumeration(list);
SequenceInputStream sis=new SequenceInputStream(en);
创建目的文件
FileOutputStream fos=new FileOutputStream("file\\f.txt");
int a;
byte[] b=new byte[1024];
while ((a=sis.read(b))!=-1)
{
fos.write(b,0,a);
}
fos.close();
sis.close();
}