Java 基础学习 IO 之 字节流 ( OutputStream、InputStream)

1 字节输出流:OutputStream

1.1 基本概念

  1. 在程序中所有的数据都是以流的方式传输或保存的。

  2. 在 Java 中 IO 操作的主要流程:
    (1)使用 File 类打开一个文件。
    (2)通过字节流或字符流的子类指定输出位置
    (3)进行读/写操作。
    (4)关闭输入输出。

  3. 字节流主要是操作 byte 类型数据,以 byte 数组为准,主要操作类就是 字节输出流:OutputStream 和 字节输入流: InputStream。

  4. OutputStream 是一个抽象类,如果想要使用此类的话,首先必须通过子类实列化对象。如果现在要操作的是一个文件,则可以使用 FileOutputStream 类,通过向上转型之后,可以为 OutputStream 实列化。

1.2 字节输出流基本操作

1. 向文件写入数据
实列1代码:
package self.learn.javaio;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class IoPractices {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		// 向文件中写入字符串
		//String path = "D:"+File.separator+"SVN"+File.separator+"outPutStream.txt";
		String path = "D:\\SVN\\outPutStream.txt";
		// 1. 使用 File 类找到一个文件
		File file = new File(path);
		// 2. 通过子类实例化父类对象
		OutputStream output = null;
		output = new FileOutputStream(file);  // 通过对象多态性进行实例化
		// 3. 进行写操作
		String str = "Hello OutputStream!"; // 准备一个字符串
		// OutputStream 主要是操作 byte 类数据,所以把字符串转换为 byte 数组
		byte b[] = str.getBytes();        
		output.write(b);   // 将内容输出,保存到文件
		// 将内容一个字节一个字节写入文件
//		for(int i = 0; i < b.length; i++) {
//			output.write(b[i]);
//		}
		// 第四步:关闭输出流
		output.close();		
	}

}

运行结果截图:

在这里插入图片描述

如果在操作之前文件不存在,则操作后自动创建并写入内容。
实列2代码(通过循环将内容一个字节一个字节写入文件):
package self.learn.javaio;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class IoPractices {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		// 向文件中写入字符串
		//String path = "D:"+File.separator+"SVN"+File.separator+"outPutStream.txt";
		String path = "D:\\SVN\\outPutStream.txt";
		// 1. 使用 File 类找到一个文件
		File file = new File(path);
		// 2. 通过子类实例化父类对象
		OutputStream output = null;
		output = new FileOutputStream(file);  // 通过对象多态性进行实例化
		// 3. 进行写操作
		String str = "Hello OutputStream! Java 真好!"; // 准备一个字符串
		// OutputStream 主要是操作 byte 类数据,所以把字符串转换为 byte 数组
		byte b[] = str.getBytes();        
		//output.write(b);   // 将内容输出,保存到文件
		//通过循环将内容一个字节一个字节写入文件
		for(int i = 0; i < b.length; i++) {
			output.write(b[i]);
		}
		// 第四步:关闭输出流
		output.close();		
	}

}

运行结果截图:

在这里插入图片描述

2. 追加新内容

  之前所有的操作,如果重新执行程序,则肯定会覆盖文件中的已有内容,那么此时可以通过 FileOutputSream 类的另一种构造方法进行实例化,向文件中追加内容。

实列3代码:
package self.learn.javaio;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class IoPractices {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		// 向文件中写入字符串
		//String path = "D:"+File.separator+"SVN"+File.separator+"outPutStream.txt";
		String path = "D:\\SVN\\outPutStream.txt";
		// 1. 使用 File 类找到一个文件
		File file = new File(path);
		// 2. 通过子类实例化父类对象
		OutputStream output = null;
		// 通过对象多态性进行实例化, 设置为 true 表示在文件末尾追加内容
		output = new FileOutputStream(file,true);  
		// 3. 进行写操作
		String str = "我要追加内容!"; // 准备一个字符串
		// OutputStream 主要是操作 byte 类数据,所以把字符串转换为 byte 数组
		byte b[] = str.getBytes();        
		//output.write(b);   // 将内容输出,保存到文件
		//通过循环将内容一个字节一个字节写入文件
		for(int i = 0; i < b.length; i++) {
			output.write(b[i]);
		}
		// 第四步:关闭输出流
		output.close();		
	}
}

运行结果截图:

在这里插入图片描述

知识小补充:增加换行(使用 “\r\n” 增加换行)
实列4代码:
package self.learn.javaio;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class IoPractices {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		// 向文件中写入字符串
		//String path = "D:"+File.separator+"SVN"+File.separator+"outPutStream.txt";
		String path = "D:\\SVN\\outPutStream.txt";
		// 1. 使用 File 类找到一个文件
		File file = new File(path);
		// 2. 通过子类实例化父类对象
		OutputStream output = null;
		// 通过对象多态性进行实例化, 设置为 true 表示在文件末尾追加内容
		output = new FileOutputStream(file,true);  
		// 3. 进行写操作 " \r ":归位 、" \n ":换行
		// 使用 "\r\n" 增加换行
		String str = "\r\n 不好意思我要再这里换行!"; // 准备一个字符串
		// OutputStream 主要是操作 byte 类数据,所以把字符串转换为 byte 数组
		byte b[] = str.getBytes();        
		//output.write(b);   // 将内容输出,保存到文件
		//通过循环将内容一个字节一个字节写入文件
		for(int i = 0; i < b.length; i++) {
			output.write(b[i]);
		}
		// 第四步:关闭输出流
		output.close();		
	}
}
运行结果截图:

在这里插入图片描述
提示: 使用字节输出流 OutputStream ,当文件不存在时在操作后会自动创建。

2 字节输入流:InputStream

2.1 基本概念

  1. 通过 InputStream 类从文件中把内容读取过来。 InputStream 本身也是一个抽象类,必须依靠其子类,如果现在是从文件中读取进来,子类肯定是 FileInputStream 类。

2.2 基本操作

1. 读取文件内容
实列5代码:
package self.learn.javaio;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class IoPractices {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		// 向文件中写入字符串
		//String path = "D:"+File.separator+"SVN"+File.separator+"outPutStream.txt";
		String path = "D:\\SVN\\outPutStream.txt";
		// 1. 使用 File 类找到一个文件
		File file = new File(path);
		// 2. 通过子类实例化父类对象
		InputStream input = null;
		// 通过对象多态性进行实例化
		input = new FileInputStream(file); 
		// 3. 进行读操作
		byte b[] = new byte[1024];
	    input.read(b); // 把内容读取出,内容读到 byte 数组中        	
	    input.close();	
	    // 把数组变为字符串输出
	    System.out.println("内容为:\n"+new String(b));
	}
}

运行结果截图:在这里插入图片描述
知识小补充:

  开辟 byte 数组大小为1024 字节,而实际内容只有 94 字节,也就是说存在了 930 个字节的空白空间,在将 byte 转换为字符串的时候也将这 930 个字节的空间空间转换为字符串了

实列6代码:
package self.learn.javaio;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class IoPractices {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		// 向文件中写入字符串
		//String path = "D:"+File.separator+"SVN"+File.separator+"outPutStream.txt";
		String path = "D:\\SVN\\outPutStream.txt";
		// 1. 使用 File 类找到一个文件
		File file = new File(path);
		// 2. 通过子类实例化父类对象
		InputStream input = null;
		// 通过对象多态性进行实例化
		input = new FileInputStream(file); 
		// 3. 进行读操作
		byte b[] = new byte[1024];
	    int len = input.read(b); // 把内容读取出,内容读到 byte 数组中        	
	    input.close();	
	    System.out.println("读取过来的内容有:"+len+" 个字节");
	    // 把数组变为字符串输出,这里只转换了 byte 数组中实际有内容的部分
	    System.out.println("内容为:\n"+new String(b,0, len));
	}
}

运行结果截图:

在这里插入图片描述

知识小补充:在使用 FileInputStream 读取文件是如果指定路径不存在,则程序会出现异常。
2. 读取文件内容,根据文件大小创建 byte 数组

  这样做的好处是按需开辟空间。利用 File 类中存在一个 length(), 此方法就可以取得文件的大小。

实列7代码:
package self.learn.javaio;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class IoPractices {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		// 向文件中写入字符串
		//String path = "D:"+File.separator+"SVN"+File.separator+"outPutStream.txt";
		String path = "D:\\SVN\\outPutStream.txt";
		// 1. 使用 File 类找到一个文件
		File file = new File(path);
		// 2. 通过子类实例化父类对象
		InputStream input = null;
		// 通过对象多态性进行实例化
		input = new FileInputStream(file); 
		// 3. 进行读操作
		// 数组大小由文件决定,但是文件内容不能过大
		byte b[] = new byte[(int)file.length()];
	    int len = input.read(b); // 把内容读取出,内容读到 byte 数组中        	
	    input.close();	
	    System.out.println("读取过来的内容有:"+len+" 个字节");
	    // 把数组变为字符串输出,这里只转换了 byte 数组中实际有内容的部分
	    System.out.println("内容为:\n"+new String(b));
	}
}

运行结果截图:

在这里插入图片描述

2. 通过循环把文件中的内容一个字节一个字节的读取过来(使用 read( ) 函数循环读取)
实列8代码:
package self.learn.javaio;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class IoPractices {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		// 向文件中写入字符串
		//String path = "D:"+File.separator+"SVN"+File.separator+"outPutStream.txt";
		String path = "D:\\SVN\\outPutStream.txt";
		// 1. 使用 File 类找到一个文件
		File file = new File(path);
		// 2. 通过子类实例化父类对象
		InputStream input = null;
		// 通过对象多态性进行实例化
		input = new FileInputStream(file); 
		// 3. 进行读操作
		// 数组大小由文件决定,但是文件内容不能过大
		byte b[] = new byte[(int)file.length()];
	    //int len = input.read(b); // 把内容读取出,内容读到 byte 数组中        	
		for(int i = 0; i < b.length; i++) {
			b[i] = (byte)input.read();
		}
	    input.close();	
	    // 把数组变为字符串输出,这里只转换了 byte 数组中实际有内容的部分
	    System.out.println("内容为:\n"+new String(b));
	}
}

运行结果截图:

在这里插入图片描述

3. 上面的程序是在明确知道了具体数组大小的前提下展开的,如果此时不知道要输入的内容有多大,则只能通过判断是否读到文件末尾的方式来读取文件。
实列9代码:
package self.learn.javaio;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class IoPractices {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		// 向文件中写入字符串
		//String path = "D:"+File.separator+"SVN"+File.separator+"outPutStream.txt";
		String path = "D:\\SVN\\outPutStream.txt";
		// 1. 使用 File 类找到一个文件
		File file = new File(path);
		// 2. 通过子类实例化父类对象
		InputStream input = null;
		// 通过对象多态性进行实例化
		input = new FileInputStream(file); 
		// 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++;
        }
	    input.close();	
	    // 把数组变为字符串输出,这里只转换了 byte 数组中实际有内容的部分
	    System.out.println("内容为:\n"+new String(b));
	}
}

运行结果截图:

在这里插入图片描述
提示: 文件读到末尾了,则返回的内容为 - 1。只有当输入流的内容已经读到底,才会返回这个数字,可以通过这个数字判断输入流中是否还有其他内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值