java 指定编码的输入流_Java输入输出流

本文详细介绍了Java中的输入输出流,包括字节流和字符流的区别,以及如何使用InputStream、OutputStream、Reader、Writer进行文件操作。重点讲解了FileInputStream、FileOutputStream、FileReader、FileWriter的使用方法,如创建、删除、重命名文件,以及读写文件的内容。同时,提到了转换流InputStreamReader和OutputStreamWriter在字节流和字符流之间的转换作用。
摘要由CSDN通过智能技术生成

1) Java流操作有关的类或接口:

Java流类图结构:

1. InputStream/OutputStream

字节流的抽象类。

2. Reader/Writer

字符流的抽象类。

3. FileInputStream/FileOutputStream

节点流:以字节为单位直接操作“文件”。

4. ByteArrayInputStream/ByteArrayOutputStream

节点流:以字节为单位直接操作“字节数组对象”。

5. ObjectInputStream/ObjectOutputStream

处理流:以字节为单位直接操作“对象”。

6. DataInputStream/DataOutputStream

处理流:以字节为单位直接操作“基本数据类型与字符串类型”。

7. FileReader/FileWriter

节点流:以字符为单位直接操作“文本文件”(注意:只能读写文本文件)。

8. BufferedReader/BufferedWriter

处理流:将Reader/Writer对象进行包装,增加缓存功能,提高读写效率。

9. BufferedInputStream/BufferedOutputStream

处理流:将InputStream/OutputStream对象进行包装,增加缓存功能,提高 读写效率。

10. InputStreamReader/OutputStreamWriter

处理流:将字节流对象转化成字符流对象。

11. PrintStream

处理流:将OutputStream进行包装,可以方便地输出字符,更加灵活。

2)流的概念和作用

流是一个抽象、动态的概念,是一连串连续动态的数据集合。

对于输入流而言,数据源就像水箱,流(stream)就像水管中流动着的水流,程序就是我们最终的用户。我们通过流(A Stream)将数据源(Source)中的数据(information)输送到程序(Program)中。

对于输出流而言,目标数据源就是目的地(dest),我们通过流(A Stream)将程序(Program)中的数据(information)输送到目的数据源(dest)中。

输入/输出流的划分是相对程序而言的,并不是相对数据源。

IO流的分类

1.按流的方向分类:

1. 输入流:数据流向是数据源到程序(以InputStream、Reader结尾的流)。

2. 输出流:数据流向是程序到目的地(以OutPutStream、Writer结尾的流)。

2.按处理的数据单元分类:

1. 字节流:以字节为单位获取数据,命名上以Stream结尾的流一般是字节流,如FileInputStream、FileOutputStream。

2. 字符流:以字符为单位获取数据,命名上以Reader/Writer结尾的流一般是字符流,如FileReader、FileWriter。

3.按处理对象不同分类:

1. 节点流:可以直接从数据源或目的地读写数据,如FileInputStream、FileReader、DataInputStream等。

2. 处理流:不直接连接到数据源或目的地,是”处理流的流”。通过对其他流的处理提高程序的性能,如BufferedInputStream、BufferedReader等。处理流也叫包装流。

节点流处于IO操作的第一线,所有操作必须通过它们进行;处理流可以对节点流进行包装,提高性能或提高程序的灵活性

3.File类

File类是对文件系统中文件以及文件夹进行封装的对象,可以通过对象的思想来操作文件和文件夹。 File类保存文件或目录的各种元数据信息,包括文件名、文件长度、最后修改时间、是否可读、获取当前文件的路径名,判断指定文件是否存在、获得当前目录中的文件列表,创建、删除文件和目录等方法。

3.1File 类的概述和构造方法:

要想实现IO的操作,就必须知道硬盘上文件的表现形式,而java中就提供了一个File类。

构造方法:

public File(String pathname):根据一个路径得到一个File对象

File(String parent, String child) : 根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。

File(File parent, String child) : 根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。

方式一:File file1 = new File(“e:\\demo\\test.txt”);

方式二:File file2 = new File(“e:\\demo”,”test.txt”);

方式三:File file3 = new File(“e:\\demo”);

File file4 = new File(file3,”test.txt”);

注意:以上三种方式其实效果一样

3.2File 类的创建功能

创建功能: boolean mkdir():创建文件夹,如果存在此文件夹,则不创建,返回结果为false;

boolean createNewFile():创建文件,如果此文件存在,则不创建,返回结果为false;

注意:如果需要在某个文件夹下创建文件,则此文件依赖的文件夹必须存在,否则会出现IO异常,系统找不到指定路径。

如果创建文件或文件夹时忘记写盘符路径,默认在项目路径下。

boolean mkdirs():用于创建文件夹,如果父文件夹不存在时,其可以自动创建父文件夹,即用于创建多级文件的。

例如:

File file = new File(“e:\\test\\test.txt”);

System.out.println(“mkdir:”+file.mkdirs());

以上两行代码执行正确。

3.3File类的删除功能:

public boolean delete();此方法可以删除文件或文件夹。

注意:java中的删除不走回收站;

被删除文件夹中不能包含子文件或文件夹

3.4File类的判断功能:

public boolean isDirectory();判断是否是目录

public boolean isFile();判断是否是文件

public boolean exists();判断是否存在

public boolean canWrite();判断是否可写

public boolean canRead();判断是否可读

public boolean isHidden();判断是否隐藏

3.5File类的重命名功能:

public boolean renameTo(File file);

如果路径名相同,改名,如果路径名不同,相当于改名并剪切

注意:路径以盘符开始:绝对路径

路径不以盘符开始:相对路径

需求:使用程序修改某个文件的名称。

File file = new File(“xxx.txt”);

File newFile = new File(“test.txt”);

System.out.println(“renameTo:”+ file.renameTo(newFile));

File file2 = new File(“xxx.txt”);

File newFile2 = new File(“e:\\test.txt”);

System.out.println(“renameTo:”+ file2.renameTo(newFile2));

3.6File 类的基本获取功能

获取功能:

public String getAbsolutePath();获取绝对路径

public String getPath();获取相对路径

public String getName();获取名称

public long length();获取长度,字节数

public long lastModified();获取最后一次的修改时间,毫秒值

3.7File类的高级获取功能:

public String[] list():获取指定目录下的所有文件或者文件夹的名称数组

public file[] listFiles(): 获取指定目录下的所有文件或者文件夹的File数组

4)Java IO流对象

1.输入字节流InputStreamio 中输入字节流的继承图可见上图,可以看出:InputStream 是所有的输入字节流的父类,它是一个抽象类。

ByteArrayInputStream、StringBufferInputStream、FileInputStream 是三种基本的介质流,它们分别从Byte 数组、StringBuffer、和本地文件中读取数据。PipedInputStream 是从与其它线程共用的管道中读取数据,与Piped 相关的知识后续单独介绍。

ObjectInputStream 和所有FilterInputStream 的子类都是装饰流(装饰器模式的主角)。

为了保证出现异常后流的正常关闭,通常要将流的关闭语句要放到finally语句块中,并且要判断流是不是null。

5)输出字节流OutputStream

http://2.IO 中输出字节流的继承图可见上图,可以看出:OutputStream 是所有的输出字节流的父类,它是一个抽象类。

ByteArrayOutputStream、FileOutputStream 是两种基本的介质流,它们分别向Byte 数组、和本地文件中写入数据。PipedOutputStream 是向与其它线程共用的管道中写入数据,

ObjectOutputStream 和所有FilterOutputStream 的子类都是装饰流。

3.字节流的输入与输出的对应

3.1.字节流的输入流(InputStream)

构造方法:

FileInputStream​(File file)

FileInputStream​(String name)

成员方法:

int read​()从该输入流读取一个字节的数据。

int read​(byte[]b)从该输入流读取最多b.length个字节的数据到一个字节数组。

int read​(byte[]b,intoff,intlen)从该输入流读取最多len个字节的数据到字节数组。

//需求:使用字节输入流将文件中的内容读取并在控制台输出 //目标文件对象 File file = new File("d:\\test.txt");

// //创建输入流对象 FileInputStream fis=new FileInputStream(file);

FileInputStream fis =new FileInputStream("d:\\test.txt"); byte [] b =new byte[(int)file.length()];

//读取内容 System.out.println( fis.read(b));

for (int i=0;i

System.out.print((char)b[i]);

}

//释放资源 fis.close();

}

3.2字节流的输出流(OutputStream)

FileOutputStream 的构造方法

public FileOutputSteam(File file);

public FileOutputSteam(String name);

public FileOutputSteam(String name,boolean append);

成员方法:

void write​(byte[] b) 将 b.length字节从指定的字节数组写入此输出流。

void write​(byte[] b, int off, int len) 从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。

void write​(int b) 将指定的字节写入此输出流。

void close​() 关闭此输出流并释放与此流相关联的任何系统资源。

//指定输出内容的文件

// File file = new File("d:\\test.txt");

//创建输出流的对象

// OutputStream os=new FileOutputStream(file);

/**

* A;创建File对象

* B:新建文件

* C:写出内容

*/

OutputStream os =new FileOutputStream("d:\\test.txt");

//准备输出的内容

String str = "Hello io";

//将输出内容按字节方式进行输出

// os.write(str.getBytes());

os.write(str.getBytes(),0,4);//0表示起始

os.close();

6.字符输入流Reader在上面的继承关系图中可以看出:

Reader 是所有的输入字符流的父类,它是一个抽象类。

CharReader、StringReader 是两种基本的介质流,它们分别将Char 数组、String中读取数据。PipedReader 是从与其它线程共用的管道中读取数据。

BufferedReader 很明显就是一个装饰器,它和其子类负责装饰其它Reader 对象。

FilterReader 是所有自定义具体装饰流的父类,其子类PushbackReader 对Reader 对象进行装饰,会增加一个行号。

InputStreamReader 是一个连接字节流和字符流的桥梁,它将字节流转变为字符流。FileReader 可以说是一个达到此功能、常用的工具类,在其源代码中明显使用了将FileInputStream 转变为Reader 的方法。我们可以从这个类中得到一定的技巧。Reader 中各个类的用途和使用方法基本和InputStream 中的类使用一致。后面会有Reader 与InputStream 的对应关系。

基类:Reader 抽象类

子类:InputStreamReder

构造方法:

按系统默认字符集进行文件内容的读取

InputStreamReader​(InputStream in) 创建一个使用默认字符集的InputStreamReader。

按指定字符集进行文件内容的读取

InputStreamReader​(InputStream in, String charsetName) 创建一个使用命名字符集的

File file =new File("d:\\\\test.txt");

//构造InputStream对象

InputStream is = new FileInputStream("d:\\\\test.txt");

//创建字符输入流对象

InputStreamReader isr= new InputStreamReader(is);

//读取内容

// int b = -1;

// while ((b=isr.read())!=-1){

// System.out.print((char)b);

// }

//创建存储的缓冲区

char [] chs = new char [(int)file.length()];

//将文件内容读取到缓冲区chs

isr.read(chs);

for (char c:chs

) {

System.out.print(c);

}

//释放资源

isr.close();

is.close();

字符输入流的便捷类:FileReder 注意:不能指定特定编码格式,其按照系统默认的编码格式进行文件读取

构造方法:

FileReader​(File file) 创建一个新的 FileReader ,给出 File读取。

FileReader​(String fileName) 创建一个新的 FileReader ,给定要读取的文件的名称。

FileReader fr = new FileReader("d:\\test.txt");

int b =-1;

while (( b=fr.read() )!=-1){

System.out.print((char)b);

}

fr.close();

7.字符输出流Writer

在上面的关系图中可以看出:Writer 是所有的输出字符流的父类,它是一个抽象类。

CharArrayWriter、StringWriter 是两种基本的介质流,它们分别向Char 数组、String 中写入数据。PipedWriter 是向与其它线程共用的管道中写入数据,

BufferedWriter 是一个装饰器为Writer 提供缓冲功能。

PrintWriter 和PrintStream 极其类似,功能和使用也非常相似。

OutputStreamWriter 是OutputStream 到Writer 转换的桥梁,它的子类FileWriter 其实就是一个实现此功能的具体类(具体可以研究一SourceCode)。功能和使用和OutputStream 极其类似,后面会有它们的对应图。

字符输出流:Writer抽象类

子类:OutputStreamWriter

构造方法

OutputStreamWriter​(OutputStream out) 创建一个使用默认字符编码的OutputStreamWriter。

OutputStreamWriter​(OutputStream out, String charsetName) 创建一个使用命名字符集的OutputStreamWriter。

成员方法:

void write​(char[] cbuf, int off, int len) 写入字符数组的一部分。

void write​(int c) 写一个字符

void write​(String str, int off, int len) 写一个字符串的一部分

//创建字符输出流对象,并指定转储文件

OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\\\pet.template"),"utf-8");

String info = "您好,我的名字是{name},我是一只{type},我的主人{master}";

//写出操作

osw.write(info);

osw.close();

FileWriter:字符输出流的便捷类,也是OutputStreamWriter的子类

构造方法:

FileWriter​(File file) 给一个File对象构造一个FileWriter对象。

FileWriter​(File file, boolean append) 给一个File对象构造一个FileWriter对象。

FileWriter​(String fileName) 构造一个给定文件名的FileWriter对象。

FileWriter​(String fileName, boolean append) 构造一个FileWriter对象,给出一个带有布尔值的文件名,表示是否附加写入的数据。

成员方法:

public void flush();

public void close();

void write​(char[] cbuf, int off, int len) 写入字符数组的一部分。

void write​(int c) 写一个字符

void write​(String str, int off, int len) 写一个字符串的一部分

9.字符流与字节流转换

转换流的特点:其是字符流和字节流之间的桥梁

可对读取到的字节数据经过指定编码转换成字符

可对读取到的字符数据经过指定编码转换成字节

何时使用转换流?当字节和字符之间有转换动作时;

流操作的数据需要编码或解码时。

具体的对象体现:InputStreamReader:字节到字符的桥梁

OutputStreamWriter:字符到字节的桥梁

这两个流对象是字符体系中的成员,它们有转换作用,本身又是字符流,所以在构造的时候需要传入字节流对象进来。

10.RandomAccessFile类

该对象并不是流体系中的一员,其封装了字节流,同时还封装了一个缓冲区(字符数组),通过内部的指针来操作字符数组中的数据。 该对象特点:该对象只能操作文件,所以构造函数接收两种类型的参数:a.字符串文件路径;b.File对象。

该对象既可以对文件进行读操作,也能进行写操作,在进行对象实例化时可指定操作模式(r,rw)

注意:该对象在实例化时,如果要操作的文件不存在,会自动创建;如果文件存在,写数据未指定位置,会从头开始写,即覆盖原有的内容。 可以用于多线程下载或多个线程同时写数据到文件。

经典代码:

1.使用流读取文件内容(经典代码,一定要掌握)

import java.io.*;

public class TestIO2 {

public static void main(String[] args) {

FileInputStream fis = null;

try {

fis = new FileInputStream("d:/a.txt"); // 内容是:abc

StringBuilder sb = new StringBuilder();

int temp = 0;

//当temp等于-1时,表示已经到了文件结尾,停止读取

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

sb.append((char) temp);

}

System.out.println(sb);

} catch (Exception e) {

e.printStackTrace();

} finally {

try {

//这种写法,保证了即使遇到异常情况,也会关闭流对象。

if (fis != null) {

fis.close();

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

为了保证出现异常后流的正常关闭,通常要将流的关闭语句要放到finally语句块中,并且要判断流是不是null。

2.利用文件流实现文件的复制

package d804_2;

import java.io.*;

public class IoDemo2 {

public static void main(String[] args) {

copyFile("d:\\p.txt","d:\\u2.txt");

}

static void copyFile(String src, String dec) {

FileInputStream fis = null;

FileOutputStream fos = null;

//为了提高效率,设置缓存数组!(读取的字节数据会暂存放到该字节数组)

byte[] buffer = new byte[1024];

int temp = 0;

try {

fis = new FileInputStream(src);

fos = new FileOutputStream(dec);

//边读边写

//temp指的是本次读取的真实长度,temp等于-1时表示读取结束

while ((temp = fis.read(buffer)) != -1) {

/*将缓存数组中的数据写入文件中,注意:写入的是读取的真实长度;

*如果使用fos.write(buffer)方法,那么写入的长度将会是1024,即缓存

*数组的长度*/

fos.write(buffer,0,temp);

}

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

} finally {

try {

if (fos != null) {

fos.close();

}

} catch (IOException e) {

e.printStackTrace();

}

try {

if (fis != null) {

fis.close();

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值