Java学习笔记(IO_1)

17 IO

关于IO流,可参见: Java IO流学习总结

17.1 IO流

IO流用来处理设备之间的数据传输。Java对数据的操作是通过流的方式。

  • 流按操作数据分为两种:字节流和字符流;
  • 按流向分为:输入流,输出流。

字节流读取文字字节数据后,不直接操作而是先查指定的编码表,获取对应的文字。再对这个文字进行操作。简单说:字节流+编码表。

17.1.1 IO流常用基类

字节流的抽象基类:InputStream,OutputStream.

字符流的抽象基类:Reader,Writer.

P.S.
由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。
如:InputStream的子类FileInputStream。
如:Reader的子类FileReader。

  • 需求:将一些文字存储到硬盘一个文件中。
  • 记住:如果要操作文字数据,建议优先考虑字符流。
    而且要将数据从内存写到硬盘上,要使用字符流中的输出流:Writer。
    硬盘的数据基本体现是文件,希望找到一个可以操作文件的Writer:FileWriter。

例1:

    import java.io.FileWriter;
    import java.io.IOException;

    public class FileWriterDemo {

        public static void main(String[] args) throws IOException {
            //创建一个FileWriter对象,该对象一被初始化就必须要明确被操作的文件
            FileWriter fw = new FileWriter("F:\\javatest\\IOtest\\demo.txt");

            fw.write("Gabriel1");
            //刷新流对象中缓冲的数据,将数据刷至目的地中
            fw.flush();
            //关闭流资源,但是关闭之前会刷新一次内部缓冲的数据,将数据刷到目的地中,
            //和flush区别:flush刷新后,流可以继续使用,close刷新后,会关闭流
            fw.close();

        }
    }

例2:

    import java.io.FileWriter;
    import java.io.IOException;
    public class FileWriterDemo {

        public static void main(String[] args) {
            FileWriter fw = null;
            try {
                fw =new FileWriter("F:\\javatest\\IOtest\\demo.txt");
                fw.write("abc");
            } catch (IOException e) {
                System.out.println("catch:"+e.toString());
                e.printStackTrace();
            }finally{
                try {
                    if(fw!=null)
                        fw.close();
                } catch (IOException e) {
                    System.out.println("catch:"+e.toString());
                }
            }
        }
    }

将abc写入到demo.txt中。

例3:

public class FileWriterDemo {
    public static void main(String[] args) {
        try {
            FileWriter fw = new FileWriter("F:\\javatest\\IOtest\\demo.txt",true);
            fw.write("a");
            fw.close();
        } catch (IOException e) {
            System.out.println("catch:"+e.toString());
            e.printStackTrace();
        }
    }
}

将a写入到demo.txt中,并接着文字往后写,为“abca”。

- 方式1:
第一种读取方式:使用read()方法读取文本文件数据。

例4:

import java.io.FileReader;
import java.io.IOException;

public class FileReaderDemo {

    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("F:\\javatest\\IOtest\\demo.txt");
        //调用读取流对象的read方法,一次读一个字符,每次调用自动往下读
        while(true){
            int ch = fr.read();
            if(ch==-1)
                break;
            System.out.println("ch:"+(char)ch);
        }
        fr.close();
    }
}

运行结果:

- 方式2:
第二种读取方式:使用read(char[])方法读取文本文件数据。

例5:

public class FileReaderDemo {

    public static void main(String[] args) throws IOException {
        char[] buf = new char[2];
        FileReader fr = new FileReader("F:\\javatest\\IOtest\\demo.txt");
        int num = 0;
        while((num=fr.read(buf))!=-1){
            System.out.println("num:"+num+".."+new String(buf,0,num));
        }
        fr.close();
    }
}

运行结果:

拷贝
  1. 在D盘创建一个文件,用于存储C盘文件中的数据;
  2. 定义读取流和C盘文件关联;
  3. 通过不断的读写完成数据存储;
  4. 关闭资源。

方法一:
例6:

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class CopeTest {

    public static void main(String[] args) throws IOException {
        copy_1();
    }

    public static void copy_1() throws IOException{
        FileWriter fw = new FileWriter("D:\\RuntimeDemo_copy.txt");
        FileReader fr = new FileReader("F:\\javatest\\Circle.java");

        int ch = 0;
        while((ch=fr.read())!=-1){
            fw.write(ch);
        }
        fw.close();
        fr.close();
    }
}

方法二:
例7:

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class CopeTest {

    public static void main(String[] args) throws IOException {
        copy_1();
    }

    public static void copy_1() throws IOException{
        FileWriter fw = null;
        FileReader fr = null;

        fw = new FileWriter("D:\\RuntimeDemo_copy.txt");
        fr = new FileReader("F:\\javatest\\BasicGeneric.java");

        char[] ch = new char[1024];
        int len = 0;
        while((len=fr.read(ch))!=-1){
            fw.write(ch,0,len);
        }
        fw.close();
        fr.close();
    }
}
缓冲区

缓冲区的出现提高了对数据的读写效率。

对应类:

  • BufferedWriter
  • BufferedReader

P.S.
缓冲区要结合流才可以使用。
作用:在流的基础上对流的功能进行了增强。

例8:

import java.io.*;

public class BufferedReaderDemo {

    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("F:\\javatest\\BasicGeneric.java");

        BufferedReader bufr = new BufferedReader(fr);
        String line = null;
        while((line=bufr.readLine())!=null){
            System.out.println(line);
        }
        bufr.close();
    }
}

例9:

import java.io.*;

public class CopeMp {

    public static void main(String[] args) throws IOException {
        long start = System.currentTimeMillis();
        copy_1();
        long end = System.currentTimeMillis();

        System.out.println((end-start)+"毫秒");
    }

    public static void copy_1() throws IOException{
        BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("C:/Users/Administrator/Desktop/[解读中国经济].林毅夫.扫描版(ED2000.COM).pdf"));
        BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("D:\\Demo_copy.pdf"));

        int by = 0;
        while((by=bufis.read())!=-1){
            bufos.write(by);
        }
        bufos.close();
        bufis.close();
    }
}

例10:

import java.io.IOException;
import java.io.InputStream;

public class ReadInTest {

    public static void main(String[] args) throws IOException {
        InputStream in = System.in;
        StringBuilder sb = new StringBuilder();

        while(true){
            int ch = in.read();
            if(ch=='\r'){
                continue;
            }
            if(ch=='\n'){
                String s = sb.toString();
                if("over".equals(s))
                    break;
                System.out.println(s.toUpperCase());
                sb.delete(0, sb.length());
            }
            else
                sb.append((char)ch);
        }
    }
}

运行结果:将输入的字符串转成大写输出

File类
  1. 创建

    • boolean createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回false;和输出流不一样,输出流对象一建立即创建文件,而且文件已经存在,会覆盖;
    • boolean mkdir():创建文件夹;
    • boolean mkdirs():创建多级文件夹。
  2. 删除

    • boolean delete():删除失败返回false;
    • void deleteOnExit():在程序退出时删除指定文件。
  3. 判断
    • boolean exists():文件是否存在。
    • isFile();
    • isDirectory();
    • isHidden();
    • isAbsolute()
  4. 获取
    • getName();
    • getPath();
    • getParent();
    • getAbsolutePath();
    • lastModified();
    • length();

例11:

        import java.io.File;
        import java.io.IOException; 

        public class FileDemo {
            public static void main(String[] args) throws IOException {
                method();
                method_1();
                method_2();
                method_3();
            }

            public static void method() throws IOException{
                File f = new File("a.txt");
                write("create:"+f.createNewFile());
                //write("delete:"+f.delete());
            }

            public static void method_1(){
                File f = new File("FileDemo.java");
                f.mkdir();
                write("execute:"+f.canExecute());
            }

            public static void method_2(){
                File f = new File("file.java");
                //f.mkdir();
                //判断文件对象是否是文件或者目的时,
                //必须要先判断该文件对象封装的内容是否存在。
                write(f.exists());
                write("execute:"+f.isDirectory());
                write("execute:"+f.isFile());
                write(f.isAbsolute());  
            }   

            public static void method_3(){
                File f = new File("b.java");
                write("path:"+f.getPath());
                write("absolutepath"+f.getAbsolutePath());
                write("parent:"+f.getParent());//该方法绝对路径中的父目录,获得相对路径则返回null

            }

            public static void write(Object obj){
                System.out.println(obj);
            }
        }

第二次运行结果:

例12:

import java.io.File;
import java.io.FilenameFilter;

public class FielDemo2 {

    public static void main(String[] args) {
        listRootsDemo();
        listDemo();
        File f = new File("E:/IELTS");
        show(f,0);
    }

    public static void listDemo(){
        File f = new File("d:\\software");

        String[] names = f.list();
        for(String name:names){
            System.out.println(name);
        }
    }

    public static void listRootsDemo(){
        File[] files = File.listRoots();

        for(File f:files){
            System.out.println(f);
        }
    }

    public static void show(File dir,int level){
        System.out.println(getLevel(level)+dir.getName());
        level++;
        File[] files = dir.listFiles();
        for(int x=0;x<files.length;x++){
            if(files[x].isDirectory()){
                show(files[x],level);//递归法          
            }
            if(files[x].isFile())
            System.out.println(getLevel(level)+files[x]);           
        }
    }
    public static String getLevel(int level){
        StringBuilder sb = new StringBuilder();
        sb.append("|--");
        for(int i=0;i<level;i++){
            sb.insert(0, "   ");
        }
        return sb.toString();
    }
}

运行结果:

例13(查询文件数量):

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class CreatFileList {

    public static void main(String[] args) throws IOException {
        File dir =  new File("F:/javatest");
        List<File> list = new ArrayList<File>();
        fileToList(dir,list);

        File file = new File(dir,"javalist.txt");
        writeToFile(list,file.toString());
    }

    public static void fileToList(File dir,List<File> list){
        File[] files = dir.listFiles();

        for(File file:files){
            if(file.isDirectory())
            {
                fileToList(file,list);
            }
            if(file.getName().endsWith(".java"))
                list.add(file); 
        }
    }
    public static void writeToFile(List<File> list,String javaListFile) throws IOException{
        BufferedWriter bufw = null; 
        try {
            bufw =  new BufferedWriter(new FileWriter(javaListFile));
            for(File f:list){
                String path = f.getAbsolutePath();
                bufw.write(path);
                bufw.newLine();
                bufw.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            if(bufw!=null){
                bufw.close();
            }
        }
    }
}

运行结果:将F:/javatest目录下所有的.java文件的地址打印到F:/javatest/javalist.txt中。

Properties集合

Map

  • |–Hashtable
  • |–Properties

特点:

  1. 该集合中的键和值都是字符串类型。
  2. 集合中的数据可以保存到流中,或者从流中获取。
  3. 通常该集合用于操作以键值对形式存在的配置文件。
    Properties集合的存和取。

例14:

    import java.io.*;
    import java.util.Properties;
    import java.util.Set;

    public class PropertiesDemo {

        public static void main(String[] args) throws IOException {
            setAndGet();
            method_1();
        }

        public static void method_1() throws IOException{
            BufferedReader bufr = new BufferedReader(new FileReader("info.txt"));
            String line = null;
            Properties prop = new Properties();
            while((line=bufr.readLine())!=null){
                if(line.startsWith("#"))
                    continue;
                String[] arr = line.split("=");
                prop.setProperty(arr[0], arr[1]);
            }
            bufr.close();
            System.out.println(prop);
        }
        public static void setAndGet() throws IOException{
            Properties prop = new Properties();

            prop.setProperty("Gabriel","20");
            prop.setProperty("Mary","12");
            prop.setProperty("Lucy","11");
            prop.setProperty("Gabriel", "5");
            FileOutputStream fos = new FileOutputStream("info.txt");
            prop.store(fos, "name+age");
            fos.close();
            Set<String> names = prop.stringPropertyNames();
            for(String name:names){
                String value = prop.getProperty(name);
                System.out.println(name+" "+value);
            }
        }
    }

运行结果:

例15:

计数器:获取一个应用程序的运行次数,超过5次则提醒已使用超限。

import java.io.*;
import java.util.Properties;

public class RunCount {

    public static void main(String[] args) throws IOException {
        Properties prop = new Properties();
        File file =  new File("count.ini");
        if(!file.exists())
            file.createNewFile();

        FileInputStream fis = new FileInputStream(file);
        prop.load(fis);

        int count = 0;
        String value = prop.getProperty("time");

        if(value!=null){
            count = Integer.parseInt(value);
            if(count>=5){
                System.out.println("使用次数超限");
                return;
            }
        }
            count++;
        prop.setProperty("time", count+"");

        FileOutputStream fos = new FileOutputStream(file);
        prop.store(fos, "count");

        fos.close();
        fis.close();
    }
}
打印流

PrintWriter与PrintStream:可以直接操作输入流和文件。

  • PrintStream为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。
  • 与其他输出流不同,PrintStream永远不会抛出IOException。
  • PrintStream打印的所有字符都使用平台的默认字符编码转换为字节。
  • 在需要写入字符而不是写入字节的情况下,应该使用PrintWriter类。

PrintStream:

  1. 提供了打印方法可以对多种数据类型值进行打印,并保持数据的表示形式
  2. 它不抛IOException

构造函数,接收三种类型的值:

  1. 字符串路径
  2. File对象
  3. 字节输出流

PrintWriter:字符打印流

构造函数参数:

  1. 字符串路径
  2. File对象
  3. 字节输出流
  4. 字符输出流

例16:

    import java.io.*;

    public class PrintStreamDemo {

        public static void main(String[] args) throws IOException {
            BufferedReader bufr = 
                    new BufferedReader(new InputStreamReader(System.in));

            PrintWriter out = new PrintWriter(new FileWriter("a.txt"),true);

            String line = null;

            while((line=bufr.readLine())!=null){
                if("over".equals(line)){
                    break;
                }
                out.println(line.toUpperCase());
            }
            out.close();
            bufr.close();
        }
    }

序列流
SequenceInputStream:对多个流进行合并。

例17:

    import java.io.*;
    import java.util.Enumeration;
    import java.util.Vector;

    public class SequenceDemo {

        public static void main(String[] args) throws IOException {
            Vector<FileInputStream> v = new Vector<FileInputStream>();

            v.add(new FileInputStream("F:\\JavaProject\\TestIO\\1.txt"));
            v.add(new FileInputStream("F:\\JavaProject\\TestIO\\2.txt"));
            v.add(new FileInputStream("F:\\JavaProject\\TestIO\\3.txt"));

            Enumeration<FileInputStream> en = v.elements();
            SequenceInputStream sis = new SequenceInputStream(en);

            FileOutputStream fos = new FileOutputStream("F:\\JavaProject\\TestIO\\4.txt");

            byte[] buf = new byte[1024];

            int len = 0;
            while((len=sis.read(buf))!=-1){
                fos.write(buf,0,len);
            }
            fos.close();
            sis.close();
        }
    }

例18:合并与分割文件:

import java.io.*;
import java.util.*;

public class SplitFile {

    public static void main(String[] args) throws IOException {
        splitFile();
        merge();
    }

    public static void merge() throws IOException{//合并文件
        ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
        //将碎片文件和流对象添加并存储在集合中
        for(int x=1;x<=3;x++){
            al.add(new FileInputStream("F:\\JavaProject\\TestIO\\"+x+".part"));     
        }

        final Iterator<FileInputStream> it = al.iterator();

        //多个流合并为序列流
        Enumeration<FileInputStream> en = new Enumeration<FileInputStream>(){
            public boolean hasMoreElements(){
                return it.hasNext();
            }
            public FileInputStream nextElement() {
                return it.next();
            }
        };//匿名类
        SequenceInputStream sis = new SequenceInputStream(en);

        FileOutputStream fos =  new FileOutputStream("F:\\JavaProject\\TestIO\\0.bmp");
        byte[] buf = new byte[1024];
        int len  = 0;
        while((len=sis.read(buf))!=-1){
            fos.write(buf, 0, len);
        }
        fos.close();
        sis.close();

    }

    public static void splitFile() throws IOException{ //分割文件
        FileInputStream fis = new FileInputStream("F:\\JavaProject\\TestIO\\1.jpg");
        FileOutputStream fos = null;

        byte[] buf = new byte[1024*20];

        int len = 0;
        int count = 1;
        while((len=fis.read(buf))!=-1){
            fos = new FileOutputStream("F:\\JavaProject\\TestIO\\"+(count++)+".part");
            fos.write(buf, 0, len);
            fos.close();
        }
        fis.close();
    }
}
管道流

PipedInputStream和PipedOutputStream:输入输出可以直接进行连接,通过结合线程使用。

例19:

import java.io.*;

public class PipedStreamDemo {
    public static void main(String[] args) throws IOException {
        PipedInputStream in = new PipedInputStream();
        PipedOutputStream out = new PipedOutputStream();
        in.connect(out);

        Read r = new Read(in);
        Write w = new Write(out);

        new Thread(r).start();
        new Thread(w).start();
    }
}

class Read implements Runnable{
    private PipedInputStream in;
    Read(PipedInputStream in){
        this.in = in;
    }
    public void run() { 
        try {
            byte[] buf = new byte[1024];
            int len = in.read(buf);
            String s = new String(buf,0,len);
            System.out.println(s);
            in.close();
        } catch (IOException e) {
            throw new RuntimeException("管道读取失败");
        }
    }
}

class Write implements Runnable{
    private PipedOutputStream out;
    Write(PipedOutputStream out){
        this.out=out;
    }
    public void run() {     
        try {
            Thread.sleep(2000);
            out.write("piped".getBytes());
            out.close();
        } catch (Exception e) {
            throw new RuntimeException("管道输出流失败");
        }
    }
}

运行结果:piped

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值