java io编程_Java_IO编程

如果要进行文件内容的操作,必须依靠数据流完成,而数据流分为两种:

字节流:InpuStream(字节输入流)、OutputStream(字节输出流)

字符流:Reader(字符输入流)、Writer(字符输出流)

字符比字节处理的多,但使用哪个,基本流程都一样

范例:

创建File类对象,主要是指明要操作的文件路径

通过字节流或字符流的子类为父类实例化

进行文件的读写操作

关闭数据流(close())

字节输出流:OutputStream

字节输出流主要以byte数据为主

输出单个字节:public abstract void write(int b) throws IOException

输出全部字节数组:public void write(byte[] b) throws IOException

输出部分字节数组:public void write(byte[] b, int off, int len) throws IOException  //重点

OutputStream是抽象类,文件的输出操作需要子类FileOutputStream,此类有两个常用构造

构造方法:public FileOutputStream(File file) throws FileNotFoundException  新内容覆盖文件

构造方法:public FileOutputStream(File file, boolean append) throws FileNotFoundException  追加文件内容

范例:实现文件的输出(往文件里写内容)

import java.io.File;

import java.io.FileOutputStream;

import java.io.OutputStream;public classHello{public static voidmain(String[] args) throws Exception {//第一步:定义要输出文件的File类对象

File file = new File("F:" + File.separator + "hello" + File.separator + "Test.txt");//输出信息的时候文件可以不存在,目录必须存在

if(!file.getParentFile().exists()) { //父路径不存在

file.getParentFile().mkdirs(); //创建父路径

}//第二部:利用OutputStream的子类为父类实例化

OutputStream output = newFileOutputStream(file);//第三步:输出文字信息

String msg = "******"; //字符串//为了方便输出,需要将字符串变为字节数组

byte data[] = msg.getBytes(); //变为了字节数组

output.write(data); //输出数据 , 创建了test.TXT,并写入了*****数据

output.close();

}

}

实现只输出部分内容:

import java.io.File;

import java.io.FileOutputStream;

import java.io.OutputStream;public classHello{public static voidmain(String[] args) throws Exception {//第一步:定义要输出文件的File类对象

File file = new File("F:" + File.separator + "hello" + File.separator + "Test.txt");//输出信息的时候文件可以不存在,目录必须存在

if(!file.getParentFile().exists()) { //父路径不存在

file.getParentFile().mkdirs(); //创建父路径

}//第二部:利用OutputStream的子类为父类实例化

OutputStream output = newFileOutputStream(file);//第三步:输出文字信息

String msg = "adfasdfadsfasdfasdfsadfasdf"; //字符串//为了方便输出,需要将字符串变为字节数组

byte data[] = msg.getBytes(); //变为了字节数组

output.write(data, 0, 10); //输出数据 , 从0开始输出10个

output.close();

}

使用循环的方式单个字节的输出

import java.io.File;

import java.io.FileOutputStream;

import java.io.OutputStream;public classHello{public static voidmain(String[] args) throws Exception {//第一步:定义要输出文件的File类对象

File file = new File("F:" + File.separator + "hello" + File.separator + "Test.txt");//输出信息的时候文件可以不存在,目录必须存在

if(!file.getParentFile().exists()) { //父路径不存在

file.getParentFile().mkdirs(); //创建父路径

}//第二部:利用OutputStream的子类为父类实例化

OutputStream output = newFileOutputStream(file);//第三步:输出文字信息

String msg = "adfasdfadsfasdfasdfsadfasdf"; //字符串//为了方便输出,需要将字符串变为字节数组

byte data[] = msg.getBytes(); //变为了字节数组

for(int x = 0; x < data.length; x++) {

output.write(data[x]);//输出数据

}

output.close();

}

}

现在发现每当执行完成后之前的内容都被覆盖了,所以也可以进行数据的追加操作:

范例:追加数据(加入新数据 之前的数据不变 ),第二部加个true

import java.io.File;

import java.io.FileOutputStream;

import java.io.OutputStream;public classHello{public static voidmain(String[] args) throws Exception {//第一步:定义要输出文件的File类对象

File file = new File("F:" + File.separator + "hello" + File.separator + "Test.txt");//输出信息的时候文件可以不存在,目录必须存在

if(!file.getParentFile().exists()) { //父路径不存在

file.getParentFile().mkdirs(); //创建父路径

}//第二部:利用OutputStream的子类为父类实例化

OutputStream output = new FileOutputStream(file, true); //此处为true,表示追加操作//第三步:输出文字信息

String msg = "111adfasdfadsfasdfasdfsadfasdf"; //字符串//为了方便输出,需要将字符串变为字节数组

byte data[] = msg.getBytes(); //变为了字节数组

output.write(data); //输出数据

output.close();

}

}

进行换行操作使用“\r\n”

字节输入流InputStream

可以实现数据读取

三个数据读取方法:

1. 读取单个字节:public abstract int read() throws IOException  //每次执行此方法将读取单个字节的数据,如果已经去取完成了,没数据了,那么最后返回的是-1

2. 读取数据到字节数组中:public int read(byte[]b) throws IOException  //每次讲数据读取到数组中,那么会返回一个读取长度的数据,如果没有数据,返回长度为-1,要考虑两种情况:1.要读取的内容大于开辟数组的内容,长度就是整个数组的长度  2.要读取的内容小于开辟的数组内容,长度就是全部最后的内容长度,数组装不满

3. 读取 部分内容到字节数组:public int read(byte[]b,int off, int len) throws IOException //每次读取内容到部分字节数组,只允许读取满限制的数组的字节个数,此方法依然返回读取的长度。

InputStream是抽象类,所以要进行文件的读取使用FileInputStream子类,子类定义的构造方法:public FileInputStream(File file) throws FileNotFoundException

范例:实现从txt的数据读取

import java.io.File;

import java.io.FileInputStream;

import java.io.InputStream;public classHello{public static voidmain(String[] args) throws Exception {//第一步:定义要输出文件的File类对象

File file = new File("F:" + File.separator + "hello" + File.separator + "Test.txt");//第二步:实例化InputStream类对象

InputStream input = newFileInputStream(file);//第三步:实现数据读取操作

byte data[] = new byte[1024];int len = input.read(data); //将数据读取到数组中

System.out.println("读取的内容:【" + new String(data,0,len) +"】");//第四步:关闭输入流

input.close();

}

}

read()方法可以实现单个字节数据读取操作,用此方法实现单个字节数据的读取

范例 :读取单个字节”

import java.io.File;

import java.io.FileInputStream;

import java.io.InputStream;public classHello{public static voidmain(String[] args) throws Exception {

File file= new File("F:" + File.separator + "hello" + File.separator + "Test.txt");

InputStream input= newFileInputStream(file);byte data[] = new byte[1024];int foot = 0; //控制保存的角标索引

int temp = 0; //接收每次保存的数据

do{

temp= (byte)input.read(); //读取出来的数据保存到字节数组中

if(temp != -1) { //现在有数据

data[foot ++] = (byte) temp;

}

}while(temp != -1); //表示后面可能还有数据

System.out.println("读取的内容:【" + new String(data,0,foot) +"】");

input.close();

}

}

以上使用了do...while,实际开发中都用while:

import java.io.File;

import java.io.FileInputStream;

import java.io.InputStream;public classHello{public static voidmain(String[] args) throws Exception {

File file= new File("F:" + File.separator + "hello" + File.separator + "Test.txt");

InputStream input= newFileInputStream(file);byte data[] = new byte[1024];int foot = 0; //控制保存的角标索引

int temp = 0; //接收每次保存的数据

while((temp = input.read())!= -1) {

data[foot++] = (byte)temp;

}

System.out.println("读取的内容:【" + new String(data,0,foot) +"】");

input.close();

}

}

字符输出流:Writer

Writer是进行字符输出操作的抽象类

之所以提供一个Writer类,是因为这个类的输出方法有一个特别好用的:

输出字符串:public void write(String str) throws IOException   //重点

范例:使用Writer输出数据

import java.io.File;

import java.io.FileWriter;

import java.io.Writer;public classHello{public static voidmain(String[] args) throws Exception {

File file= new File("F:" + File.separator + "hello" + File.separator + "Test.txt");if(file.getParentFile().exists()) {

file.getParentFile().mkdirs();

}

Writerout = newFileWriter(file);

String data= "测试数据测试数据测试数据测试数据测试数据";out.write(data); //直接输出字符串

out.close();

}

}

若要追加增加数据,之前的不变:

Writer out = new FileWriter(file, true);

虽然Wirter类提供字符数组的输出操作能力,但本质上讲使用Writer类就意味着要执行字符串的直接输出。

字符输入流:Reader

数据读取:public int read(char[] cbuf) throws IOException

范例:读取数据

import java.io.File;

import java.io.FileReader;

import java.io.Reader;public classHello{public static voidmain(String[] args) throws Exception {

File file= new File("F:" + File.separator + "hello" + File.separator + "Test.txt");if(file.exists()) {

Readerin = newFileReader(file);char data[] = new char[1024];int len = in.read(data); //向字符数组中保存数据,返回长度

System.out.println(new String(data, 0, len));in.close();

}

}

}

Reader与InputStream类相比除了数据类型的差别之外,操作上没有优势

字节流与字符流的区别

这两种流的区别就好比数据库中的BLOB与CLOB区别

CLOB保存大文本数据,都是字符数据

BLOB保存二进制数据,例如:电影、图片、文字,都是字节数据

通过任何终端(网络、文件)读取或者输出的数据都一定是字节,但字符是通过内存处理后的数据。

字符输入:字符输入的时候字节(磁盘)自动转换为字符(内存)

字符输出:字符(内存)自动转换为字节(磁盘)

在利用字符流输出的时候,所有的内容实际上都只是输出到了缓冲区中(内存)。在使用close()关闭的时候会将缓冲区的数据输出,如果不关闭就不发进行输出,此时可以利用flush()进行强制刷新

字符使用到了缓冲区,而字节没有使用到缓冲区。如果处理中文使用字符流,其他任何数据都是用字节流。

综合案例:文件拷贝

是模拟dos系统中的copy命令完成

编写一个文件拷贝程序,可实现任意文件拷贝操作,通过初始化参数输入拷贝的源文件以及拷贝的目标文件路径,本程序暂不考虑类的设计。

dos拷贝命令:“copy 路径1 路径2”

两种实现思路:

思路一:开辟一个数组,将需拷贝的内容读取到数组之中,而后一次性输出到目标路径中

思路二:采用边读边写的方式进行拷贝,不是一次性读取

第一种方式如果文件小没问题,5M左右。如果文件大,基本内存就被沾满了,

范例:初期实现

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.InputStream;

import java.io.OutputStream;public classCopyDemo {public static voidmain(String[] args) throws Exception {if(args.length != 2) { //参数内容必须是两个,一个源文件路径一个目标文件路径

System.out.println("错误的命令,格式为:CopyDemo 源文件路径 目标文件路径。");

System.exit(1); //退出程序

}//接下来验证源文件是否存在

File inFile = new File(args[0]);if(!inFile.exists()) {

System.out.println("路径错误,请确定源文件路径正确。");

System.exit(1);

}//如果拷贝的目标文件存在,则也不应该进行拷贝

File outFile = new File(args[1]);if(outFile.exists()) { //目标文件已经存在

System.out.println("拷贝的路径文件已经存在,请更换路径。");

System.exit(1);

}long start =System.currentTimeMillis();

InputStreamin = newFileInputStream(inFile);

OutputStreamout = newFileOutputStream(outFile);

copy(in,out); //开始文件拷贝

in.close();out.close();long end =System.currentTimeMillis();

System.out.println("花费的时间:" + (end -start) );

}public static voidcopy(InputStream input, OutputStream output) throws Exception {int temp = 0; //保存每次读取的字节量

while((temp = input.read()) != -1 ) { //每次读取一个字节

output.write(temp);

}

}

}

要先执行以下再输入路径。此种方法只能复制很小的文件。

用数组来提升拷贝性能,可以将数据读取到数组中,而后一次性将数组输出。

修改拷贝方法:

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.InputStream;

import java.io.OutputStream;public classCopyDemo {public static voidmain(String[] args) throws Exception {if(args.length != 2) { //参数内容必须是两个,一个源文件路径一个目标文件路径

System.out.println("错误的命令,格式为:CopyDemo 源文件路径 目标文件路径。");

System.exit(1); //退出程序

}//接下来验证源文件是否存在

File inFile = new File(args[0]);if(!inFile.exists()) {

System.out.println("路径错误,请确定源文件路径正确。");

System.exit(1);

}//如果拷贝的目标文件存在,则也不应该进行拷贝

File outFile = new File(args[1]);if(outFile.exists()) { //目标文件已经存在

System.out.println("拷贝的路径文件已经存在,请更换路径。");

System.exit(1);

}long start =System.currentTimeMillis();

InputStreamin = newFileInputStream(inFile);

OutputStreamout = newFileOutputStream(outFile);

copy(in,out); //开始文件拷贝

in.close();out.close();long end =System.currentTimeMillis();

System.out.println("花费的时间:" + (end -start) );

}public static voidcopy(InputStream input, OutputStream output) throws Exception {int temp = 0; //保存每次读取的字节量

byte data[] = new byte[2048];//数据向数组中读取

while((temp = input.read(data)) != -1 ) { //每次读取一个字节

output.write(data, 0 , temp); //输出数组

}

}

}

特别快。

对于File、InputStream、OutputStream最直接操作就体现在本程序中

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值