java byte 与操作_java的IO操作:字节流与字符流操作

流的概念

5ba480f555b9ef7ed514e1f07449a5f5.png

程序中的输入输出都是以流形式,流中保存的实际上都是字节文件。

字节流与字符流

字节流的操作:

1)输入:inputStream,

2)输出:outPutStream;

字符流的操作:

1)输入主要使用:write类。

2)输出主要使用:reader类。

内容操作就四个类。

操作流程:

02e527d4fa2d582e6bb9972c25ae79d5.png

使用File类操作一定有路径问题,注意分隔符:

实际上四个操作类都是抽象类(区别接口,抽象类的成员都是抽象,并且只能单继承,接口可以有全局变量,但是接口可以多继承)

IO操作属于资源操作,对于资源操作,操作最后必须关闭,否则有可能出现未知错误。

字节流

字节流主要操作byte类型数据,以byte数组为准,注意操作类为字节输出流:outputStream,字节输入流:inputStream,类。

Byte是字节,肯定使用字节流操作,所有的数据基本都可以使用byte数组表示出来。

OutputStream类

字节输出流的最大父类:定义如下:

public abstract class OutputStream extends Object implements Closeable ,Flushable;

Closeable表示可以关闭的操作,因为程序最后要关闭。

Flushable表示刷新,清空内存中数据。

此类是抽象类,所以要想使用此类,必须要通过子类实例化父类对象。

那么要操作的是一个文件,则可以使用FileOutputStream类,通过向上转型之后,可以为OutputStream实例化。

FileOutputStream构造方法:

public FileOutputStream( File file) throws FielNotFoundException

可见FileOutputStream需要操作File类的对象,并且有异常处理。

importjava.io.File ;importjava.io.OutputStream ;importjava.io.FileOutputStream ;public classOutputStreamDemo01{public static void main(String args[]) throws Exception{ // 异常抛出,不处理// 第1步、使用File类找到一个文件

File f= new File("d:" + File.separator + "test.txt") ; //声明File对象//第2步、通过子类实例化父类对象,注意下面是通过向上转型,实例化父类对象。

OutputStream out = null ; //准备好一个输出的对象

out = new FileOutputStream(f) ; // 通过对象多态性,进行实例化//第3步、进行写操作

String str = "Hello World!!!" ; //准备一个字符串

byte b[] =str.getBytes() ; //只能输出byte数组,所以将字符串变为byte数组

out.write(b) ; // 将内容输出,保存文件//第4步、关闭输出流

out.close() ; // 关闭输出流

}

};

1)因为FielOutputStream有异常,wire()方法也有异常,为了节省操作,可以在主方法抛出异常,不处理

2)输出字符串:可以先用方法 getBytes()一次性读取字符串到字节数组中,然后再把字节数组输出。

3)OutputStream的实例对象调用write(byte []b)方法,把数组输出。

4)在操作时候,如果文件本身不存在,就会为用户自动创建新文件。

在操作输出流的时候也可以使用write(int i)的方式写出数据。

importjava.io.File ;importjava.io.OutputStream ;importjava.io.FileOutputStream ;public classOutputStreamDemo02{public static void main(String args[]) throws Exception{ //异常抛出,不处理//第1步、使用File类找到一个文件

File f= new File("d:" + File.separator + "test.txt") ; //声明File对象//第2步、通过子类实例化父类对象

OutputStream out = null ; //准备好一个输出的对象

out = new FileOutputStream(f) ; //通过对象多态性,进行实例化//第3步、进行写操作

String str = "Hello World!!!" ; //准备一个字符串

byte b[] = str.getBytes() ; //只能输出byte数组,所以将字符串变为byte数组

for(int i=0;i

out.write(b[i]) ; // 每次只写入一个内容

}//第4步、关闭输出流

out.close() ; //关闭输出流

}

};

以上操作在输入数据后,以前的数据不存在。因为在IO操作中默认是将其覆盖。如果要想执行追加功能,必须设置追加操作。

找到FileOutputStream类:

public FileOutputStream(File file,bool append)throws FileNotFoundException

在构造方法中,如果append的值设为true,表示在文件的末尾追加。

importjava.io.File ;importjava.io.OutputStream ;importjava.io.FileOutputStream ;public classOutputStreamDemo03{public static void main(String args[]) throws Exception{ //异常抛出,不处理//第1步、使用File类找到一个文件

File f= new File("d:" + File.separator + "test.txt") ; //声明File对象//第2步、通过子类实例化父类对象

OutputStream out = null ; //准备好一个输出的对象

out = new FileOutputStream(f,true) ; // 此处表示在文件末尾追加内容//第3步、进行写操作

String str = "Hello World!!!" ; //准备一个字符串

byte b[] = str.getBytes() ; //只能输出byte数组,所以将字符串变为byte数组

for(int i=0;i

out.write(b[i]) ; //每次只写入一个内容

}//第4步、关闭输出流

out.close() ; //关闭输出流

}

};

上面是在末尾追加,没换行,如果要换行,在要添加的文子前面,使用“\r\n”完成。

如:String str="\r\n在这里追加";

packageThread1;importjava.io.File;importjava.io.FileOutputStream;importjava.io.OutputStream;public classdemo1 {//所有的异常直接抛出,程序中不再进行处理

public static void main(String args[]) throwsException{

File f=new File("D:\\outputStream.txt");

OutputStream out=new FileOutputStream(f,true);

String str="\r\n在这里追加";byte[]b=str.getBytes();

out.write(b);

out.close();

}

};

运行结果:

d54ebf2d35b0f4c69b12d46935a97db0.png

字节输入流InputStream

定义:public abstract class inputStream extends Object implements Clossablle;

与OutputStream类似,也是抽象类,必须依靠子类,如果从文件读取,肯定是FileInputStream;

构造方法:

public FileInputStream(File file) throws FileNotFoundException

要处理异常,参数需要File对象,向上转型。

7c6e1d1e631432233e7a98e3e6d7041b.png

以read(byte[] b)形式读取到数组中。

packageThread1;importjava.io.File;importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.InputStream;importjava.io.OutputStream;public classdemo1 {public static void main(String args[]) throws Exception{ //异常抛出,不处理//第1步、使用File类找到一个文件

File f= new File("d:" + File.separator + "outputStream.txt") ; //声明File对象//第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 moto在这里追加

在这里追加

1)定义一个byte类型的数组对象,用于读取从File类的指定文件的内容。

2)InputStream通过子类,利用多态性,向上转型,实例化对象。

3)InputStream对象调用read(byte b[])方法,把File中的内容读取给b[]数组。

此刻虽然读取出来了,但是存在问题,文件没有这么大,但是开辟了这么大空间,浪费内存。

能不能根据文件大小开辟数组空间?

如果要想知道文件大小,直接使用File类即可。f.length()方法获得文件的大小,注意同时要类型转换。

packageThread1;importjava.io.File;importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.InputStream;importjava.io.OutputStream;public classdemo1 {public static void main(String args[]) throws Exception{ //异常抛出,不处理//第1步、使用File类找到一个文件

File f= new File("d:" + File.separator + "outputStream.txt") ; //声明File对象//第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("读入数据的长度:" +len) ;

System.out.println("内容为:" +new String(b)) ; // 把byte数组变为字符串输出

}

};

运行结果:

读入数据的长度:32内容为:hello moto在这里追加

在这里追加

new String(b),因为读取的时候是从字符类型先转化成byte类型,所以输出要转换成String类型。

这里其实是String类的构造方法,相当于实例化了一个String类的对象,生成了一个String 变量。

以上是利用byte数组形式读取文件。read(byte [] b)

另外一个常用的读取方法read();字节一个个的读

abstract intread()

从输入流中读取数据的下一个字节

注意:read()方法的返回结果是int类型,所以对于字节需要转化类型,

package类集;importjava.io.File ;importjava.io.InputStream ;importjava.io.FileInputStream ;public classInputStreamDemo04{public static void main(String args[]) throws Exception{ //异常抛出,不处理//第1步、使用File类找到一个文件

File f= new File("d:" + File.separator + "test.txt") ; //声明File对象//第2步、通过子类实例化父类对象

InputStream input = null ; //准备好一个输入的对象

input = new FileInputStream(f) ; //通过对象多态性,进行实例化//第3步、进行读操作

byte b[] = new byte[(int)f.length()] ; // 数组大小由文件决定

for(int i=0;i

b[i]= (byte)input.read() ; // 读取内容

}//第4步、关闭输出流

input.close() ; //关闭输出流\

System.out.println("内容为:" + new String(b)) ; //把byte数组变为字符串输出

}

};

以上操作只适合知道输入流大小的时候,如果现在不知道大小呢?

package类集;importjava.io.File ;importjava.io.InputStream ;importjava.io.FileInputStream ;public classInputStreamDemo05{public static void main(String args[]) throws Exception{ //异常抛出,不处理//第1步、使用File类找到一个文件

File f= new File("d:" + File.separator + "te.text") ; //声明File对象//第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){  //这里先把字节读取出来,赋值给temp,如果temp不等于-1,表示还有内容,文件没有读完

b[len] = (byte)temp ;

len++;

}//第4步、关闭输出流

input.close() ; //关闭输出流\

System.out.println("内容为:" + new String(b,0,len)) ; //把byte数组变为字符串输出

}

};

当不知道读取的内容有多大的时候,就只能通过以读取的内容是否为-1为读完的标志。

这个是常用的字节流操作方法:

InputStream input = null ; //准备好一个输入的对象

input = new FileInputStream(f) ; //通过对象多态性,进行实例化//第3步、进行读操作

byte b[] = new byte[1024] ; //数组大小由文件决定

int len = 0;int temp = 0 ; //接收每一个读取进来的数据

while((temp=input.read())!=-1){  //这里先把字节读取出来,赋值给temp,如果temp不等于-1,表示还有内容,文件没有读完

b[len] = (byte)temp ;

len++;

}

字符流操作

字符输入流:Writer类

字符输出流:Reader类。

Writer类

常用方法:

e84edf7e79f907dbe0ce6e9867656d82.png

字符流比字节流操作好在一点,就是可以直接输出字符串了。不用跟之前一样进行转换操作。

代码实例:

importjava.io.File ;importjava.io.Writer ;importjava.io.FileWriter ;public classWriterDemo01{public static void main(String args[]) throws Exception{ //异常抛出,不处理//第1步、使用File类找到一个文件

File f= new File("d:" + File.separator + "test.txt") ; //声明File对象//第2步、通过子类实例化父类对象

Writer out = null ; //准备好一个输出的对象

out= new FileWriter(f) ; //通过对象多态性,进行实例化//第3步、进行写操作

Stringstr = "Hello World!!!" ; //准备一个字符串,注意,这里不用跟字节流操作一样转换成Byte数组类型。

out.write(str) ; // 将内容输出,保存文件//第4步、关闭输出流

out.close() ; //关闭输出流

}

};

使用字符流默认情况下依然覆盖已有文件,要想追加,则在FileWriter上加一个追加标记即可。

package类集;importjava.io.File ;importjava.io.Writer ;importjava.io.FileWriter ;public classWriterDemo02{public static void main(String args[]) throws Exception{ //异常抛出,不处理//第1步、使用File类找到一个文件

File f= new File("d:" + File.separator + "te.text") ; //声明File对象//第2步、通过子类实例化父类对象

Writer out = null ; //准备好一个输出的对象

out = new FileWriter(f,true) ; //通过对象多态性,进行实例化//第3步、进行写操作

String str = "\r\nLIXINGHUA\r\nHello World!!!" ; //准备一个字符串

out.write(str) ; //将内容输出,保存文件//第4步、关闭输出流

out.close() ; //关闭输出流

}

};

字符输入流:Reader()

常用方法

60ae95bf7b390d77c75263a19146c6a7.png

以字符数组形式读取出数组。

package类集;importjava.io.File ;importjava.io.Reader ;importjava.io.FileReader ;public classReaderDemo01{public static void main(String args[]) throws Exception{ //异常抛出,不处理//第1步、使用File类找到一个文件

File f= new File("d:" + File.separator + "te.text") ; //声明File对象//第2步、通过子类实例化父类对象

Reader input = null ; //准备好一个输入的对象

input = new FileReader(f); //通过对象多态性,进行实例化//第3步、进行读操作

char c[] = new char[1024] ; //所有的内容都读到此数组之中

int len = input.read(c) ; // 读取内容//第4步、关闭输出流

input.close() ; //关闭输出流

System.out.println("内容为:" + new String(c,0,len)) ; //把字符数组变为字符串输出

}

};

输出结果:

内容为:hello fsdfsdfshello

LIXINGHUA

Hello World!!!

也可以以循环方式,通过文件是否读到底判断。

importjava.io.File ;importjava.io.Reader ;importjava.io.FileReader ;public classReaderDemo02{public static void main(String args[]) throws Exception{ //异常抛出,不处理//第1步、使用File类找到一个文件

File f= new File("d:" + File.separator + "test.txt") ; //声明File对象//第2步、通过子类实例化父类对象

Reader input = null ; //准备好一个输入的对象

input= new FileReader(f) ; //通过对象多态性,进行实例化//第3步、进行读操作

char c[] = new char[1024] ; // 所有的内容都读到此数组之中

int temp = 0 ; // 接收每一个内容

int len = 0 ; // 读取内容

while((temp=input.read())!=-1){//如果不是-1就表示还有内容,可以继续读取

c[len] = (char)temp ;

len++;

}//第4步、关闭输出流

input.close() ; //关闭输出流

System.out.println("内容为:" + new String(c,0,len)) ; //把字符数组变为字符串输出

}

};

字符流与字节流的区别

字节和字符使用非常相似,有哪些不同呢?

1,字节流不会用到缓存,字符流会用到缓存。

6516043a82a815f3b6d7ac64901c0b28.png

通过代码验证字节流使用到了缓存。

字节流操作:

package类集;importjava.io.File ;importjava.io.OutputStream ;importjava.io.FileOutputStream ;public classOutputStreamDemo05{public static void main(String args[]) throws Exception{ //异常抛出,不处理//第1步、使用File类找到一个文件

File f= new File("d:" + File.separator + "te.text") ; //声明File对象//第2步、通过子类实例化父类对象

OutputStream out = null ; //准备好一个输出的对象

out = new FileOutputStream(f) ; //实例化//第3步、进行写操作

String str = "Hello World!!!" ; //准备一个字符串

byte b[] = str.getBytes() ; //只能输出byte数组,所以将字符串变为byte数组

out.write(b) ; //写入数据//第4步、关闭输出流// out.close() ; // 关闭输出流

}

};

结果在指定目录成功输出内容。

在使用字节流操作中,即使没有关闭,最终也可以输出。

字符流操作:

package类集;importjava.io.File ;importjava.io.Writer ;importjava.io.FileWriter ;public classWriterDemo03{public static void main(String args[]) throws Exception{ //异常抛出,不处理//第1步、使用File类找到一个文件

File f= new File("d:" + File.separator + "te.text") ; //声明File对象//第2步、通过子类实例化父类对象

Writer out = null ; //准备好一个输出的对象

out = new FileWriter(f) ; //通过对象多态性,进行实例化//第3步、进行写操作

String str = "Hello World!!!" ; //准备一个字符串

out.write(str) ; //将内容输出,保存文件//第4步、关闭输出流// out.close() ; // 此时,没有关闭

}

};

运行结果:为空。

以上操作没有输出任何内容,所有的内容现在保存在缓冲区当中,如果执行关闭的时候,会强制性的刷新缓冲区,所以可以把内容输出。

abstract voidclose()

关闭此流,但要先刷新它。

如果现在没有关闭的话,也可以强制调用刷新方法。

abstract voidflush()

刷新该流的缓冲。

package类集;importjava.io.File ;importjava.io.Writer ;importjava.io.FileWriter ;public classWriterDemo03{public static void main(String args[]) throws Exception{ //异常抛出,不处理//第1步、使用File类找到一个文件

File f= new File("d:" + File.separator + "te.text") ; //声明File对象//第2步、通过子类实例化父类对象

Writer out = null ; //准备好一个输出的对象

out = new FileWriter(f) ; //通过对象多态性,进行实例化//第3步、进行写操作

String str = "Hello World!!!" ; //准备一个字符串

out.write(str) ; // 将内容输出,保存文件//第4步、关闭输出流

out.flush() ; // 强制性清空缓冲区中的内容//out.close() ;

}

};

此时成功将内容写入指定路径下文件中。

开发中是使用字节流好还是字符流好。

在所有的硬盘中保存文件或进行传输的时候,都是以字节的方式进行的,包括图片,视频等多媒体也是以字节进行。

而字符是只有在内存中才会形成的,所以使用字节的时候是最多的。

操作范例:文件拷贝

操作的时候可以按照如下格式进行:

java Copy 源文件 目标文件

如果要采用以上的格式,则肯定要使用初始化参数的形式,输入两个路径。所以此时必须对输入的参数个数进行验证,判断其是否为2,

是使用字节流还是字符流呢,肯定使用字节流,因为万一拷贝的是图片呢?

要完成拷贝程序,有两种方式:

实现一,将源文件中内容全部读取进来,之后一次性写入到目标文件。

实现二,边读边写。

很明显第二种方式更好。

package类集;import java.io.*;public classCopy{public static voidmain(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= newFileInputStream(f1) ;

}catch(FileNotFoundException e){

e.printStackTrace() ;

}try{

out= newFileOutputStream(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() ;

}

}

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值