IO の概要
1 ストリーム ストリーム
IO ストリームを学習する前に、最初に学習する必要がある概念は ストリーム ストリーム です
。理解を容易にするために、データの読み取りおよび書き込み操作を「パイプ」内を流れるデータとして抽象化できますが、次の点に注意してください
。ストリームは単一の方向フローのみにすることができます
2. 入力ストリームは読み取り→入力に使用されます
3. 出力ストリームは書き込み→出力に使用されます
4. データの読み取りと書き込みは最初から最後まで 1 回のみ可能です
。プログラムの観点から見ると、入/出力はプログラムの入力 (読み取り)/出力 (書き込み) プロセスに関連します。
2 IOストリームの継承構造
Java では、ストリームは、処理されるさまざまなデータ単位に応じて、バイト ストリームと文字ストリームに分類できます。
バイト ストリーム: バイナリ ファイルの場合、
文字ストリーム: テキスト ファイルの場合、
対応するタイプの入力および出力方向と組み合わせると、一般的に使用されるストリームは次のようになります。
File
バイト ストリーム: バイナリ ファイルの場合
InputStream
FileInputStream
BufferedInputStream
ObjectInputStream
OutputStream
FileOutputStream
BufferedOutputStream
ObjectOutputStream
字符流:针对文本文件
Reader
FileReader
BufferedReader
InputStreamReader
Writer
FileWriter
BufferedWriter
OutputStreamWriter
PrintWriter 一行ずつ書き出す
3 ファイル ファイルクラス
3.1 概要
ディスク パス文字列をカプセル化すると、このパスで操作を実行できます。
ファイル パス、フォルダー パス、および存在しないパスをカプセル化できます。
3.2 オブジェクトの作成
File(String pathname) は、指定されたパス名文字列を抽象パス名に変換することにより、新しい File インスタンスを作成します
new File("d:/abc/a.txt");
new File("d:/abc", "a.txt" );
3.3 一般的な方法
3.4 演習: 一般的なメソッドのテスト
パッケージの作成: cn.tedu.file
クラスの作成: TestFile.java
package cn.tedu.file;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
/*本类用于测试文件类File*/
public class TestFile {
public static void main(String[] args) throws IOException {
//1.创建File类对象
/*1.ready目录与1.txt需要自己手动创建
* 2.File需要导包:import java.io.File;
* 3.路径是String类型,必须写正确,不然找不到文件
* 4.完整的文件名包含两部分:文件名+后缀名*/
File file = new File("E:\\ready\\1.txt");
//2.1测试File中的常用方法
System.out.println(file.length());//3,获取文件的字节量
System.out.println(file.exists());//true,判断文件是否存在
System.out.println(file.isFile());//true,判断是否为文件
System.out.println(file.isDirectory());//false,判断是否为文件夹
System.out.println(file.getName());//1.txt获取文件名
System.out.println(file.getParent());//E:\ready 获取父级路径
System.out.println(file.getAbsolutePath());//E:\ready\1.txt 获取带盘符的完整路径:绝对路径
//2.2 测试创建与删除
/*new 只会帮你在内存中创建一个File类型的对象
* 并不会帮你在磁盘中创建一个真实存在的2.txt文件*/
file = new File("E:\\ready\\2.txt");
//创建一个之前不存在的文件2.txt,如果创建成功,会返回true
/*如果指定创建文件的路径不对,会抛出异常:java.io.Exception
* 所以需要提前处理这个问题,我们暂时选择在main()上抛出
* 这个IO异常是目前我们遇到的强制要求必须预先处理的异常
* 如果不处理,方法的调用会报错,通不过编译*/
System.out.println(file.createNewFile());//创建之前不存在的文件
file = new File("E:\\ready\\m");
System.out.println(file.mkdir());//创建之前不存在的单层文件夹
file = new File("E:\\ready\\a\\b\\c");
System.out.println(file.mkdirs());//创建之前不存在的多层文件夹
System.out.println(file.delete());//c被删除,删除空文件夹或者文件
file = new File("E:\\ready\\a");
System.out.println(file.delete());//false,a文件夹不是空的,里面有内容
file = new File("E:\\ready\\2.txt");
System.out.println(file.delete());//2.txt被删除,可以删除文件
//2.3测试展示文件列表
file = new File("E:\\ready");
String[] list = file.list();/*不常用*/
System.out.println(Arrays.toString(list));
//这句话会报错,因为这是一个String[],所以数组中每个元素都是String类型的
//那么只能用String类中的方法,而isDirectory()是File类中的方法
//System.out.println(list[0].isDirectory());
File[] fs = file.listFiles();/*常用*/
System.out.println(Arrays.toString(fs));
System.out.println(fs[0].isDirectory());
}
}
4バイトストリーム読み取り
バイト ストリームはバイトで構成され、文字ストリームは文字で構成されます。Java
の文字は 2 バイトで構成されます。バイト ストリームは、主にバイナリ データの処理に使用される基本的なストリームです。
そのため、バイト ストリームがより一般的に使用され、テキスト ドキュメント/オーディオ/ビデオなど、さまざまな種類のファイルを処理できます。
4.1 InputStream 抽象クラス
この抽象クラスは、バイト入力ストリームを表すすべてのクラスのスーパークラス/抽象クラスであり、オブジェクトを作成することはできません
一般的なメソッド:
abstract int read() 入力ストリームからデータの次のバイトを読み取ります。
int read(byte[] b) 入力ストリームから特定のバイト数を読み取り、バッファ配列 b に格納します。
int read(byte[] b、int off、int len) 入力ストリーム内の最大 len データ バイトをバイト配列に読み取ります。off は保存時のオフセットを意味します。 void close() 入力ストリームを閉じ、ストリームに関連付けられたデータを解放します。 に関連付けられたすべてのシステム
リソース
4.2 FileInputStream のサブクラス
ファイルに直接挿入し、ファイルデータを直接読み取ります
オブジェクトの作成
FileInputStream(File file) - ファイル オブジェクトを直接
渡します ファイル システム内の File オブジェクト ファイルで指定された実際のファイルへの接続を開いて FileInputStream を作成します FileInputStream(String pathname) - 実際のファイルへの接続を開いてパスを渡し
ますファイル システム内のパス名 name で指定されたファイルの FileInputStream を作成します
4.3 BufferedInputStream サブクラス
BufferedInputStream は、別の入力ストリームにいくつかの関数を追加します BufferedInputStream の作成時に、内部バッファ配列 (デフォルト 8k サイズ) が作成されます。ストリーム内のバイトが読み取られるかスキップされると、この内部バッファは必要に応じて、含まれる入力ストリームから一度に複数バイトずつ再充填されます。
オブジェクトを作成する
BufferedInputStream(InputStream in)
は BufferedInputStream を作成し、将来の使用に備えてそのパラメーターである入力ストリームを保存します。
4.4 演習: バイトストリーム読み取りの例
パッケージの作成: cn.tedu.file
クラスの作成: TestIn.java
package cn.tedu.file;
import java.io.*;
/*本类用于练习字节输入流*/
public class TestIn {
public static void main(String[] args) {
//method();//字节流的读取
method2();//高效字节流的读取
}
//本方法用于测试高效字节流的读取
private static void method2() {
//定义一个在本方法中都生效的局部变量in,注意手动初始化,值为null
InputStream in = null;
try {
//1.创建高效字节输入流对象
// InputStream in = new BufferedInputStream(
// new FileInputStream(new File("E:\\ready\\1.txt")));
in = new BufferedInputStream
(new FileInputStream("E:\\ready\\1.txt"));
//2.使用流进行读取
int b;
while ((b= in.read())!= -1){
System.out.println(b);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
//关流操作写在finally{}中
//3.流用完以后一定要关闭!!!
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//本方法用于测试字节流的读取
private static void method() {
//创建一个在本方法都生效的局部变量注意手动初始化
InputStream in = null;
try {
//1.创建字节输入流对象用于读取
//InputStream in = new InputStream();//报错原因:抽象类不可实例化
//InputStream in = new FileInputStream(new File("E:\\ready\\1.txt"));
in = new FileInputStream("E:\\ready\\1.txt");
//2.开始读取
/*read()每次调用都会读取一个字节,如果读到了数据的末尾,返回-1*/
// System.out.println(in.read());
// System.out.println(in.read());
// System.out.println(in.read());
// System.out.println(in.read());
//需求:需要循环读取文件中的所有内容,直至读完
//定义变量,记录读到的数据
int b;
while((b=in.read())!= -1){
System.out.println(b);
}
} catch (Exception e) {
e.printStackTrace();//打印错误信息
/*try-catch结构中的第三个部分:finally{}
* 这部分不论是否捕获到异常,是一定会被执行到的代码,常用于关流*/
}finally {
try {
//3.释放资源,流资源用完必须释放!!!
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
5文字ストリーム読み取り
プレーンテキストデータの処理に使用されることが多く、読み書き時に文字化けが起こりやすいため、読み書き時にはエンコードセットをUTF-8に指定するのがベストです。
5.1 Reader抽象类
文字ストリームを読み取るための抽象クラス。
常用方法:
int read() 単一文字を読み取ります
int read(char[] cbuf) 文字を配列に読み取ります
abstract int read(char[] cbuf, int off, int len) 文字を配列の一部に読み取ります
int read(CharBuffer) target) 指定された文字バッファーへの文字の読み取りを試みます。
abstract void close() ストリームを閉じ、それに関連付けられたすべてのリソースを解放します。
5.2 FileReader サブクラス
文字ファイルを読み取るための便利なクラスです。このクラスのコンストラクターは、デフォルトの文字エンコーディングとデフォルトのバイト バッファ サイズが適切であることを前提としています。これらの値を自分で指定するには、まず FileInputStream 上に InputStreamReader を構築します。
创建对象
FileReader(String fileName) ファイル名を指定してデータを読み取る新しい FileReader を作成します。
FileReader(File file) データを読み取るファイルを指定して新しい FileReader を作成します。
5.3 BufferedReader サブクラス
文字入力ストリームからテキストを読み取り、各文字をバッファリングして、文字、配列、行の効率的な読み取りを実現します。
バッファのサイズを指定することも、デフォルトのサイズを使用することもできます。ほとんどの場合、デフォルト値は十分な大きさです。
创建对象
BufferedReader(Reader in) は、デフォルト サイズの入力バッファを使用して、バッファリングされた文字入力ストリームを作成します。
5.4 演習: 文字ストリームを読み取る場合
パッケージの作成: cn.tedu.file
クラスの作成: TestIn2.java
package cn.tedu.file;
import java.io.*;
/*本类用于测试字符流的读取*/
public class TestIn2 {
public static void main(String[] args) {
//method();//测试普通字符输入流
method2();//测试高效字符输入流
}
//创建一个用于测试高效字符输入流的方法
private static void method2() {
//1.定义一个在本方法都生效的局部变量,手动初始化值null
Reader in=null;
try{
//1.创建高效字符读取流对象
//in = new BufferedReader(new FileReader(new File("E:\\ready\\1.txt")));
in = new BufferedReader(new FileReader("E:\\ready\\1.txt"));
//2.使用流对象
int b;
while((b=in.read())!=-1){
System.out.println(b);
}
}catch (Exception e){
e.printStackTrace();
}finally {
//3.关闭流对象
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//创建一个用于测试普通字符输入流的方法
private static void method() {
//1.1创建一个在本方法中都生效的局部变量,注意初始化值null
Reader in = null;
try {
//1.2创建字符输入流对象,注意需要捕获异常
//Reader in = new Reader();//报错原因:抽象父级不可实例化
//in = new FileReader(new File("E:\\ready\\1.txt"));
in = new FileReader("E:\\ready\\1.txt");
//2.使用流对象
//System.out.println(in.read());
//需求:循环读取文件中的所有内容,只要不是-1,就说明还有数据,继续读取
//3.1定义变量,记录读取到的数据
int b;
while((b = in.read())!= -1){
System.out.println(b);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//3.关流
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
6バイトストリームが書き出される
6.1 OutputStream 抽象クラス
この抽象クラスは、出力バイト ストリームを表すすべてのクラスのスーパークラスです。出力ストリームは出力バイトを受け入れ、これらのバイトを何らかのシンクに送信します。
常用方法:
Void close() は、この出力ストリームを閉じ、このストリームに関連付けられたすべてのシステム リソースを解放します。
Voidlush() は、この出力ストリームをフラッシュし、バッファされたすべての出力バイトを強制的に書き出します。
Void write(byte[ ] b) b.length ワードを書き込みます。 これを書き込みます。指定されたバイト配列からの出力ストリーム
Void write(byte[ ] b,int off ,int len) 指定されたバイト配列のオフセット off から始まる len バイトを出力ストリームに書き込みます
Abstract void write(int b) 指定されたバイトをこれに書き込みます出力ストリーム
6.2 FileOutputStream のサブクラス
ファイルに直接挿入、ファイルデータを直接書き込む
构造方法(创建对象):
FileOutputStream(String name): 指定された名前のファイルにデータを書き込むファイル出力ストリームを作成します
FileOutStream(File file): 指定された File オブジェクトによって表されるファイルにデータを書き込むファイル出力ストリームを作成します
FileOutStream(File file, boolean append): 2 番目のパラメータが true の場合、上書きせずに追加することを意味します。
指定された File オブジェクトで表されるファイルにデータを書き込むファイル出力ストリームを作成します。次のパラメータは、元のファイルの内容を上書きするかどうかを参照します。
6.3 BufferedOutputstream サブクラス
このクラスは、バッファリングされた出力ストリームを実装します。この出力ストリームを設定することにより、アプリケーションは、バイトが書き出されるたびに基礎となるシステムを呼び出すことなく、基礎となる出力ストリームに各バイトを書き込むことができます。
构造方法(创建对象):
BufferedOutputStream(OutputStream out) は、
新しいバッファリングされた出力ストリームを作成して、指定された基になる出力ストリームにデータを書き込みます
6.4 演習: バイト出力ストリームのテスト:
パッケージの作成: cn.tedu.file
クラスの作成: TestOut.java
package cn.tedu.file;
import java.io.*;
/*本类用于测试字节输出流*/
public class TestOut {
public static void main(String[] args) {
method();//用于测试普通字节输出流
//method2();//用于测试高效字节输出流
}
//创建一个用于测试高效字节输出流的方法
private static void method2() {
//1.创建一个在本方法都生效的局部变量,注意手动初始化
OutputStream out = null;
try{
//2.创建高效字节输出流对象
// out = new BufferedOutputStream(new FileOutputStream(new File("E:\\ready\\2.txt")));
out = new BufferedOutputStream(new FileOutputStream("E:\\ready\\2.txt"));
//3.使用流对象--进行写出操作
out.write(97);
out.write(97);
out.write(97);
}catch (Exception e){
e.printStackTrace();
}finally {
//关流操作要放在finally{}中
try {
//4.关流
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//创建一个用于测试普通字节输出流的方法
private static void method() {
//1.创建一个在本方法中都生效的局部变量,注意手动初始化null
OutputStream out = null;
//2.创建try-catch-finally结构,因为IO操作可能会产生异常
try{
//3.创建普通字节输出流对象
//out = new FileOutputStream(new File("E:\\ready\\2.txt"));
//out = new FileOutputStream("E:\\ready\\2.txt");
out = new FileOutputStream("E:\\ready\\2.txt",true);
//4.使用流对象--进行写出操作
out.write(99);//对应ASCII码表中的a
out.write(99);//对应ASCII码表中的b
out.write(99);//对应ASCII码表中的c
}catch (Exception e){
e.printStackTrace();
}finally {
//如果想要代码一定会执行,需要写在finally中
try {
//5.关流操作
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
7文字ストリームの書き出し
7.1 Writer 抽象クラス
文字ストリームを書き込むための抽象クラス
常用方法:
抽象 void close() このストリームを閉じますが、最初にフラッシュします。
Void write(char[ ] cbuf) 文字配列を
書き込みます。 Void write(int c) 単一文字を書き込みます。
Void write(String str) 文字列を書き込みます
。 Void write(String str, int off, int len) 文字列の一部を書き込みます
Abstract void write(char[] cbuf, int off, int len) 文字配列の一部を書き込みます
7.2 FileWriter サブクラスは
、文字ファイルの書き込みに使用される便利なクラスです。このクラスの構築メソッドは、デフォルトの文字エンコーディングとデフォルトのバイト バッファ サイズが受け入れられることを前提としています。これらの値を自分でカスタマイズする必要がある場合は、最初に構築できますFileOutputStream 上 OutputStreamWriter。
构造方法(创建对象):
FileWriter(String filename)
指定されたファイル名に基づいて FileWriter オブジェクトを構築します。
FileWriter(String filename, boolean append)
指定されたファイル名と、書き込まれたデータを追加するかどうかを示すブール値に基づいて FileWriter を構築します。
7.3 BufferedWriter サブクラスは、
文字出力ストリームにテキストを書き込み、個々の文字をバッファリングすることで、個々の文字、配列、文字列を効率的に書き込みます。バッファのサイズを指定することも、デフォルトのサイズを受け入れることもできます。ほとんどの場合、デフォルトは値は十分に大きい
构造方法(创建对象):
BufferedWriter(Writer out) は、
デフォルト サイズの出力バッファを使用して、バッファリングされた文字出力ストリームを作成します。
7.4 演習: 文字出力ストリームのテスト:
パッケージの作成: cn.tedu.file
クラスの作成: TestOut2.java
package cn.tedu.file;
import java.io.*;
/*本类用于测试字符输出流*/
public class TestOut2 {
public static void main(String[] args) {
//method();//用于测试普通字符输出流
method2();//用于测试高效字符输出流
}
//创建一个用于测试高效字符输出流的方法
private static void method2() {
//1.创建一个在本方法都生效的局部变量,值为null,注意手动初始化!!!
Writer out = null;
//2.由于程序可能会抛出异常,所以需要写一个try-catch-finally结构
try{
//存放可能会抛出异常的代码
//3.创建普通字符输出流对象
//out = new BufferedWriter(new FileWriter(new File("E:\\ready\\2.txt")));
//out = new BufferedWriter(new FileWriter("E:\\ready\\2.txt"));
out = new BufferedWriter(new FileWriter("E:\\ready\\2.txt",true));
//4.使用流对象
out.write(100);
out.write(100);
out.write(100);
out.write(100);
out.write(100);
}catch (Exception e){
//匹配并捕获异常
e.printStackTrace();//如果捕获到异常就打印错误信息
}finally {
//一定会被执行到的代码块,常用于关流
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//创建一个用于测试普通字符输出流的方法
private static void method() {
//1.创建一个在本方法都生效的局部变量,值为null,注意手动初始化!!!
Writer out = null;
//2.由于程序可能会抛出异常,所以需要写一个try-catch-finally结构
try{
//存放可能会抛出异常的代码
//3.创建普通字符输出流对象
//out = new FileWriter(new File("E:\\ready\\2.txt"));
//out = new FileWriter("E:\\ready\\2.txt");
out = new FileWriter("E:\\ready\\2.txt",true);
//4.使用流对象
out.write(98);
out.write(98);
out.write(98);
out.write(98);
}catch (Exception e){
//匹配并捕获异常
e.printStackTrace();//如果捕获到异常就打印错误信息
}finally {
//一定会被执行到的代码块,常用于关流
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
8拡張
上記のいくつかのストリームを学習することで、ファイルを展開してコピーしてみることもできます。
パッケージの作成: cn.tedu.file
クラスの作成: TestCopyFile.java
package cn.tedu.file;
import java.io.*;
import java.util.Scanner;
/*本类用于练习文件复制综合案例*/
public class TestCopyFile {
public static void main(String[] args) {
//1.提示并接收用户输入的两个路径
System.out.println("请输入源文件路径");//--被复制的那个文件
String f = new Scanner(System.in).nextLine();
System.out.println("请输入新文件路径:");//--复制好的新文件
String t = new Scanner(System.in).nextLine();
//2.调用创建好的自定义方法完成文件复制
//ZFCopy(f,t);//用字符流完成文件的复制案例
ZJCopy(f,t);//用字节流完成文件的复制案例
}
//利用字节流完成文件复制案例
private static void ZJCopy(String f, String t) {
//1.定义在整个方法都生效的局部变量,注意手动初始化,引用类型默认值为null
InputStream in = null;
OutputStream out = null;
//2.由于代码可能会发生异常,所以需要编写try-catch-finally结构
try{
//3.1创建高效字节输入流对象--FIS的参数是用户传入的源文件路径f
in = new BufferedInputStream(new FileInputStream(f));
//3.2创建高效字节输出流对象--FOS的参数是用户传入的新文件路径t
out = new BufferedOutputStream(new FileOutputStream(t));
//4.利用创建好的流对象完成业务
//4.1定义变量用来保存读到的数据
int b;
//4.2循环读取源文件中的数据,只要不是-1,说明还有数据循环继续
while((b = in.read()) != -1){
//4.3将读到的数据写入到新文件中
out.write(b);
}
System.out.println("恭喜您!文件复制成功!");
}catch (Exception e){
System.out.println("很抱歉!文件复制失败!");
e.printStackTrace();
}finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//利用字符流完成文件复制案例
private static void ZFCopy(String f, String t) {
//1.定义在整个方法中都生效的局部变量,注意手动初始化,默认值为null
Reader in = null;
Writer out = null;
//2.由于代码可能会发生异常,所以需要编写try-catch-finally结构
try{
//3.1创建高效字符输入流对象
in = new BufferedReader(new FileReader(f));
//3.2创建高效字符输出流对象
out = new BufferedWriter(new FileWriter(t));
//4.拿到流对象以后,就可以使用流对象来完成业务了
//4.1定义变量用来保存读到的数据
int b;
//4.2循环读取源文件,直到返回值为-1,说明没有数据了,再结束循环
while ((b=in.read())!=-1) {
//4.3将本轮循环中读到的数据写入到新文件中
out.write(b);
}
System.out.println("恭喜您!文件复制成功!");
}catch (Exception e){
System.out.println("很抱歉!文件复制失败!");
e.printStackTrace();
}finally {
/*关流是有顺序的:如果有多个流,最后创建的流最先关闭
* 多条关流语句需要各自try-catch*/
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
9 概要: IO 継承構造
1.主流分类
1. 方向による分類:入力ストリーム 出力ストリーム(プログラムに対して、プログラムからファイルへの書き込みデータを出力)
2. 伝送形式による分類:バイトストリーム キャラクタストリーム
3. 組み合わせ:バイト入力ストリーム ワードセクション出力ストリーム 文字入力ストリーム 文字出力ストリーム
2.学习方法:在抽象父类中学习通用的方法,在子类中学习如何创建对象
3.字节输入流:
InputStream 抽象クラス。新規にすることはできません。提供する一般的なメソッドを学習するためのスーパークラスとして使用できます。
--FileInputStream 子类,操作文件的字节输入流,普通类
--BufferedInputStream 子类,缓冲字节输入流,普通类
4、字符输入流
Reader は抽象クラスであり、新しいものにすることはできません。リーダーが提供する一般的なメソッドを学習するためのスーパークラスとして使用できます。
--FileReader,子类,操作文件的字符输入流,普通类
--BufferedReader,子类,缓冲字符输入流,普通类
5.字节输出流:
OutputStream 抽象クラスは新しいものではありませんが、提供する一般的なメソッドを学習するためのスーパークラスとして使用できます。
--FileOutputStream 子类,操作文件的字节输出流,普通类
--BufferedOutputStream 子类,缓冲字节输出流,普通类
6.字符输出流
Writer は抽象クラスであり、新しいものにすることはできません。また、Writer が提供する一般的なメソッドを学習するためのスーパークラスとして使用できます。
--FileWriter,子类,操作文件的字符输出流,普通类
--BufferedWriter,子类,缓冲字符输出流,普通类