Java学习系列(十)Java面向对象之I/O流(上)
2014-04-25 11:25
726 查看
IO流
我们知道应用程序运行时数据是保存在内存中的,但由于内存中的数据不可持久保存(如断电或程序退出时数据会丢失),因此需要一种手段将数据写入硬盘或读入内存。面向IO流编程就是一种很好的选择。IO:Input/Output 完成输入输出,所谓输入:是指将外部存储器把数据读入内存,而输出:是指将内存中的数据写入外部存储器(如硬盘、磁盘、U盘)中。
File:代表磁盘上的文件或目录。它的特征是只能盘问磁盘上的文件和目录,但无法访问文件内容,必须使用IO流。
举例说明1(遍历根目录):
Java代码
public class FileTest {
public static void main(String[] args) {
// 列出系统中所有的根目录
File[] roots = File.listRoots();
for (File root : roots) {
System.out.println(root);
}
// 下面是相对路径,生成的mydir文件和src同一目录;
// 注意只有从根目录开始的路径才是绝对路径
File myFile = new File("mydir");
if (!myFile.exists()) {
// 创建相应目录
myFile.mkdir();
}
}
}
举例说明2(遍历某个磁盘上的所有文件):
Java代码
/**
* @author lhy
* @description 递归遍历某个磁盘下的所有目录及其子目录
*/
public class FileTest {
public static void main(String[] args) {
File f = new File("f:/");
myList(f);
}
public static void myList(File dir) {
System.out.println(dir + "目录下包含的目录和子文件有:");
// 返回当前目录所包含的目录和子文件
File[] files = dir.listFiles();
for (File file : files) {
System.out.println(" " + file);
// 如果file是目录,继续列出该目录下的所有文件
if (file.isDirectory()) {
myList(file);
}
}
}
}
举例说明3(过滤文件):
Java代码
public class FileTest {
public static void main(String[] args) {
File f = new File("f:/");
File[] files = f.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
try {
// getCanonicalPath()规范路径名是绝对路径名,并且是惟一的。
if (pathname.getCanonicalPath().endsWith(".txt")) {
return true;
}
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
});
for (File file : files) {
System.out.println(file);
}
}
}
IO流的分类(如果要访问文件内容,必须使用IO流):
a)按流的方向来分(从程序所在内存的角度来看):分为输入流、输出流。输入流是指将外部输入读入当前程序所在内存;而输出流是指将当前程序所在的内存的数据输出到外部。
b)按流处理的数据来分:分为字节流、字符流。字节流处理的数据单元是字节,适应性广、能共强大;而字符流处理的数据单元是字符,通常来说它主要用于处理文本文件,而且它在处理文本文件时比字节流更方便。
c)按流的角色来分:分为节点流、包装流(处理流/过滤流)。节点流直接和一个IO的物理节点(磁盘上的文件、键盘、网络等)关联;而包装流以节点为基础,经包装之后得到的流。
【流的概念模型】
输入流:只要你得到一个输入流对象,你就相当于得到一根“水管”,每个水滴就代表数据单元(字节/字符)。
输出流:只要你得到一个输出流对象,你也相当于得到一根“水管”,水管中无水滴。
下面讲下IO里面常用的几个类。
FileInputStream类的使用:
Java代码
public class Test {
public static void main(String[] args) {
// 准备水桶,可以装“1024”个水滴(数据单元)
byte[] bt = new byte[1024];
FileInputStream fis = null;
try {
fis = new FileInputStream("f:/Test.java");
int hasRead = -1;
while ((hasRead = fis.read(bt)) > 0) {
System.out.println(new String(bt, 0, hasRead));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
fis.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
FileOutputStream类的使用:
Java代码
public class Test {
public static void main(String[] args) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(new File("f:/1.txt"));
fos.write("Java学习系列(十)Java面向对象之I/O流".getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
文件的复制:
Java代码
public class Test {
public static void main(String[] args) {
FileOutputStream fos = null;
FileInputStream fis = null;
try {
fis = new FileInputStream(new File("f:/Test.java"));
fos = new FileOutputStream(new File("f:/Copy.java"));
int hasRead = -1;
// 作為水桶
byte[] buff = new byte[1024];
while ((hasRead = fis.read(buff)) > 0) {
fos.write(buff, 0, hasRead);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fis.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
ByteArrayOutputStream的使用:
Java代码
public class Test {
public static void main(String[] args) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
String str = "你好,世界!";
try {
bos.write(str.getBytes());
System.out.println(new String(bos.toByteArray()));
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
缓冲流:我们知道外部存储器的速度要比内存速度慢,所以外部存储器的读写与内存的读写是不同步的。注意:流用完了,别忘了调用flush(把缓冲中的内容刷入实际的节点)或者调用close()也可-系统会在关闭之前,自动刷缓冲。
节点流与缓冲流的联系:
节点流:直接与IO节点关联,--IO节点很多:键盘、网络、文件、磁带....
过滤流:建立在节点流的基础之上。
好处:消除底层节点之间的差异。使用过滤流的方法执行IO更加便捷。
PrintStream的使用:
Java代码
public class Test {
public static void main(String[] args) {
PrintStream ps = null;
try {
// 过滤流
ps = new PrintStream(new FileOutputStream("f:/1.txt"));
ps.println("春");
ps.println("夏");
ps.println("冬");
ps.println("冬");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
重定向标准输入输出。
System.setOut(new PrintStream("out.txt"));//将标准输出重定向到指定的输出流 -->out.txt
将字节流装换为字符流(使用BufferedReader可以每次读一行):
Java代码
public class Test {
public static void main(String[] args) {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(
"f:/Test.txt")));
String hasLine = null;
while ((hasLine = br.readLine()) != null) {
System.out.println(hasLine);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close();
} catch (Exception e2) {
}
}
}
}
【规律】除DataInputStream和DataOuputStream(这两个类后面会讲)这两个特殊的过滤流外,其它所有以Stream结尾的都是字节流,所有以Reader/Writer结尾的结尾的都是字符流。还有两个类:InputStreamReader、OutputStreamWriter是转换类,负责将字节流转换成字符流。
结束语
由于IO流的的内容比较多,所以打算分两次讲。
我们知道应用程序运行时数据是保存在内存中的,但由于内存中的数据不可持久保存(如断电或程序退出时数据会丢失),因此需要一种手段将数据写入硬盘或读入内存。面向IO流编程就是一种很好的选择。IO:Input/Output 完成输入输出,所谓输入:是指将外部存储器把数据读入内存,而输出:是指将内存中的数据写入外部存储器(如硬盘、磁盘、U盘)中。
File:代表磁盘上的文件或目录。它的特征是只能盘问磁盘上的文件和目录,但无法访问文件内容,必须使用IO流。
举例说明1(遍历根目录):
Java代码
public class FileTest {
public static void main(String[] args) {
// 列出系统中所有的根目录
File[] roots = File.listRoots();
for (File root : roots) {
System.out.println(root);
}
// 下面是相对路径,生成的mydir文件和src同一目录;
// 注意只有从根目录开始的路径才是绝对路径
File myFile = new File("mydir");
if (!myFile.exists()) {
// 创建相应目录
myFile.mkdir();
}
}
}
举例说明2(遍历某个磁盘上的所有文件):
Java代码
/**
* @author lhy
* @description 递归遍历某个磁盘下的所有目录及其子目录
*/
public class FileTest {
public static void main(String[] args) {
File f = new File("f:/");
myList(f);
}
public static void myList(File dir) {
System.out.println(dir + "目录下包含的目录和子文件有:");
// 返回当前目录所包含的目录和子文件
File[] files = dir.listFiles();
for (File file : files) {
System.out.println(" " + file);
// 如果file是目录,继续列出该目录下的所有文件
if (file.isDirectory()) {
myList(file);
}
}
}
}
举例说明3(过滤文件):
Java代码
public class FileTest {
public static void main(String[] args) {
File f = new File("f:/");
File[] files = f.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
try {
// getCanonicalPath()规范路径名是绝对路径名,并且是惟一的。
if (pathname.getCanonicalPath().endsWith(".txt")) {
return true;
}
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
});
for (File file : files) {
System.out.println(file);
}
}
}
IO流的分类(如果要访问文件内容,必须使用IO流):
a)按流的方向来分(从程序所在内存的角度来看):分为输入流、输出流。输入流是指将外部输入读入当前程序所在内存;而输出流是指将当前程序所在的内存的数据输出到外部。
b)按流处理的数据来分:分为字节流、字符流。字节流处理的数据单元是字节,适应性广、能共强大;而字符流处理的数据单元是字符,通常来说它主要用于处理文本文件,而且它在处理文本文件时比字节流更方便。
c)按流的角色来分:分为节点流、包装流(处理流/过滤流)。节点流直接和一个IO的物理节点(磁盘上的文件、键盘、网络等)关联;而包装流以节点为基础,经包装之后得到的流。
【流的概念模型】
输入流:只要你得到一个输入流对象,你就相当于得到一根“水管”,每个水滴就代表数据单元(字节/字符)。
输出流:只要你得到一个输出流对象,你也相当于得到一根“水管”,水管中无水滴。
下面讲下IO里面常用的几个类。
FileInputStream类的使用:
Java代码
public class Test {
public static void main(String[] args) {
// 准备水桶,可以装“1024”个水滴(数据单元)
byte[] bt = new byte[1024];
FileInputStream fis = null;
try {
fis = new FileInputStream("f:/Test.java");
int hasRead = -1;
while ((hasRead = fis.read(bt)) > 0) {
System.out.println(new String(bt, 0, hasRead));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
fis.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
FileOutputStream类的使用:
Java代码
public class Test {
public static void main(String[] args) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(new File("f:/1.txt"));
fos.write("Java学习系列(十)Java面向对象之I/O流".getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
文件的复制:
Java代码
public class Test {
public static void main(String[] args) {
FileOutputStream fos = null;
FileInputStream fis = null;
try {
fis = new FileInputStream(new File("f:/Test.java"));
fos = new FileOutputStream(new File("f:/Copy.java"));
int hasRead = -1;
// 作為水桶
byte[] buff = new byte[1024];
while ((hasRead = fis.read(buff)) > 0) {
fos.write(buff, 0, hasRead);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fis.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
ByteArrayOutputStream的使用:
Java代码
public class Test {
public static void main(String[] args) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
String str = "你好,世界!";
try {
bos.write(str.getBytes());
System.out.println(new String(bos.toByteArray()));
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
缓冲流:我们知道外部存储器的速度要比内存速度慢,所以外部存储器的读写与内存的读写是不同步的。注意:流用完了,别忘了调用flush(把缓冲中的内容刷入实际的节点)或者调用close()也可-系统会在关闭之前,自动刷缓冲。
节点流与缓冲流的联系:
节点流:直接与IO节点关联,--IO节点很多:键盘、网络、文件、磁带....
过滤流:建立在节点流的基础之上。
好处:消除底层节点之间的差异。使用过滤流的方法执行IO更加便捷。
PrintStream的使用:
Java代码
public class Test {
public static void main(String[] args) {
PrintStream ps = null;
try {
// 过滤流
ps = new PrintStream(new FileOutputStream("f:/1.txt"));
ps.println("春");
ps.println("夏");
ps.println("冬");
ps.println("冬");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
重定向标准输入输出。
System.setOut(new PrintStream("out.txt"));//将标准输出重定向到指定的输出流 -->out.txt
将字节流装换为字符流(使用BufferedReader可以每次读一行):
Java代码
public class Test {
public static void main(String[] args) {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(
"f:/Test.txt")));
String hasLine = null;
while ((hasLine = br.readLine()) != null) {
System.out.println(hasLine);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close();
} catch (Exception e2) {
}
}
}
}
【规律】除DataInputStream和DataOuputStream(这两个类后面会讲)这两个特殊的过滤流外,其它所有以Stream结尾的都是字节流,所有以Reader/Writer结尾的结尾的都是字符流。还有两个类:InputStreamReader、OutputStreamWriter是转换类,负责将字节流转换成字符流。
结束语
由于IO流的的内容比较多,所以打算分两次讲。
相关文章推荐
- Java学习系列(十)Java面向对象之I/O流(上)
- Java学习系列(十一)Java面向对象之I/O流(下)
- Java学习系列(十一)Java面向对象之I/O流(下)
- Java学习系列(十一)Java面向对象之I/O流(下)
- Java学习系列(十)Java面向对象之I/O流(上)
- Java学习系列(十三)Java面向对象之界面编程
- Java学习系列(七)Java面向对象之集合框架详解(上)
- Java学习系列(二十三)Java面向对象之内部类详解
- Java学习系列(四)Java面向对象之修饰符、封装、继承、多态详解
- Java学习系列(十四)Java面向对象之细谈线程、线程通信(上)
- Java学习系列(十七)Java面向对象之开发聊天工具
- Java学习系列(四)Java面向对象之修饰符、封装、继承、多态详解
- Java学习系列(二十二)Java面向对象之枚举详解
- Java学习系列(七)Java面向对象之集合框架详解(上)
- Java学习系列(五)Java面向对象之抽象类、接口、内部类、枚举类详解
- Java学习系列(十七)Java面向对象之开发聊天工具
- Java学习系列(四)Java面向对象之修饰符、封装、继承、多态详解
- Java学习系列(六)Java面向对象之Jar命令、正则表达式、国际化详解
- Java学习系列(十五)Java面向对象之细谈线程、线程通信(下)
- Java学习系列(十五)Java面向对象之细谈线程、线程通信(下)