Java---IO流(一)
IO流:
大多数应用程序都需要实现与设备之间的数据传输, 对于任何程序设计语言而言,输入输出(Input/Output)系统都是非常核心的功能。在Java中,将这种通过不同输入输出设备(键盘,内存,显示器,网络等)之间的数据传输抽象表述为“流”,程序允许通过流的方式与输入输出设备进行数据传输。Java中的“流”都位于java.io包中,称为IO(输入输出)流。
IO流有很多种,按照操作数据的不同,可以分为字节流和字符流,按照数据传输方向的不同又可分为输入流和输出流,程序从输入流中读取数据,向输出流中写入数据。
流的分类:
- 按数据单位分为:字节流(8bit),字符流(16bit);
- 按数据流向不同分为:输入流,输出流;
- 按流的角色不同分为:节点流,处理流;

下面为几个常用流:
| 字节流(输入) | 字节流(输出) | 字符流(输入) | 字符流(输出) | |
|---|---|---|---|---|
| 基本流 | InputStream | OutpuStream | Reader | Writer |
| 访问文件 | FileInputStream | FileOutputStream | FileReader | FileWriter |
| 缓冲流 | BufferedInputStream | BufferedOutputStream | BufferedReader | BufferedWriter |
| 转换流 | InputStreamReader | OutputStreamWriter | ||
| 对象流 | ObjectInputStream | ObjectOutputStream |
在计算机中,无论是文本、图片、音频还是视频,所有文件都是以二进制(字节)形式存在的,IO流中针对字节的输入输出提供了一系列的流,统称为字节流。在JDK中,提供了两个抽象类InputStream和OutputStream,它们是字节流的顶级父类,所有的字节输入流都继承自InputStream,所有的字节输出流都继承自OutputStream。为了方便理解,可以把InputStream和OutputStream比作两根“水管”,如图所示:

在JDK中,InputStream和 OutputStream提供了一系列与读写数据相关的方法,
InputStream方法,如下图所示:

OutputStream方法,如下图所示:

在程序中操作字符,可以使用字符流,分别是Reader和Writer。其中Reader是字符输入流,用于从某个源设备读取字符,Writer是字符输出流,用于向某个目标设备写入字符。Reader和Writer作为字符流的顶级父类,也有许多子类:

如果想从文件中直接读取字符便可以使用字符输入流FileReader,通过此流可以从关联的文件中读取一个或一组字符。
如果想对文件进行字符的写出可以使用字符写出流FileWriter。
File类
File类用于封装一个路径,这个路径可以是从系统盘符开始的绝对路径,也可以是相对于当前目录而言的相对路径。在File类中提供了针对这些文件或目录的一些常规操作。接下来首先介绍一下File类常用的构造方法,如表所示:(三种实现File的方式:)

File file1 = new File("G:\\java\\javaSE\\数据类型"); //类型一
File file2 = new File("G:\\java\\javaSE","数据类型"); //类型二
File file3 = new File(file2,"数据类型"); //类型三
File类中提供了一系列方法,用于操作其内部封装的路径指向的文件或者目录,例如判断文件/目录是否存在、创建、删除文件/目录等。

File f = new File("D:\\a.txt");
f.createNewFile();
f.renameTo(new File("D:\\aa.txt"));
//将文件重命名 注意:将一个file()传到另外一个file()时,要保证第二个file不存在。
System.out.println(System.getProperty("user.dir"));
File f = new File("aa.txt");
System.out.println("判断File是否存在:---" + f.exists());
System.out.println("判断File是否为目录:---" + f.isDirectory());
System.out.println("判断File是否为文件:---" + f.isFile());
System.out.println("判断File是否为可读文件:---" +f.canRead());
System.out.println("判断File是否为可写文件:---" +f.canWrite());
System.out.println("判断File是否为隐藏文件:---" +f.isHidden());
System.out.println("返回最后修改的时间:---" + new Date(f.lastModified()));
System.out.println("返回文件的大小:---" + f.length());
System.out.println("返回文件名:---" + f.getName());
System.out.println("返回文件的目录绝对路径:---" + f.getAbsolutePath());
System.out.println("获取文件上层目录:---" +f.getParent());
创建指定路径下的文件:createNewFile(),删除文件:delete(),创建目录:mkdir():
// f.createNewFile(); //创建f对应路径的文件,如果文件存在则不能创建,返回false
// f.delete(); //删除对应路径的文件,如果文件不存在则不能删除。目录下不能有文件
// f.mkdir(); //创建对应路径的文件目录,如果文件上层目录不存在,则不能创建。
// f.mkdirs(); //创建对应路径的文件目录,如果文件上层目录不存在,会一并创建。
遍历目录下的文件:使用list()方法,该方法用于遍历某个指定目录下的所有文件的名称: list() 、 listFiles()
File file = new File("D:\\JavaFile文件目录\\Java文件");
file.createNewFile();
String[] list = file.list(); //获取当前目录下的所有文件或目录的名字的数组
for (String i : list) {
System.out.println(i);
}
System.out.println("********************");
File[] files = file.listFiles(); //获取当前文件目录的所有绝对路径的数组
for (File j : files) {
System.out.println(j);
}
我们还可以将文件重命名 。 注意:重命名是将一个file()传到另外一个file(),要保证第二个file不存在。也就是修改的名字不能已经存在。
File f = new File("D:\\a.txt"); //a.txt
f.createNewFile();
f.renameTo(new File("D:\\aa.txt")); //将文件重命名
System.out.println(f.getName()); //aa.txt
再window中,我们再路径中每个\都要再加上\进行转义,如:D:\\a.txt。除此之外还可以使用File.separator 代替\
File file = new File("D:" + File.separator + "JavaFile文件目录"
+ File.separator +"Java文件");
//上面中的File.separator等同于"\\"
File基本流
基本字节流:InputSteam()和OutputStream();
基本字符流:Reader()和Writer();
这些基本文件流都可以对文件简单的输出写入的操作,但是一般都会使用访问文件流来操作。
对于IO文件流的基本步骤解析:
- 提供具体的流;
- 实例化流的对象;
- 数据读写操作;(字符流read()返回读入的一个字符,达到末尾时为-1);
- 关闭使用的流;
文件字节流&文件字符流
文件字节流一般使用的是FileInputStream()与FIleOutputStream()。
-
FileInputStream():通过字节的方式读取文件,适合读取所有类型的文件(图像、视频、文本文件等)。 -
FIleOutputStream():通过字节的方式写数据到文件中,适合所有类型的文件。 -
文件字节流中也可以使用Reader()和Writer()的方法;
使用文件字节流对.txt文件进行读取:
- 使用字节流对.txt文件进行读取在控制台输出有可能出现乱码的情况;
- 使用字节流对.txt文件进行读取再写入到数据文件中,则不会出现乱码的情况。
FileInputStream fi = null;
try {
File file = new File("src\\IOstream\\text2.txt");
fi = new FileInputStream(file);
byte[] bytes = new byte[5];
int leng;
while ((leng = fi.read(bytes)) != -1) {
String str = new String(bytes,0,leng);
System.out.print(str); //输出.txt文件,可能出现乱码
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fi != null)
fi.close();
} catch (IOException e) {
e.printStackTrace();
}
}
使用字节流对图片复制:
FileInputStream fi = null;
FileOutputStream fo = null;
try {
File file1 = new File("src\\IOstream\\img1.jpg");
File file2 = new File("src\\IOstream\\img2.jpg");
fi = new FileInputStream(file1);
fo = new FileOutputStream(file2);
byte[] bytes = new byte[10];
int leng;
while ((leng = fi.read(bytes)) != -1){
fo.write(bytes,0,leng);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fi != null)
fi.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if (fo != null)
fo.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
注意:1、为了提高效率,通常设置缓存数组。相应地,读取时使用的方法为:read(byte[] b);写入时的方法为:write(byte[ ] b, int off, int length)。
2、如果程序中有多个流,那么每个流都要关闭,防止其中一个流出现问题导致后面也出现问题。
文件字符流一般使用FileReader()和FileWriter()。
上面讲过使用文件字节流来处理文本文件,可能会出现乱码的情况。但是使用文件字符流来处理文本就不会出现乱码的情况了。所以,处理文本文件一般都会使用字符流来处理。
//对文本文件就行读取操作:
FileReader fr = null;
try {
File file = new File("src\\IOstream\\text1.txt"); //提供具体的流
fr = new FileReader(file); //实例化file对象
char[] cbuf = new char[5]; //使用read()数字类型
int leng;
while ((leng = fr.read(cbuf)) != -1) {
for (int i = 0; i < cbuf.length; i++) {
System.out.print(cbuf[i]);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fr != null)
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
使用FileWrite类型:文件可以不存在,不存在时会自动创建。
实例化FileWrite有两种情况:1)FileWrite(file,true)----->允许在原有文件里插入数据,不会覆盖原有数据;
2) FileWrite(file,false)----->不允许在原有文件里插入数据,添加的数据将会
覆盖原有数据。
//从文件中读取数据,再写出到另外一个文件中去:
FileReader fr = null;
FileWriter fw = null;
try {
File file1 = new File("src\\IOstream\\text1.txt");
File file2 = new File("src\\IOstream\\text3.txt");
fr = new FileReader(file1);
fw = new FileWriter(file2);
char[] cbuf = new char[5];
int leng;
while ((leng = fr.read(cbuf)) != -1) {
fw.write(cbuf,0,leng);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fw != null)
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if (fw != null)
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

浙公网安备 33010602011771号