java基础知识--IO的的常用操作
Posted JordanInShenzhen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java基础知识--IO的的常用操作相关的知识,希望对你有一定的参考价值。
这章主要介绍IO相关的常用操作,从我自己这几年的项目经验上来看,文件IO操作是最频繁使用到的,必然要介绍文件的字符流IO和字节流IO;其次,在网络传输过程中,需要将外面传输进来的数据放到缓冲区,减少对外访问次数,所以缓冲输入输出流BufferInputStream、BufferOutputStream也是必须要了解的了;最后就是说下面试中可能会问的一些问题,以及解答
文件操作
上一篇文章已经分别介绍了IO分字符流和字节流,至于文件的IO,则有字符流的FileReader、FileWrite,字节流的FileInputStream和FileOutputStream。不过,在介绍这几个类之前,我们先来看看File类,毕竟先把文件找到,才能说读写的事情,是不是
File类
在Java语言的java.io包中,由File类提供了描述文件和目录的操作与管理方法。File类不是InputStream、OutputStream或Reader、Writer的子类,因为它不负责数据的输入输出,而专门用来管理磁盘文件与目录。
作用:File类主要用于命名文件、查询文件属性和处理文件目录。
构造函数:
1)File (String pathname)
例:File f1 = new File("File.txt"); // 创建文件对象f1,指向当前目录下的File.txt文件
2)File (String parent , String child)
例: File f2 = new File(“D:\\\\dir1","File.txt") ; // 创建文件对象f2,指向D:\\\\dir1目录下的File.txt文件,注意:D:\\\\dir1目录事先必须存在,否则会抛异常
3)File (File parent , String child)
例: File f4 = new File("D:\\\\dir3");
File f5 = new File(f4,"FileTest5.txt");
//这种方式,如果D:\\\\dir3目录不存在则会先创建一个对应于某磁盘文件或目录,跟第二种方式存在
File对象常用的方法:
1)public boolean exists( ) 判断文件或目录是否存在
2)public boolean isFile( ) 判断是文件还是目录
3)public boolean isDirectory( ) 判断是文件还是目录
4)public String getName( ) 返回文件名或目录名
5)public String getPath( ) 返回文件或目录的路径。
6)public long length( ) 获取文件的长度
7)public String[ ] list( ) 将目录中所有文件名保存在字符串数组中返回。
File类中还定义了一些对文件或目录进行管理、操作的方法,常用的方法有:
1) public boolean renameTo( File newFile ); 重命名文件
2) public void delete( ); 删除文件
3) public boolean mkdir( ); 创建目录
标准的文件获取代码:
public class Test {
public static void main(String[] args) throws IOException {
public static void main(String[] args) throws IOException {
// 如果不存在这个目录,则创建
File dir = new File("d:\\\\test");
if (!dir.exists())
dir.mkdir();
// 如果这个文件不存在,则创建
File f= new File(dir,"text.txt");
if(!f.exists())
{
f.createNewFile();
}
System.out.println("f1's AbsolutePath= " + f.getAbsolutePath());
System.out.println("f1 Canread=" + f.canRead());
System.out.println("f1's len= " + f.length());
String[] FL;
int count = 0;
FL = dir.list();
for (int i = 0; i < FL.length; i++) {
count++;
System.out.println(FL[i] + "is in d:\\\\test");
}
System.out.println("there are" + count + "file in d:\\\\test");
}
}
字节流方式读写文件
上一篇博客已经介绍了字节流的文件读写FileInputStram和FileOutputStream,FileInputStream可以使用read()方法一次读入一个字节,并以int类型返回,或者是使用read()方法时读入至一个byte数组,byte数组的元素有多少个,就读入多少个字节。在将整个文件读取完成或写入完毕的过程中,这么一个byte数组通常被当作缓冲区,因为这么一个byte数组通常扮演承接数据的中间角色。FileOutputStream则用来处理以文件作为数据输出目的数据流,或者说是从内存区读数据入文件。
比如需要从一个text1.txt文件,将内容复制到另外一个text2.txt文件:
public class Test {
public static void main(String[] args) throws IOException {
// 如果不存在这个目录,则创建
File dir = new File("d:\\\\test");
if (!dir.exists()) {
return;
}
// 如果这个文件不存在,则直接返回
File f1= new File(dir,"text1.txt");
if(!f1.exists()) {
return;
}
// 如果这个文件不存在,则创建
File f2= new File(dir,"text2.txt");
if(!f2.exists()) {
f2.createNewFile();
}
FileInputStream finS = new FileInputStream(f1);
FileOutputStream foutS = new FileOutputStream(f2);
int c;
while ((c = finS.read()) != -1) {
foutS.write(c);
}
finS.close();
foutS.close();
}
}
字符流方式操作文件
字符流方式处理文件其实要考虑比较多的问题,比如是否涉及字节码的转换,由于读到内存中是从源文件的字节编码格式,转换成Unicode格式,再从unicode格式转换到目标文件字节编码格式,所以需要两边都支持这种字节码转换才能使用该方式操作,否则就会出现乱码的问题
public class Test {
public static void main(String[] args) throws IOException {
// 如果不存在这个目录,则创建
File dir = new File("d:\\\\test");
if (!dir.exists()) {
return;
}
// 如果这个文件不存在,则直接返回
File f1= new File(dir,"text1.txt");
if(!f1.exists()) {
return;
}
// 如果这个文件不存在,则创建
File f2= new File(dir,"text2.txt");
if(!f2.exists()) {
f2.createNewFile();
}
FileReader fr = new FileReader(f1);
BufferedReader bf = new BufferedReader(fr);
FileWriter fw = new FileWriter(f2);
BufferedWriter bout = new BufferedWriter(fw);
String s;
while ((s = bf.readLine()) != null) {
bout.write(s, 0, s.length());
}
bout.flush(); // 这行很关键,如果不加这行,则文件内容无法从缓冲区刷到文件上
bout.close();
fw.close();
bf.close();
fr.close();
}
}
缓冲输入输出流 BufferedInputStream/BufferedOutputStream
计算机访问外部设备非常耗时。访问外部(键盘、网络)的频率越高,造成CPU闲置的概率就越大。为了减少访问外部的次数,应该在一次对外部的访问中,读写更多的数据。为此,除了程序和流节点间交换数据必需的读写机制外,还应该增加缓冲机制。缓冲流就是每一个数据流分配一个缓冲区,一个缓冲区就是一个临时存储数据的内存。这样可以减少访问外部的次数,提高传输效率。
BufferedInputStream:当向缓冲流写入数据时候,数据先写到缓冲区,待缓冲区写满后,系统一次性将数据发送给输出设备。
BufferedOutputStream :当从向缓冲流读取数据时候,系统先从缓冲区读出数据,待缓冲区为空时,系统再从输入设备读取数据到缓冲区。
键盘输入流读到内存
将BufferedReader与标准的数据流相接 :
import java.io.*;
public class ReadWriteToFile {
public static void main(String args[]) throws IOException {
InputStreamReader sin = new InputStreamReader(System.in);
BufferedReader bin = new BufferedReader(sin);
FileWriter out = new FileWriter("myfile.txt");
BufferedWriter bout = new BufferedWriter(out);
String s;
while ((s = bin.readLine()).length() > 0) {
bout.write(s, 0, s.length());
}
}
}
面试题汇总
(1)java中有几种类型的流?
字符流和字节流。字节流继承inputStream和OutputStream,字符流继承自InputSteamReader和OutputStreamWriter。
(2)谈谈Java IO里面的常见类,字节流,字符流、接口、实现类、方法阻塞
答:输入流就是从外部文件输入到内存,输出流主要是从内存输出到文件。
IO里面常见的类,第一印象就只知道IO流中有很多类,IO流主要分为字符流和字节流。字符流中有抽象类InputStream和OutputStream,它们的子类FileInputStream,FileOutputStream,BufferedOutputStream等。字符流BufferedReader和Writer等。都实现了Closeable, Flushable, Appendable这些接口。程序中的输入输出都是以流的形式保存的,流中保存的实际上全都是字节文件。
java中的阻塞式方法是指在程序调用改方法时,必须等待输入数据可用或者检测到输入结束或者抛出异常,否则程序会一直停留在该语句上,不会执行下面的语句。比如read()和readLine()方法。
(3)字符流和字节流有什么区别?
要把一片二进制数据数据逐一输出到某个设备中,或者从某个设备中逐一读取一片二进制数据,不管输入输出设备是什么,我们要用统一的方式来完成这些操作,用一种抽象的方式进行描述,这个抽象描述方式起名为IO流,对应的抽象类为OutputStream和InputStream ,不同的实现类就代表不同的输入和输出设备,它们都是针对字节进行操作的。
在应用中,经常要完全是字符的一段文本输出去或读进来,用字节流可以吗?
计算机中的一切最终都是二进制的字节形式存在。对于“中国”这些字符,首先要得到其对应的字节,然后将字节写入到输出流。读取时,首先读到的是字节,可是我们要把它显示为字符,我们需要将字节转换成字符。由于这样的需求很广泛,人家专门提供了字符流的包装类。
底层设备永远只接受字节数据,有时候要写字符串到底层设备,需要将字符串转成字节再进行写入。字符流是字节流的包装,字符流则是直接接受字符串,它内部将串转成字节,再写入底层设备,这为我们向IO设别写入或读取字符串提供了一点点方便。
以上是关于java基础知识--IO的的常用操作的主要内容,如果未能解决你的问题,请参考以下文章
java内存流:java.io.ByteArrayInputStreamjava.io.ByteArrayOutputStreamjava.io.CharArrayReaderjava.io(代码片段
java缓冲字符字节输入输出流:java.io.BufferedReaderjava.io.BufferedWriterjava.io.BufferedInputStreamjava.io.(代码片段