java IO 流

1.什么是java IO?
通过java一些列文件操作的API,对文件进行读取,写入等操作。即为java IO;这里的文件可以是文本文件,视频,音频,图片等等。

2.什么是IO流
java中操作文件的类,大多叫流(stream)。比如输入的类 InputStream(输入流),输出的类(OutputStream)。为什么叫流呢,其实很形象。比如我们水从一个地方流向一个地方,就形成了水流,而文件呢,是一堆字节。这些字节呢,从硬盘流向程序里面,就形成了一个字节流,即输入流。 而这些类更像一个水管,连接着文件与程序代码。

IO操作图解.png

3.java常用IO类
java中流按流向来分,可以分为两类:
3.1 InputStream:输入流,即将文件读入程序。(文件-->程序,是进入程序,所以为输入流);
3.2 OutputStream:输出流,即将程序中的内容,写入文件。(程序 -->文件 ,是离开程序,所以是输出流)。

4.java 输入流 InputStream
输入流对应的类是InputStream。java API中 ,这是一个抽象类。 其主要的方法有:

  • int read() :读取一个字节,并以int形式返回。
  • int read(byte b[]) :将数据读取入传入的byte数组中,即byte b[]中。返回值 int 为读取的字节的个数。返回-1则表示已经读取到了文件末尾。
  • int read(byte b[], int off, int len) 将数据读取到byte b[]中。起始位置为off,最大读取字节长度为len。
  • void close(); 关闭流。 对应的流是会占用系统资源的,当我们读取完后,需要调用close()方法,关闭流。

InputStram 是抽象类,刚才提到的这些方法大多是抽象方法。抽象类只是定义了方法的规范,具体的实现,可能还需要其子类来完成。

InputStream 常用的子类有:
1)FileInputStream: 文件输入流。
2)BufferedInputStream:缓冲输入流。

接下来我们将具体介绍这两个输入流的操作。

4.1 FileInputStream

FIleInputStream 主要用于读取文件内容。常用的两个构造方法为:
1)FileInputStream(String name) name为文件的全路径(包含文件名)
2)FileInputStream(File file) file为文件对象

代码示例:

/**
     * 测试read 方法
     * @throws IOException
     */

    @Test
    public  void read() throws IOException {
        //FileInputStram 的常用构造方法
        //1) FileInputStream(String name) name为文件的全路径(包含文件名)
        //2)FileInputStream(File file) file为文件对象
        //通过构造方法1)创建对象
        FileInputStream fileInputStream=new FileInputStream("E:/java.txt");
        //读取一个字节
        int i=fileInputStream.read();
        //内容为字节的int值
        System.out.println(i);
        //将字节转换为char ,如果他是英文的话(占一个字节),即可看到内容。
        char a=(char)i;
        System.out.println(a);
        //定义一个数组来存放读取到的字节
        byte[] bytes={};
        //通过read()方法读取全部内容
        int b=0;
        //当存在中文时,一个一个读取,然后打印就会出现乱码的情况
        while((b=fileInputStream.read())!=-1){
            System.out.println((char)b+":"+b);
            bytes=Arrays.copyOf(bytes,bytes.length+1);
            bytes[bytes.length-1]=(byte) b;
        }
        String str=new String(bytes);
        System.out.println(str);
        //关闭流
        fileInputStream.close();
    }

    /**
     * 通过read(byte[] b)一次性读取到byte[]数组中
     * @throws IOException
     */
    @Test
    public  void readByteArray() throws IOException {
        //通过构造方法2)创建对象
        File file=new File("E:/java.txt");
        FileInputStream fileInputStream=new FileInputStream(file);
        //创建字节数组来接收读取到的内容
        byte[] bytes=new byte[(int)file.length()];
        //一次性读取bytes.length个数组。
        fileInputStream.read(bytes);
        //如果编码不是当前项目编码,则指定编码格式
        System.out.println(new String(bytes,"GB2312"));
        //关闭流
        fileInputStream.close();
    }

5.java中输出流
输出流对应的java中的OutputStream。同InputStream类似,OutputStream同样是一个抽象类。主要作用就是写文件,将内容写入文件中。常见的方法有:

  • void write(int b):写入一个字节。
  • void write(byte b[]) :写入一个字节数组。
  • void write(byte b[], int off, int len):写入字节数组内容,开始位置为off,长度为len。
  • void close():关闭流。
  • void flush(): 清理缓冲内容,将内容全部写入文件。

OutputStream中常用的子类有:

  • FileOutputStream :文件输出流,用于写文件。
  • BufferedOutputStream:字节缓冲输出流。

5.1 FileOutputStream 文件输出流

代码示例:

/**
     * write方法:向文件中写单个字节
     */
    @Test
    public void write() throws IOException {
        File file=new File("E:/a.txt");
        FileOutputStream out=new FileOutputStream(file);
        //写入单个字节
        char a='a';
        out.write(a);
        out.write(97);
        out.write(98);
        char num=49;
        out.write(num);

        //写一段话的话 需要循环写
        String str="hello!你好。\n我是FileOutputStream 写入的一段话";
        byte[] bytes=str.getBytes();
        for(byte b:bytes){
            out.write(b);
        }
        //清理缓存
        out.flush();
        //关闭流
        out.close();
    }

    /**
     * 写入byte数组
     */
    @Test
    public void writeByteArray() throws IOException {

        String str="我是通过write(byte[]b)写入的内容";
        FileOutputStream fos=new FileOutputStream("E:/a.txt");
        fos.write(str.getBytes());
        fos.flush();
        fos.close();
    }

    @Test
    public void writeByArrayWidthParam() throws IOException {
        String str="我是通过write(byte[]b,int offset,int len)方法写入的内容";
        File file=new File("E:/a.txt");
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(str.getBytes(),10,str.getBytes().length-10);
        fos.flush();
        fos.close();
    }

OK! 相信通过FileInputStream 和FileOutputStream的例子呢,大家应该都大概知道了文件的输入操作,输出操作该怎么弄啦,大致的方法是什么。
我们接下来呢,就通过FileInputStream 和FileOutputStream来实现一个文件的复制操作。

public static void fileCopy(String from,String to){
        FileInputStream fis=null;
        FileOutputStream fos=null;
        try {
            fis=new FileInputStream(from);
            fos=new FileOutputStream(to);
            byte[] buffer=new byte[1024];

            int size=0;
            while((size=fis.read(buffer))!=-1){
                fos.write(buffer,0,size);
                fos.flush();
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(fos!=null){
                        fos.close();
                }
                if(fis!=null){
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    public static void main(String[] args) {
        fileCopy("D://a//test.java","D://a//a.java");
    }

6.字符流

前面讲到的字节流,处理文本文件还是不是很方便。于是java提供了Reader和Writer。字符输入和输出流,来完善文本文件的读取与写入操作。
字符流是以字符为单位读取文件的。
6.1 InputStreamReader

public class FileReaderAndWriterTest {
    public static void readFile(String filePath){
        FileReader fr=null;
        try {

            fr=new FileReader(filePath);
            char [] buffer=new char[1024];
            int size=0;

            while ((size=fr.read(buffer))!=-1){
                for (int i=0;i<=size;i++){
                    System.out.println(buffer[i]);
                }
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    public static void fileWriter(String filePath){
        FileWriter writer= null;
        try {
            writer = new FileWriter(filePath,true);
            writer.write("\r\n我是FileWriter写入的内容第三行");
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    public static void bufferedReaderTest(String path){
        BufferedReader br=null;
        try {
            br=new BufferedReader(new FileReader(path));
            String str=null;
            while ((str=br.readLine())!=null){
                System.out.println(str);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if (br!=null){
                    br.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
//        readFile("D://a//b.txt");
//        fileWriter("D://a//b.txt");
        bufferedReaderTest("D://a//b.txt");
    }
}

7.序列化与反序列化
把对象转换为字节序列的过程称为对象的序列化。
  把字节序列恢复为对象的过程称为对象的反序列化。
  对象的序列化主要有两种用途:
  1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;
  2) 在网络上传送对象的字节序列。

transient 修饰的属性和static修饰的属性不会被序列化

在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存。比如最常见的是Web服务器中的Session对象,当有 10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,于是Web容器就会把一些seesion先序列化到硬盘中,等要用了,再把保存在硬盘中的对象还原到内存中。

  public static void serziableTest(){
        User user=new User();
        user.setName("张三");
        user.setAge(12);
        user.setBirthday(new Date());
        try {
            ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("D://a//c.txt"));
            oos.writeObject(user);
            oos.writeObject(user);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void readObject() {
        try {
            FileInputStream fis = new FileInputStream("D://a//c.txt");
            ObjectInputStream ois = new ObjectInputStream(fis);
            //判断是否到文件末尾
            while (fis.available() > 0) {
                User u = (User) ois.readObject();
                System.out.println(u);
            }

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

推荐阅读更多精彩内容