④Java.IO

java.IO包是java处理文件目录有关的工具包,对于本节的学习,我们要有以下几个目标

  • 了解java.io包
  • 运用File类对文件或者目录的属性进行操作
  • 理解流,理解输入输出流的概念
  • 运用FileInputStream类和FileOutputStream类读、写字节文件
  • 运用FileReader类和FileWriter类配合BufferedReader类和BufferedWriter类读、写字符文件。
  • 使用BufferedReader类从控制台接受输入
  • 运用DataInputStream类和DataOutputStream类读写数据文件

这里十分感谢:http://blog.csdn.net/nisior/article/details/7162754

首先来了解File类

顾名思义看来,就是文件,这个类包含了文件的属性包括路径、名称、大小等等,如果在处理文件的时候需要用到某种属性或者方法,一定要到File类来看看是否有你想要的东西。

注:学习应该也是应该以网络的形式展开,你需要做的是拓展网络节点的个数,每个节点代表了一个知识点,实践的时候再去拓展这个节点,形成一个子网络。

至于File类中的方法,希望诸君不要像我一样偷懒,一定要浏览一遍。这里举个例子以飨读者:

public class FileDemo
{
public static void main(String[] args)
{
    //创建一个文件对象,使之与一个文件关联
    File file = new File("File.txt");

    //显示与文件有关的属性信息
System.out.println("文件或目录是否存在:" + file.exists());
System.out.println("是文件吗:" + file.isFile());
System.out.println("是目录吗:" + file.isDirectory());
System.out.println("名称:" + file.getName());
System.out.println("绝对路径:" + file.getAbsolutePath());
System.out.println("文件大小:" + file.length());
    }
}
再来看看流的概念

流是指一连串流动的数据信号,是以先进先出的方式发送和接收数据的通道。

流示意图
流示意图

流示意图
流示意图

根据流动的方向,分为输入流和输出流

根据文件的大小,分为字节流和字符流

字节流:是指8位的通用字节流,以字节为基本单位,对字节流进行操作的类大多继承于InputStream和OutputStream类。

字符流:是指16位的Unicode字符流,以字符(两个字节)为基本单位,非常适合处理字符串和文本,大部分继承自Reader类和Writer类。

下面我们来看看这个包中最常见的方法,也是你们今后用到的最频繁的方法:

使用FileInputStream类读文件
  • FileInputStream类成为文件输入流,继承于InputStream类,是文件操作的最基本的类
  • 它的作用是将文件中的数据输入到内存中,我们可以利用它来读文件
  • 由于它属于字节流,因此在读取Unicode字符(如中文)的文件时候可能会出现问题
使用FileOutputStream类写文件
  • 继承自OutputStream类,可以利用它来写文件。

一般来讲,这两个类的使用是成对出现的,采用字节来处理文件,好处就在于,不必考虑数据格式的问题,虽然在编码上稍微复杂了一些,但是当文件过大的时候,效率就体现出来了。

public class CopyFileDemo {
public static void main(String[] args) throws IOException {
File srcFile = new File("src.dat");    //源文件对象
File destFile = new File("dest.dat");  //目标文件对象
if (!(destFile.exists())) {  //判断目标文件是否存在
  destFile.createNewFile();  //如果不存在则创建新文件
}
//使用源文件对象创建文件输入流对象
FileInputStream fis = new FileInputStream(srcFile);
//使用目标文件对象创建文件输出流对象
FileOutputStream fos = new FileOutputStream(destFile);
byte[] buf = new byte[1024];  //创建字节数组,作为临时缓冲
System.out.println("开始复制文件...");
while (fis.read(buf) != -1) {  //循环从文件输入流中读取数据
  fos.write(buf);    //写入到文件输出流中
}
System.out.println("文件复制成功!");
fis.close();    //关闭流
fos.close();

}
}

字符流

• FileInputStram类和FileOutputStream类虽然可以高效率地读/写文件,但对于Unicode编码的文件,使用它们有可能出现乱码;

• 考虑到Java是跨平台的语言,要经常操作Unicode编码的文件,使用字符流操作文件是有必要的;

• 使用字符流将涉及到以下4个类:

FileReader类和FileWriter类;

BufferedReader类和BufferedWriter类。

这四个类你非常容易用到,不要再被各种名称搞混淆,其核心就这么几句话:
读写类要用Buffer类包装,任何的读写都要设置缓存才能实现高效。

可以将这段代码作为例子仔细的研读一番

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;


public class Test11 {


public static void main(String[] args) throws IOException {
    String s="abcd中国家@#$%"+System.getProperty("line.separator")+"asdfsdf顺右面";
    Test11 t=new Test11();
    t.writeFile(s);
    t.readFile();

}

public void readFile() throws IOException{
    File f=new File("r:\\io\\reader.doc");
    FileReader fr=new FileReader(f);
    BufferedReader br=new BufferedReader(fr);
    String ss=null;
    while((ss=br.readLine())!=null){
        System.out.println(ss);
    }
    br.close();
    fr.close();
}

public void writeFile(String s) throws IOException{
    File f=new File("r:\\io\\reader.doc");
    FileWriter fr=new FileWriter(f);
    BufferedWriter br=new BufferedWriter(fr);
    
    br.write(s);
    
    br.close();
    fr.close();
}

}

到目前位置我们已经介绍了两种流,字符和字节,这两种流之间还有过渡流,即:
InputStreamReader, InputStreamWriter
他们是字节流和字符流的桥梁,作用是人为的操作格式编码。

设想这么一种情况:
当你使用System.in 从控制台接受输入的时候,由于in是一个InputStream类型的对象,所以你每一次只能从控制台输入一个字节才不会引起错误,所以必须对in进行处理,才可以顺利的从控制台接受输出,所以将使用:
 InputStreamReader
 BufferedReader
 
•可以使用它来转换System.in,如:
InputStreamReader isr = new InputStreamReader(System.in);
•这样的字符流效率很低,再使用BufferedReader类来为其建立缓冲,如:
BufferedReader br = new BufferedReader(isr);
•这样,就可以从控制台接受输入了。
基本数据类型的读/写

•FileInputStream和FileOutputStream在读写文件时不考虑数据的类型;
•FileWriter和FileReader在读写文件时,将所有的数据都看做字符;
•有时候,我们需要将各种类型的数据写入文件或是从文件中读取,

DataInputStream类和DataOutputStream类可以满足需要。

但是它们不能单独使用,需要配合别的字节流一起使用。

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class Test8 {

public static void main(String[] args) throws Exception {
    File f = new File("r:\\io\\dat.dat");

    FileOutputStream fos = new FileOutputStream(f);
    DataOutputStream dos = new DataOutputStream(fos);
    dos.write(22);
    dos.writeBoolean(true);
    dos.writeChar('a');
    dos.writeUTF("abc中国家####");

    dos.close();
    fos.close();
    
    
    FileInputStream fis=new FileInputStream(f);
    DataInputStream dis=new DataInputStream(fis);
    
  System.out.println(  dis.read());
  System.out.println(  dis.readBoolean());
}

}
ObjectInputStream ObjectOutputStream

作用:用来处理Object对象的流,能将原来只能存于VM中的对象存入到我们要求的储存介质中去,可以用来做数据缓存。
处理的对象都必须实现Serializable,transiant关键字来修饰无需序列化的属性

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Test9 {

public static void main(String[] args) throws Exception {
    File f = new File("r:\\io\\dat2.dat");

    FileOutputStream fos = new FileOutputStream(f);
    ObjectOutputStream dos = new ObjectOutputStream(fos);
    
    Person p=new Person("yy",22);
    
    dos.writeObject(p);

    dos.close();
    fos.close();
    
    FileInputStream fis=new FileInputStream(f);
    ObjectInputStream ois=new ObjectInputStream(fis);
    
    Person ps=(Person)ois.readObject();
    
    System.out.println(ps.getName()+"\t"+ps.getId());
    

}

}

class Person implements Serializable{
private String name;
private transient int id;

public Person() {
    super();
}
public Person(String name, int id) {
    super();
    this.name = name;
    this.id = id;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public int getId() {
    return id;
}
public void setId(int id) {
    this.id = id;
}   

}
RandomAccessFile:随机文件读取

使用场景:支持对随机访问文件的读取和写入
特点:

  • 类中既有读方法也有写方法

  • 必须指定访问文件模式

  • seek()和skip()
    示例:操作日志

    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.RandomAccessFile;
    import java.text.SimpleDateFormat;
    import java.util.Date;

public class Test10 {

public static void main(String[] args) throws IOException {
    BankAccount ba=new BankAccount(1000);
    for(int i=0;i<10;i++){
    ba.withDrawal(100);
    }

}
}


class BankAccount{
private int money;
public BankAccount(int money){
    this.money=money;
}

public void withDrawal(int money) throws IOException{
    this.money=this.money-money;
    log("您取了"+money+",账户余额:"+this.money);
}

private void log(String string) throws IOException {
    File f=new File("r:\\io\\log.txt");
    RandomAccessFile raf=new RandomAccessFile(f,"rwd");
    SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日");
    Date d=new Date();
    String dd=sdf.format(d);
    
    raf.seek(raf.length());
    
    String s="\r\n"+dd+"\t"+string;
    raf.write(s.getBytes("gbk"));
    raf.close();
    
}

}

总结

• java.io包是Java内置的包,其中包含一系列对输入/输出进行操作的类;

• File类的对象可以访问文件(或目录)的属性,但不可以进行读/写操作;

• 从方向上讲,流分为输入流和输出流,但从格式上区分的话,流分为字节流和字符流;

• 使用FileInputStream类和FileOutputStream类以字节流方式对文件进行读/写操作,这是操作文件最基本的两个类;

• FileReader类和FileWriter类配合BufferedReader类和BufferedWriter类可以以字符流方式对文件进行读/写操作;

• 从控制台接受输入要使用到InputStreamReader类和BufferedReader类;

• DataInputStream类和DataOutputStream类允许读/写各种基本数据类型;

• 绝大部分的IO操作都可能抛出IOException。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,587评论 18 399
  • tags:io categories:总结 date: 2017-03-28 22:49:50 不仅仅在JAVA领...
    行径行阅读 2,168评论 0 3
  • 一、流的概念和作用。 流是一种有顺序的,有起点和终点的字节集合,是对数据传输的总成或抽象。即数据在两设备之间的传输...
    布鲁斯不吐丝阅读 10,018评论 2 95
  • 标准输入输出,文件的操作,网络上的数据流,字符串流,对象流,zip文件流等等,java中将输入输出抽象称为流,就好...
    navy_legend阅读 703评论 0 0
  • 那是四个字,“禁止说话”。 宋大伯心下一琢磨,这是监狱里的规矩吧,写在墙上是不让犯人吵闹喧哗以免乱了秩序,要是...
    予安手记阅读 327评论 5 1