【JAVA IO】_字节流与字符流笔记
本章目标:
掌握流的概念
掌握字节流与字符流的作用
掌握文件的标准操作步骤
掌握字节与字符操作的区别
程序中的输入输出都是以流的形式保存的,流中保存的实际上全部是字节文件。
3.2、字节流与字符流
在java.io包中操作文件内容的主要有两大类:字节流、字符流,两类都分为输入和输出操作。在字节流中输出数据主要是使用OutputStream完成,输入使的是InputStream,在字符流中输出主要是使用Write类完成,输入主要是使用Reader类完成。
内容操作就四个类:OutputStream、InputStream、Writer、Reader
操作流程:
A、使用File类打开一个文件
B、通过字节流或字符流的子类,指定输出的位置
C、进行读/写操作
D、关闭输入/输出
3.3、字节流
字节流主要是操作byte类型数据,以byte数组为准,主要操作类就是OutputStream、InputStream。
字节输出流:OutputStream
字节输入流:InputStream
Byte是字节,肯定使用字节流操作。所有的数据基本上都可以直接使用byte数组表示出来。
3.3.1、字节输出流:OutputStream
OutputStream类
outputStream是整个io包中字节输出流的最大父类,此类的定义如下:
public abstract class OutputStream extends Object implements Closeable,Flushable
Closeable表示可以关闭的操作,因为程序运行到最后肯定要关闭。
Flushable表示刷新,清空内存中的数据。
OutputStream类的常用方法:
No. 方法或变量 描述
1 public void close() throws IOException 关闭输出流
2 public void flash() throws IOException 刷新缓冲区
3 public void write(byte[] b) throws IOException 将一个byte数组写入数据流
4 public void write(byte[] b,int off,int len) throws IOException 将一个指定范围的byte数组写入数据流
5 public abstract void write(int b) throws IOException 将一个字节数据写入数据流
要想使用以上方法,必须使用子类实例化,此时使用FileOutputStream子类,此类的构造方法如下:
public FileOutputStream(File file) throws FileNotFoundException
在操作的时候,如果文件本身不存在,则会为用户自动创建新文件。
在操作输出流的时候,也可以使用write(int i)的方法写出数据。
以上操作中在写入数据后,文件之前的内容已经不存在了,因为在IO操作中默认的情况是将其内容覆盖的,那么如果现在想要执行追加的功能,则必须设置追加操作,找到FileOutputStream类。
构造方法:
public FileOutputStream(File file,boolean append) throws FileNotFoundException
如果在文件操作中想换行的话,使用"\r\n"完成。
3.3.2、字节输入流:InputStream
定义格式:
public abstract class InputStream extends Object implements Closeable
构造方法:
public FileInputStream(File file) throws FileNotFoundException
InputStream类的常用方法
No. 方法或常量 描述
1 public int available() throws IOException 可以取得输入文件的大小
2 public void close() throws IOException 关闭输入流
3 public abstract int read() throws IOException 读取内容,以数字的方式读取
4 public int read(byte[] b) throws IOException 将内容读到byte数组之中,同时返回读入的个数。
输出:
内容为:Hello World!!!Hello World!!!
Hello World!!!
此时内容虽然读取出来了,但是可以发现存在的问题。
能不能根据文件的大小来开辟数组空间呢?
直接使用File类即可:public long length()
以上是直接使用byte数组的方式完成的。
现在使用public abstract int read() throws IOException读取内容
以上的操作,只适合于知道输入流大小的时候,如果现在不知道大小呢?
当不知道读取内容有多大的时候,就只能以读取的数据是否为-1做为读完的标志。
3.4、字符流
在程序中一个字节等于2个字节,那么java提供了Reader、Writer两个专门操作字符流的类。
字符输出流Writer
字符输入流Reader
3.4.1、字符输出流:Writer
Write本身是一个字符流的输出类,此类的定义如下:
public abstract class Writer extends Object implements Appendable,Closeable,Flushable
构造方法:
public FileWriter(File file) throws IOException
Writer类的常用方法
No. 方法或常量 描述
1 public abstract void close() throws IOException 关闭输出流
2 public void write(String str) throws IOException 将字符串输出
3 public void write(Char[] char) throws IOException 将字符数组输出
4 public abstract void flush() throws IOException 强制性清空缓存
字符流的操作比字节流操作好在一点,就是可以直接输出字符串了。不用再像之前那样进行转换操作了。
FileWriter增加追加标识
3.4.2、字符输入流Reader
字符输入流:Reader
定义格式:
public abstract class Reader extends Object implements Readable,Closeable
Reader本身也是抽象类地,如果现在要从文件中读取内容,则可以直接使用FileReader子类。
FileReader的构造方法:
public FileReader(File file) throws FileNotFoundException
Reader类的常用方法:
No. 方法或常量 描述
1 public abstract void close() throws IOException 关闭输出流
2 public int read() throws IOException 读取单个字符
3 public int read(char[] cbuf) throws IOException 将内容读到字符数组之中,返回读入的长度
以字符数组的形式读取出数组
可以使用循环的方式,通过文件是否读到低的形式读取。
3.5、字节流与字符流的区别
字节流和字符流使用是非常相似的,那么除了操作代码的不同之外,还有那些不同呢?
通过一段代码来验证字符流使用到了缓存。
在使用字节流操作中,即使没有关闭,最终也是可以输出的。
以上的操作,没有输出任何的内容出来,也就是说,所有的内容现在都是保存在了缓冲区之中,而如果执行关闭的时候会强制性的刷新缓冲区,所以可以把内容输出。
如果现在假设,没有关闭的话,也可以手工强制性调用刷新方法。
public abstract void flush() throws IOException
问题: 开发中是使用字节流好还是字符流好?
所有的硬盘上保存文件或是进行传输的时候都是以字节的方式进行的。包括图片也是按字节完成,而字符是只有在内存中才会形成,所以使用字节的操作是最多的。
3.6、操作范例
本章目标:
掌握流的概念
掌握字节流与字符流的作用
掌握文件的标准操作步骤
掌握字节与字符操作的区别
程序中的输入输出都是以流的形式保存的,流中保存的实际上全部是字节文件。
3.2、字节流与字符流
在java.io包中操作文件内容的主要有两大类:字节流、字符流,两类都分为输入和输出操作。在字节流中输出数据主要是使用OutputStream完成,输入使的是InputStream,在字符流中输出主要是使用Write类完成,输入主要是使用Reader类完成。
内容操作就四个类:OutputStream、InputStream、Writer、Reader
操作流程:
A、使用File类打开一个文件
B、通过字节流或字符流的子类,指定输出的位置
C、进行读/写操作
D、关闭输入/输出
3.3、字节流
字节流主要是操作byte类型数据,以byte数组为准,主要操作类就是OutputStream、InputStream。
字节输出流:OutputStream
字节输入流:InputStream
Byte是字节,肯定使用字节流操作。所有的数据基本上都可以直接使用byte数组表示出来。
3.3.1、字节输出流:OutputStream
OutputStream类
outputStream是整个io包中字节输出流的最大父类,此类的定义如下:
public abstract class OutputStream extends Object implements Closeable,Flushable
Closeable表示可以关闭的操作,因为程序运行到最后肯定要关闭。
Flushable表示刷新,清空内存中的数据。
OutputStream类的常用方法:
No. 方法或变量 描述
1 public void close() throws IOException 关闭输出流
2 public void flash() throws IOException 刷新缓冲区
3 public void write(byte[] b) throws IOException 将一个byte数组写入数据流
4 public void write(byte[] b,int off,int len) throws IOException 将一个指定范围的byte数组写入数据流
5 public abstract void write(int b) throws IOException 将一个字节数据写入数据流
要想使用以上方法,必须使用子类实例化,此时使用FileOutputStream子类,此类的构造方法如下:
public FileOutputStream(File file) throws FileNotFoundException
import java.io.File;
import java.io.OutputStream;
import java.io.FileOutputStream;
public class OutputStreamDemo01{
public static void main(String args[])throws Exception{
//第一步、使用File类找到一个文件
File f = new File("d:"+File.separator+"test.txt");
//第二步、通过子类实例化父类对象
OutputStream out = null;
out = new FileOutputStream(f);
//第三步、进行写操作
String str = "Hello World!!!";
byte b[] = str.getBytes();
out.write(b);
//第四步、关闭输出流
out.close();
}
}
在操作的时候,如果文件本身不存在,则会为用户自动创建新文件。
在操作输出流的时候,也可以使用write(int i)的方法写出数据。
import java.io.File;
import java.io.OutputStream;
import java.io.FileOutputStream;
public class OutputStreamDemo01{
public static void main(String args[])throws Exception{
//第一步、使用File类找到一个文件
File f = new File("d:"+File.separator+"test.txt");
//第二步、通过子类实例化父类对象
OutputStream out = null;
out = new FileOutputStream(f);
//第三步、进行写操作
String str = "Hello World!!!";
byte b[] = str.getBytes();
for(int i=0;i<b.length;i++){
out.write(b[i]); //每次只写一个字节内容
}
//第四步、关闭输出流
out.close();
}
}
以上操作中在写入数据后,文件之前的内容已经不存在了,因为在IO操作中默认的情况是将其内容覆盖的,那么如果现在想要执行追加的功能,则必须设置追加操作,找到FileOutputStream类。
构造方法:
public FileOutputStream(File file,boolean append) throws FileNotFoundException
import java.io.File;
import java.io.OutputStream;
import java.io.FileOutputStream;
public class OutputStreamDemo01{
public static void main(String args[]) throws Exception{
//第一步、使用File类找到一个文件
File f = new File("d:"+File.separator+"test.txt");
//第二步、通过子类实例化父类对象
OutputStream out = null;
out = new FileOutputStream(f,true);
//第三步、进行写操作
String str = "Hello World!!!";
byte b[] = str.getBytes();
for(int i=0;i<b.length;i++){
out.write(b[i]); //每次只写一个字节内容
}
//第四步、关闭输出流
out.close();
}
}
如果在文件操作中想换行的话,使用"\r\n"完成。
import java.io.File;
import java.io.OutputStream;
import java.io.FileOutputStream;
public class OutputStreamDemo01{
public static void main(String args[])throws Exception{
//第一步、使用File类找到一个文件
File f = new File("d:"+File.separator+"test.txt");
//第二步、通过子类实例化父类对象
OutputStream out = null;
out = new FileOutputStream(f,true);
//第三步、进行写操作
String str = "\r\nHello World!!!";
byte b[] = str.getBytes();
for(int i=0;i<b.length;i++){
out.write(b[i]); //每次只写一个字节内容
}
//第四步、关闭输出流
out.close();
}
}
3.3.2、字节输入流:InputStream
定义格式:
public abstract class InputStream extends Object implements Closeable
构造方法:
public FileInputStream(File file) throws FileNotFoundException
InputStream类的常用方法
No. 方法或常量 描述
1 public int available() throws IOException 可以取得输入文件的大小
2 public void close() throws IOException 关闭输入流
3 public abstract int read() throws IOException 读取内容,以数字的方式读取
4 public int read(byte[] b) throws IOException 将内容读到byte数组之中,同时返回读入的个数。
import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;
public class InputStreamDemo01{
public static void main(String[] args)throws Exception{
//1.使用File类找到一个文件
File f = new File("d:"+File.separator+"test.txt");
//2.通过子类实例化父类对象
InputStream input = null;
input = new FileInputStream(f);
//3.进行读操作
byte b[] = new byte[1024];
input.read(b);
//4.关闭输出流
input.close();
System.out.println("内容为:"+new String(b)); //将byte数组变为字符串输出
}
}
输出:
内容为:Hello World!!!Hello World!!!
Hello World!!!
此时内容虽然读取出来了,但是可以发现存在的问题。
import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;
public class InputStreamDemo01{
public static void main(String[] args)throws Exception{
//1.使用File类找到一个文件
File f = new File("d:"+File.separator+"test.txt");
//2.通过子类实例化父类对象
InputStream input = null;
input = new FileInputStream(f);
//3.进行读操作
byte b[] = new byte[1024];
int len = input.read(b);
//4.关闭输出流
input.close();
System.out.println("内容为:"+new String(b,0,len)); //将byte数组变为字符串输出
}
}
能不能根据文件的大小来开辟数组空间呢?
直接使用File类即可:public long length()
import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;
public class InputStreamDemo01{
public static void main(String[] args)throws Exception{
//1.使用File类找到一个文件
File f = new File("d:"+File.separator+"test.txt");
//2.通过子类实例化父类对象
InputStream input = null;
input = new FileInputStream(f);
//3.进行读操作
byte b[] = new byte[(int)f.length()];
int len = input.read(b);
//4.关闭输出流
input.close();
System.out.println("内容为:"+new String(b)); //将byte数组变为字符串输出
}
}
以上是直接使用byte数组的方式完成的。
现在使用public abstract int read() throws IOException读取内容
import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;
public class InputStreamDemo01{
public static void main(String[] args)throws Exception{
//1.使用File类找到一个文件
File f = new File("d:"+File.separator+"test.txt");
//2.通过子类实例化父类对象
InputStream input = null;
input = new FileInputStream(f);
//3.进行读操作
byte b[] = new byte[(int)f.length()];
for(int i=0;i<b.length;i++){
b[i] = (byte)input.read();
}
//4.关闭输出流
input.close();
System.out.println("内容为:"+new String(b)); //将byte数组变为字符串输出
}
}
以上的操作,只适合于知道输入流大小的时候,如果现在不知道大小呢?
import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;
public class InputStreamDemo01{
public static void main(String[] args)throws Exception{
//1.使用File类找到一个文件
File f = new File("d:"+File.separator+"test.txt");
//2.通过子类实例化父类对象
InputStream input = null;
input = new FileInputStream(f);
//3.进行读操作
byte b[] = new byte[1024];
int len = 0;
int temp = 0;
//以下代码颜色加深标记
while((temp = input.read())!=-1){
b[len] = (byte)temp;
len++;
}
//4.关闭输出流
input.close();
System.out.println("内容为:"+new String(b,0,len)); //将byte数组变为字符串输出
}
}
当不知道读取内容有多大的时候,就只能以读取的数据是否为-1做为读完的标志。
3.4、字符流
在程序中一个字节等于2个字节,那么java提供了Reader、Writer两个专门操作字符流的类。
字符输出流Writer
字符输入流Reader
3.4.1、字符输出流:Writer
Write本身是一个字符流的输出类,此类的定义如下:
public abstract class Writer extends Object implements Appendable,Closeable,Flushable
构造方法:
public FileWriter(File file) throws IOException
Writer类的常用方法
No. 方法或常量 描述
1 public abstract void close() throws IOException 关闭输出流
2 public void write(String str) throws IOException 将字符串输出
3 public void write(Char[] char) throws IOException 将字符数组输出
4 public abstract void flush() throws IOException 强制性清空缓存
字符流的操作比字节流操作好在一点,就是可以直接输出字符串了。不用再像之前那样进行转换操作了。
import java.io.File;
import java.io.Writer;
import java.io.FileWriter;
public class WriteDemo01{
public static void main(String args[])throws Exception{
//1.使用File类找到一个文件
File f = new File("d:"+File.separator+"test.txt");
//2.通过子类实例化父类对象
Writer out = null;
out = new FileWriter(f);
//3.进行写操作
String str = "Hello World!!!";
out.write(str);
//4.关闭输出流
out.close();
}
}
FileWriter增加追加标识
import java.io.File;
import java.io.Writer;
import java.io.FileWriter;
public class WriteDemo01{
public static void main(String args[])throws Exception{
//1.使用File类找到一个文件
File f = new File("d:"+File.separator+"test.txt");
//2.通过子类实例化父类对象
Writer out = null;
out = new FileWriter(f,true);
//3.进行写操作
String str = "\r\nLixinghuaHello World!!!";
out.write(str);
//4.关闭输出流
out.close();
}
}
3.4.2、字符输入流Reader
字符输入流:Reader
定义格式:
public abstract class Reader extends Object implements Readable,Closeable
Reader本身也是抽象类地,如果现在要从文件中读取内容,则可以直接使用FileReader子类。
FileReader的构造方法:
public FileReader(File file) throws FileNotFoundException
Reader类的常用方法:
No. 方法或常量 描述
1 public abstract void close() throws IOException 关闭输出流
2 public int read() throws IOException 读取单个字符
3 public int read(char[] cbuf) throws IOException 将内容读到字符数组之中,返回读入的长度
以字符数组的形式读取出数组
import java.io.File;
import java.io.Reader;
import java.io.FileReader;
public class ReaderDemo01{
public static void main(String args[])throws Exception{
//1.使用File类找到一个文件
File f = new File("d:"+File.separator+"test.txt");
//2.通过子类实例化父类对象
Reader input = null;
input = new FileReader(f);
//3.进行读操作
char c[] = new char[1024]; //记住这里的char是小写
int len = input.read(c);//形同FileinputStream的read()方法
//4.关闭输出流
input.close();
System.out.println("内容为:"+new String(c,0,len));
}
}
可以使用循环的方式,通过文件是否读到低的形式读取。
import java.io.File;
import java.io.Reader;
import java.io.FileReader;
public class ReaderDemo01{
public static void main(String args[]) throws Exception{
//1.使用File类找到一个文件
File f = new File("d:"+File.separator+"test.txt");
//2.通过子类实例化父类对象
Reader input = null;
input = new FileReader(f);
//3.进行读操作
char c[] = new char[1024];
int len=0;
int temp=0;
while((temp=input.read())!=-1){
c[len] = (char)temp;
len++;
}
//4.关闭输出流
input.close();
System.out.println("内容为:"+new String(c,0,len));
}
}
3.5、字节流与字符流的区别
字节流和字符流使用是非常相似的,那么除了操作代码的不同之外,还有那些不同呢?
通过一段代码来验证字符流使用到了缓存。
import java.io.File;
import java.io.OutputStream;
import java.io.FileOutputStream;
public class OutputStreamDemo01{
public static void main(String args[]) throws Exception{
//第一步、使用File类找到一个文件
File f = new File("d:"+File.separator+"test.txt");
//第二步、通过子类实例化父类对象
OutputStream out = null;
out = new FileOutputStream(f);
//第三步、进行写操作
String str = "Hello World!!!";
byte b[] = str.getBytes();
out.write(b);
//第四步、关闭输出流
//out.close();
}
}
在使用字节流操作中,即使没有关闭,最终也是可以输出的。
import java.io.File;
import java.io.Writer;
import java.io.FileWriter;
public class WriteDemo01{
public void main(String args[])throws Exception{
//1.使用File类找到一个文件
File f = new File("d:"+File.separator+"test.txt");
//2.通过子类实例化父类对象
Writer out = null;
out = new FileWriter(f,true);
//3.进行写操作
String str = "\r\nLixinghuaHello World!!!";
out.write(str);
//4.关闭输出流
//out.close();
}
}
以上的操作,没有输出任何的内容出来,也就是说,所有的内容现在都是保存在了缓冲区之中,而如果执行关闭的时候会强制性的刷新缓冲区,所以可以把内容输出。
如果现在假设,没有关闭的话,也可以手工强制性调用刷新方法。
public abstract void flush() throws IOException
import java.io.File;
import java.io.Writer;
import java.io.FileWriter;
public class WriteDemo01{
public void main(String args[])throws Exception{
//1.使用File类找到一个文件
File f = new File("d:"+File.separator+"test.txt");
//2.通过子类实例化父类对象
Writer out = null;
out = new FileWriter(f,true);
//3.进行写操作
String str = "\r\nLixinghuaHello World!!!";
out.write(str);
//4.关闭输出流
out.flush();
//out.close();
}
}
问题: 开发中是使用字节流好还是字符流好?
所有的硬盘上保存文件或是进行传输的时候都是以字节的方式进行的。包括图片也是按字节完成,而字符是只有在内存中才会形成,所以使用字节的操作是最多的。
3.6、操作范例
import java.io.* ;
public class Copy{
public static void main(String args[]){
if(args.length!=2){ // 判断是否是两个参数
System.out.println("输入的参数不正确。") ;
System.out.println("例:java Copy 源文件路径 目标文件路径") ;
System.exit(1) ; // 系统退出
}
File f1 = new File(args[0]) ; // 源文件的File对象
File f2 = new File(args[1]) ; // 目标文件的File对象
if(!f1.exists()){
System.out.println("源文件不存在!") ;
System.exit(1) ;
}
InputStream input = null ; // 准备好输入流对象,读取源文件
OutputStream out = null ; // 准备好输出流对象,写入目标文件
try{
input = new FileInputStream(f1) ;
}catch(FileNotFoundException e){
e.printStackTrace() ;
}
try{
out = new FileOutputStream(f2) ;
}catch(FileNotFoundException e){
e.printStackTrace() ;
}
if(input!=null && out!=null){ // 判断输入或输出是否准备好
int temp = 0 ;
try{
while((temp=input.read())!=-1){ // 开始拷贝
out.write(temp) ; // 边读边写
}
System.out.println("拷贝完成!") ;
}catch(IOException e){
e.printStackTrace() ;
System.out.println("拷贝失败!") ;
}
try{
input.close() ; // 关闭
out.close() ; // 关闭
}catch(IOException e){
e.printStackTrace() ;
}
}
}
}