java-IO-第二章

 文件复制     

      文件复制的原理是通过读取一个文件的内容,然后将其写入到另一个文件中。具体步骤如下:

  1. 创建一个输入流(InputStream)来读取源文件的内容。
  2. 创建一个输出流(OutputStream)来写入目标文件的内容。
  3. 使用缓冲区(Buffer)来提高读写效率,先将源文件的内容读入到缓冲区中。
  4. 将缓冲区中的内容写入到目标文件中。
  5. 重复步骤3和4,直到源文件的内容全部复制到目标文件中。
  6. 关闭输入流和输出流,释放资源。 

     代码示例   


package io;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 文件的复制
 */
public class CopyDemo {
    public static void main(String[] args) throws IOException {
        //创建文件输入流读取原文件
        FileInputStream fis = new FileInputStream("image.jpg");
        //创建文件输出流写入复制文件
        FileOutputStream fos = new FileOutputStream("image_cp.jpg");

        int d;//保存每次读取到的字节
        /*
            原文件数据:
            11000011 10101010 00001111 11001100 00110011 ...
                     ^^^^^^^^
            d = fis.read();
            d:00000000 00000000 00000000 10101010
            fos.write(d);
            复制文件的数据:
            11000011 10101010
         */
        long start = System.currentTimeMillis();//获取当前系统时间的毫秒值(UTC时间)
        while((d = fis.read()) != -1) {
            fos.write(d);
        }

        long end = System.currentTimeMillis();//获取当前系统时间的毫秒值(UTC时间)
        System.out.println("复制完毕!耗时:"+(end-start)+"ms");
        fis.close();
        fos.close();
    }
}

块读写的文件复制操作

     int read(byte[] data)
      一次性从文件中读取给定的字节数组总长度的字节量,并存入到该数组中。
       返回值为实际读取到的字节量。若返回值为-1则表示读取到了文件末尾。

    块写操作
   void write(byte[] data)
   一次性将给定的字节数组所有字节写入到文件中

  void write(byte[] data,int offset,int len)
一次性将给定的字节数组从下标offset处开始的连续len个字节写入文件


package io;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 通过提高每次读写的数据量,减少实际读写的次数,可以提高读写效率。
 * 单字节读写是一种随机读写形式。而一组一组字节的读写是块读写形式。
 */
public class CopyDemo2 {
    public static void main(String[] args) throws IOException {
        //使用块读写形式完成文件复制
        //创建文件输入流读取原文件
        FileInputStream fis = new FileInputStream("wnwb.exe");
        //创建文件输出流写复制文件
        FileOutputStream fos = new FileOutputStream("wnwb_cp.exe");

        /*
            流提供了块读写的方法
            int read(byte[] data)
            一次性从文件中读取给定的字节数组总长度的字节量,并存入到该数组中。
            返回值为实际读取到的字节量。若返回值为-1则表示读取到了文件末尾。

            文件数据
            11001100 11110000 10101010 00001111 00110011
            ^^^^^^^^ ^^^^^^^^ ^^^^^^^^
            int d;
            byte[] data = new byte[3];
            [00000000 00000000 00000000]
            第一次调用
            d = fis.read(data);
            [11001100 11110000 10101010]
            d = 3 本次读取到了3个字节

            文件数据
            11001100 11110000 10101010 00001111 00110011
                                       ^^^^^^^^ ^^^^^^^^
            第二次调用
            d = fis.read(data);//仅读取了最后两个字节
            [00001111 00110011 10101010]//前两个字节为本次读取的内容
             ^^^^^^^^ ^^^^^^^^
            d = 2 本次读取到了2个字节

            文件数据
            11001100 11110000 10101010 00001111 00110011 文件末尾!
                                                         ^^^^^^^^
            第三次调用
            d = fis.read(data);//一个字节都没有读取到
            [00001111 00110011 10101010]数组没变化
            d = -1 文件末尾

            块写操作
            void write(byte[] data)
            一次性将给定的字节数组所有字节写入到文件中

            void write(byte[] data,int offset,int len)
            一次性将给定的字节数组从下标offset处开始的连续len个字节写入文件

         */

        int len;//记录每次实际读取的字节量
        /*
            00000000  1byte   8位2进制称为1字节
            1024byte  1kb
            1024kb    1mb
            1024mb    1gb
         */
        byte[] data = new byte[1024*10];//10kb
        long start = System.currentTimeMillis();
        while((len = fis.read(data))!=-1){
            fos.write(data,0,len);//读取多少就写多少
        }
        long end = System.currentTimeMillis();
        System.out.println("复制完毕!耗时:"+(end-start)+"ms");
        fis.close();
        fos.close();

    }
}

写文本数据

    String提供方法:
    byte[] getBytes(String charsetName)
   将当前字符串转换为一组字节

   参数为字符集的名字,常用的是UTF-8。 其中中文字3字节表示1个,英文1字节表示1个。


package io;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

/**
 * 向文件中写入文本数据
 */
public class WriteStringDemo {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("demo.txt");
        String str = "super idol的笑容都没你的甜,";
        /*
            支持中文的常见字符集有:
            GBK:国标编码。英文每个字符占1个字节,中文每个字符占2个字节
            UTF-8:内部是unicode编码,在这个基础上不同了少部分2进制信息作为长度描述
                  英文每个字符占1字节
                  中文每个字符占3字节

            String提供了将字符串转换为一组字节的方法
            byte[] getBytes(String charsetName)
            参数为字符集的名字,名字不缺分大小写,但是拼写错误会引发异常:
            UnsupportedEncodingException
            不支持      字符集   异常
         */
        byte[] data = str.getBytes("UTF-8");
        fos.write(data);

        fos.write("八月正午的阳光,都没你耀眼。".getBytes("UTF-8"));

        System.out.println("写出完毕!");
        fos.close();
    }
}

文件输出流-追加模式

      重载的构造方法可以将文件输出流创建为追加模式

     - FileOutputStream(String path,boolean append)
     - FileOutputStream(File file,boolean append)

      当第二个参数传入true时,文件流为追加模式,即:指定的文件若存在,则原有数据保留,新写入的数据会被顺序的追加到文件中


package io;

import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 文件流的追加写模式
 */
public class FileAppendDemo {
    public static void main(String[] args) throws IOException {
        /*
            FileOutputStream默认创建方式为覆盖模式,即:如果连接的文件存在,
            则会将该文件原有数据全部删除。然后将通过当前流写出的内容保存到文件中。

            重载的构造方法允许我们再传入一个boolean型参数,如果这个值为true,则
            文件流为追加模式,即:若连接文件时该文件存在,原有数据全部保留,通过当前
            流写出的数据会顺序的追加到文件中。
         */
        FileOutputStream fos = new FileOutputStream(
                "demo.txt",true
        );
        fos.write("热爱105°的你,".getBytes("UTF-8"));
        fos.write("滴滴清纯的蒸馏水。".getBytes("UTF-8"));
        System.out.println("写出完毕!");
        fos.close();
    }
}

读取文本数据


package io;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 * 从文件中读取文本数据
 */
public class ReadStringDemo {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("fos.txt");

        byte[] data = new byte[1024];
        int len = fis.read(data);//块读操作
        System.out.println("实际读取到了"+len+"个字节");
        /*
            String提供了将字节数组转换为字符串的构造方法:
            String(byte[]data,String charsetName)
            将给定的字节数组中所有字节按照指定的字符集转换为字符串

            String(byte[]data,int offset,int len,String charsetName)
            将给定的字节数组从下标offset处开始的连续len个字节按照指定的字符集转换为字符串
         */
        String line = new String(data,0,len,"UTF-8");
        System.out.println(line);
        System.out.println(line.length());

        fis.close();

    }
}

总结   

    文件的读写操作主要是通过输入输出流(IO流)来实现的。IO流分为字节流和字符流两种类型,分别用于处理二进制文件和文本文件。

   读文件操作步骤:

  1. 创建一个文件输入流对象,将要读取的文件与该对象关联起来。可以使用FileInputStreamBufferedInputStream来创建文件输入流对象。
  2. 利用文件输入流对象读取文件内容。可以使用read()方法读取一个字节,或者使用read(byte[] buffer)方法读取多个字节到缓冲区。
  3. 关闭文件输入流。

   写文件操作步骤:

  1. 创建一个文件输出流对象,将要写入的文件与该对象关联起来。可以使用FileOutputStreamBufferedOutputStream来创建文件输出流对象。
  2. 利用文件输出流对象写入文件内容。可以使用write(int b)方法写入一个字节,或者使用write(byte[] buffer)方法写入多个字节。
  3. 关闭文件输出流。

  另外,为了方便处理文本文件,Java还提供了字符流用于处理字符数据,通常与字节流配合使用。常用的字符流有FileReaderFileWriter

    读取文本文件:

  1. 创建一个字符输入流对象,将要读取的文件与该对象关联起来。可以使用FileReaderBufferedReader来创建字符输入流对象。
  2. 利用字符输入流对象读取文本文件内容。可以使用read()方法读取一个字符,或者使用read(char[] buffer)方法读取多个字符到缓冲区。
  3. 关闭字符输入流。

    写入文本文件:

  1. 创建一个字符输出流对象,将要写入的文件与该对象关联起来。可以使用FileWriterBufferedWriter来创建字符输出流对象。
  2. 利用字符输出流对象写入文本文件内容。可以使用write(int c)方法写入一个字符,或者使用write(char[] buffer)方法写入多个字符。
  3. 关闭字符输出流。

    在进行文件读写操作时,需要注意异常处理和资源释放,可以使用try-catch-finally语句块来确保程序的稳定性和可靠性。

    

你可能感兴趣的:(java,开发语言)