我们要把一个文件从外部读入程序中,大致的步骤如下:
第一步:获取需要被读取的文件
第二步:构造一个字节输入流,用来读取文件
第三步:为了提高读写速度,需要把字节流转换成一个字符输入流
第四步:写文件
所以我们必须需要明白File、FileInputStream和InputStreamReader各自的作用
File类:
java 8的API中是这样描述的:文件和目录路径名的抽象表示。用户界面和操作系统使用依赖于系统的路径名字符串命名文件和目录。 这个类提供了一个抽象的,独立于系统的层次化路径名的视图。
什么意思呢?就是当我们需要操作一个文件的时候,要明确的标识它的文件路径。
常见的构造方法有如下:
FileInputStream类
继承了java中io操作的父类:InputStream
java8的API中对它的描述:FileInputStream从文件系统中的文件获取输入字节
FileInputStream用于读取诸如图像数据的原始字节流。 要阅读字符串,请考虑使用FileReader 。FileInputStream常用的构造方法如下:
InputStreamReader类
java8的API中对它的描述:InputStreamReader是从字节流到字符流的桥:它读取字节,并使用指定的charset将其解码为字符 。
构造方法有:
1)字节流到字符流的桥梁怎么理解?
1、计算机存储的单位是字节,如尽管txt文本中有中文汉字这样的字符,但是对计算机而言,其是字节形式存在的
2、字节流读取是单字节读取,但是不同字符集解码成字符需要不通过个数,因此字节流读取会报错
3、 那么就需要一个流把字节流读取的字节进行缓冲而后在通过字符集解码成字符返回,因而形式上看是字符流
4、InputStreamReader流就是起这个作用,实现从字节流到字符流的转换
2)使用指定的字符集读取字节并将它们解码为字符怎么理解?
字节本质是8个二进制位,且不同的字符集对同一字节解码后的字符结果是不同的,因此在读取字符时务必要指定合适的字符集,否则读取的内容会产生乱码
理解了上面的各个类以及作用,接下来就可以进行文件的读取操作了:
具体的代码如下:
public static void main(String[] args) {
//第一步 指定需要被读取的文件
File file = new File("D:\\toprs_test.sql");
//第二步 构造一个字节输入流 FileInputStream
try {
// 方法一 通过文件创建FileInputStream
FileInputStream fileInputStream = new FileInputStream(file);
// 方法二 通过文件名创建FileInputStream 一定要取绝对路径 file.getAbsolutePath()
FileInputStream fileInputStream1 = new FileInputStream(file.getAbsolutePath());
// 第三步 构造字符输入流 指定字符编码
InputStreamReader inputStream = new InputStreamReader(fileInputStream,"utf-8");
//第四步 读取文件
char[] ch=new char[2014];
int len=inputStream.read(ch);
System.err.println(new String(ch,0,len));
// 关闭流并释放与之相关联的任何系统资源。
inputStream.close();
}catch (Exception e){
log.info("读取文件异常结束,错误信息:{}",e.getMessage());
}
}
运行结果:
备注:new FileInputStream(file)和new FileInputStream(file.getAbsolutePath())的比较
查看了FileInputStream构造方法的源码发现当我们试图用一个文件的全路径去获得一个字节输入流的时候,它其实也是把文件路径创建成一个文件的,以此来创建一个字节输入流。
new FileInputStream(file)构造方法的源码如下:
public FileInputStream(File file) throws FileNotFoundException {
String name = (file != null ? file.getPath() : null);
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(name);
}
if (name == null) {
throw new NullPointerException();
}
if (file.isInvalid()) {
throw new FileNotFoundException("Invalid file path");
}
fd = new FileDescriptor();
fd.attach(this);
path = name;
open(name);
}
FileInputStream(file.getAbsolutePath())构造方法的源码如下
// 源码显示,当传入的fileName不为空的时候,会利用这个全路径去new一个文件,然后再去调用new FileInputStream(file)这个构造方法来new一个字节输入流
public FileInputStream(String name) throws FileNotFoundException {
this(name != null ? new File(name) : null);
}
--------------------------------------------------------------日常记录点滴---------------------------------------------------------