Java的第一遍学习笔记 IO流

Posted Acc222222

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java的第一遍学习笔记 IO流相关的知识,希望对你有一定的参考价值。

文件

常见的文件操作 

方式一

    public static void main(String[] args) {
        File newFile2 = new File("d:\\\\news2.txt"); //一个 \\ 为转义字符
        try {
            newFile2.createNewFile(); //会抛出一个异常 ,返回值是一个布尔值
            System.out.println("文件创建成功");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

注意这里的File对象,只是一个对象,只有在执行createNewFile方法,才会真正创建文件。 

方式二

public static void main(String[] args) {
        File newFile1 = new File("d:\\\\","news2.txt"); //注意不能写成d,可以写成d:/
        try {
            newFile1.createNewFile(); //会抛出一个异常
            System.out.println("文件创建成功");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

方式三(不常用)

    public static void main(String[] args) {
        File file = new File("d:\\\\");
        File newFile3 = new File(file,"news3.txt");
        try {
            newFile3.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

其它常用方法

    public static void main(String[] args) {
        File file = new File("d:\\\\news1.txt");
        System.out.println(file.getName()); //获取文件名 news1.txt
        System.out.println(file.getParent()); //文件父级目录  d:\\
        System.out.println(file.length()); // 文件大小(字节)
        System.out.println(file.exists()); // 文件是否存在 (因为上面已经创建所以为T)
        System.out.println(file.isFile()); // 是不是一个文件 T
        System.out.println(file.isDirectory()); //是不是一个目录 F
    }

 删除 

    public static void main(String[] args) {
        File file = new File("d:\\\\news1.txt"); 
        if(!file.exists()){ 
            System.out.println("d:\\\\nes1.txt"); 
        }else{
            if(file.delete()){ // delete删除文件
                System.out.println("删除成功");
            }else{
                System.out.println("删除失败");
            }
        }
    }

 创建一级目录 

    public static void main(String[] args) {
        // 注意在Java里目录(文件夹)也算是文件
        File file = new File("d:\\\\demo02");
        if(file.exists()){
            System.out.println("文件夹存在");
        }else{
            file.mkdir(); //创建单极目录,当然mkdirs也行
        }
    }

 创建多级目录 

    public static void main(String[] args) {
        // 注意在Java里目录(文件夹)也算是文件
        File file = new File("d:\\\\demo02\\\\demo03");
        if(file.exists()){
            System.out.println("文件夹存在");
        }else{
            file.mkdirs(); //创建多级目录
        }
    }

IO流 

原理

注:1. Java的IO流总共涉及40多个类,实际上非常规则,都是从上面的四个抽象基类派生的。

       2. 由这四个类派生出来的子类名称都是以其父类名作为子类名后缀。 

流与文件的类似关系:

InputStream

FileInputStream 

  用read读取单个字节 read()

    public static void main(String[] args) { //用read读取单个字节
        int readData = 0; //注意这里,readData初始化为int类型,因为读入的是字符码
        FileInputStream fis = null; //不初始化会报错
        try {
            //创建 FileInputStream对象,用于读取文件
            fis = new FileInputStream("d:\\\\test1.txt");
            //从该输入流读取一个字节的数据,如果没有输入可用,此方法返回-1,表示读取完毕
            while((readData = fis.read()) != -1){ //持续读入
                System.out.print((char)readData);  //输出时转换为char类型
            }
        } catch (IOException e) {
            //IOException包括一切IO异常,用别的read和FileInputStream只能管一个
            e.printStackTrace();
        } finally {
            //关闭文件流,释放资源
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    但是这种方法不适用于汉字的读取,因为在UTF-8中,一个汉字是由二到三个字符码编成的,如果按字节读取,会导致乱码。

    用read读取多个字节:read(byte[])  每次能读取byte数组容量(N)个字节

    public static void main(String[] args) {
        int readLen;
        byte[] buf = new byte[8]; //一次读取8个字节
        FileInputStream fis = null; //不初始化会报错
        try {
            //创建 FileInputStream对象,用于读取文件
            fis = new FileInputStream("d:\\\\test1.txt");
            //从该输入流读取一个字节的数据,如果没有输入可用,此方法返回-1,表示读取完毕
            while((readLen = fis.read(buf)) != -1){ //如果读取正常,返回实际读取的字节数
                System.out.print(new String(buf,0,readLen)); 
                           //注意不能用buf.length,会有额外字节
            }
        } catch (IOException e) {
            //IOException包括一切IO异常,用别的read和FileInputStream只能管一个
            e.printStackTrace();
        } finally {
            //关闭文件流,释放资源
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

OutPutStream

FileOutputStream

    public static void main(String[] args) {
        String filePath = "d:\\\\a.txt";
        //如果不存在这个文件,会自动创建
        FileOutputStream fos = null;
        String str = "Hello,world!";
        try {
            fos = new FileOutputStream(filePath);
         //   fos.write('a'); 输入一个字符
  // 写入字符串方法:str.getBytes() 可以把 字符串-> 字节数组
            fos.write(str.getBytes());
            fos.write(str.getBytes(),2,3);
            //从索引为2的地方开始追加3个字节。
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

注:1. write(byte[] b,int off,int len){} 将len个字节从off索引开始写入文件

       2. new FileOutputStream(filePath) 这样的创建方式会把写入的内容覆盖原来的内容。

       3. new FileOutputStream(filePath,true) 这样的创建方式,当写入内容会追加到文件后面。

       4. FileOutputStream和FileInputStream都是字节处理流,可以处理二进制文件和文本文件。

 复制一个文件(图像等) 

    public static void main(String[] args) {
        FileInputStream  fileInputStream = null; //输入流
        FileOutputStream fileOutputStream = null; //输出流
        try {
            fileOutputStream = new FileOutputStream("d:\\\\test2.txt");
            fileInputStream = new FileInputStream("d:\\\\test1.txt");
            byte[] b = new byte[1024]; //边读边写
            int len;
            while((len = fileInputStream.read(b)) != -1){
                fileOutputStream.write(b,0,len); //不能用b,因为可能有没有用到的空间
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                fileOutputStream.close();
                fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

FileReader

FileWriter

 

FileWriter和FileReader是节点流中的字符流,处理字符,不能处理二进制文件,只能处理文本文件。 

节点流和处理流

节点流图解: 

包装流图解:

对包装流的模拟:

class BufferReader_{ //这个就是个包装类
    private Reader_ reader_; //包装了一个Reader_类型的属性

    public Test(Reader_ reader_) {
        this.reader_ = reader_;
    } //构造器

    public static void main(String[] args) {
        BufferReader_ test = new BufferReader_(new StringReader_()); 
      //根据多态可以传入各种 节点流
        test.reader_.readString(); //调用相关方法
    } 
}

abstract class Reader_{
    public void readFile(){}
    public void readString(){}
} //定义抽象类,后面在调用时,用动态绑定机制

class FileReader_ extends Reader_{ //文件读取类
    @Override
    public void readFile(){
        System.out.println("对文件进行读取");
    }
}

class StringReader_ extends Reader_{ //字符串读取类
    @Override
    public void readString() {
        System.out.println("对字符串进行读取");
    }
}

 也可以在 BufferReader_中 添加各种读取方法: 

    public void readFiles(int num){
        for(int i=0;i<num;i++){
            reader_.readFile();
        }
    }

BufferedReader 

 注:1. readLine方法读取一行,读取完毕返回null。

        2. BufferedReader的关闭只需要关闭包装流,节点流在包装流关闭后会自动关闭。

注:

new FileWriter(filePath,true);  //表示以追加的方式写入
new FileWriter(filePath);  // 表示以覆盖的方式写入

 2. BufferedReader 和 BufferedWriter 是安装字符操作。不要去操作二进制文件(声音,视频,doc等),可能造成文件损坏。

BufferedInputStream和BufferedOutputStream

前面的Buffered使用writer和reader,这个Buffered使用 FileInputStream和FileOutputStream

ObjectInputStream和ObjectOutputStream 

    假如说我们只想把"10"这个数存到文件里,那么只是保存值,用不上ObjectInputStream。但如果想把值和数据类型都保存,比如Dog类或者"int a = 10",那么就需要用到了。

   ObjectOutputStream提供 序列化功能。  ObjectInputStream提供 反序列化功能。

注:Dog类需要实现Serializable接口

class Dog implements Serializable{
    ...
}

值得注意的是:1. 读取顺序必须和write顺序一致。 2. 读取自定义类时,这个类需要能被访问到。 

3. ObjectInputStream和ObjectOutputStream都是只关闭外流就可以了。

标准输入输出流

public final static InputStream in = null;

public final static PrintStream out = null;

System.in 编译类型:InputStream,运行类型:BufferedInputStream。表示的是标准输入 键盘

System.out 编译类型:PrintStream,运行类型:PrintStream。 表示的是标准输入 显示器

转换流 

默认情况下,读取文件是按照UTF-8编码,如果文件按照别的方式编码,就很容易读取到乱码。

 

包装:其实就是转换。 

String filePath = "d:\\\\a.txt";
InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath,"gbk"));
//注意文件编码格式是啥,就转化成啥格式
BufferedReader br = new BufferedReader(isr); //包装转换流,转换成字符流

String s = br.readLine();
br.close(); //关闭外层流

打印流

只有输出流,没有输入流。

        PrintStream out = new PrintStream(System.out);
        out.println("hello");
        out.write("你好,世界".getBytes());
        //print底层调用的是write,所以可以直接调用write进行打印
        out.close(); //注意由于out是System.out,这个一结束,sout就不能用了
        System.out.println("wowowo"); //无法输出
        PrintStream out2 = new PrintStream("d:\\\\a.txt");
        System.setOut(out2);
        //修改打印流输出的位置
        System.out.println("1111"); //输出到文件当中
    public static void main(String[] args) throws IOException {
        FileWriter fileWriter = new FileWriter("d:\\\\a.txt");
        PrintWriter printWriter = new PrintWriter(fileWriter);
        printWriter.print("hello,world!!!!!!");
        printWriter.flush();
        //printWriter.close(); //flush或者close调用一个,才能输入进去
    }

Properties  

注:键值对不需要有空格,值不需要用引号引起来,值的默认类型是String。

     store方法的第二个参数是注释,null表示没有注释。在store方法中,如果没有这个文件就是创建,如果有这个文件就是修改。

以上是关于Java的第一遍学习笔记 IO流的主要内容,如果未能解决你的问题,请参考以下文章

java缓冲字符字节输入输出流:java.io.BufferedReaderjava.io.BufferedWriterjava.io.BufferedInputStreamjava.io.(代码片段

Java IO学习第一天部分详解

Java 学习笔记 - IO篇:常见的IO流Stream以及相互关系

Java IO流 学习笔记

Java IO流 学习笔记

io系列之字符流