java-IO-第二章

发布时间:2024年01月21日

?文件复制? ? ?

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

  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语句块来确保程序的稳定性和可靠性。

? ??

文章来源:https://blog.csdn.net/Flying_Fish_roe/article/details/135634668
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。