目次
6.バイトバッファリングされた出力ストリームBufferedOutputStream
7.バイトバッファリングされた入力ストリームBufferedInputStream
1.IOストリームの概要
- IOストリームは、ファイルのアップロードやファイルのダウンロードなど、デバイス間のデータ転送を処理するために使用されます。
- データに対するJavaの操作は、ストリーミングを介して行われます。
- Javaがフローを操作するために使用するオブジェクトはすべてIOパッケージに含まれています
2.IOフロー分類
2.1データフローによると
- 入力ストリーム:データの読み取り
- 出力ストリーム:データの書き込み
2.2データ型による
- バイトストリーム
- キャラクターストリーム
バイトストリームを選択するのはいつですか?どちらの場合、キャラクターストリームを選択する必要がありますか?
- データが保存されているファイルをWindowsに付属のメモ帳で開き、内部のコンテンツを読み取ることができる場合は、文字ストリームを使用します。他の人はバイトストリームを使用します。
- 何もわからない場合は、バイトストリームを使用してください
3.IOストリームに一般的に使用される基本クラス
3.1バイトストリームの抽象基本クラス
- InputStream
- OutputStream
3.2文字ストリームの抽象基本クラス
- 読者
- 作家
注:これらの4つのクラスから派生したサブクラスの名前には、すべて親クラスの名前の接尾辞が付いています。
例えば:
- FileInputStream、InputStreamのサブクラス、FileOutputStream、OutputStreamのサブクラス
- FileReader、Readerのサブクラス、FileWriter、Writerのサブクラス
4.バイト出力ストリームFileOutputStream
4.1FileOutputStreamの構築方法
- FileOutputStream(File file):指定されたFileオブジェクトによって表されるファイルにデータを書き込むファイル出力ストリームを作成します
- FileOutputStream(String name):指定された名前のファイルにデータを書き込む出力ファイルストリームを作成します
4.1.1要件:データ「hello、io」をファイルに書き込む
4.1.2バイト出力ストリームのステップは何ですか?
- バイト出力ストリームオブジェクトを作成します
- データ入力
- リソースを解放する
コードは次のように表示されます。
package cn.itcast_01;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 需求: 向一个文件中写入数据"hello,io"
*
* @author HW
*/
public class FileOutputStreamDemo {
public static void main(String[] args) {
FileOutputStream fos = null;
try {
// 创建字节输出流对象
fos = new FileOutputStream("fos.txt");
// 写入数据
String str = "hello,io";
fos.write(str.getBytes());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 释放资源
// 只有在fos!=null的时候,才需要释放资源,否则会报空指针异常
if(fos!=null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
4.1.3バイト出力ストリームオブジェクトの作成は正確に何をしましたか?
- システム関数を呼び出してファイルを作成します
- バイト出力ストリームオブジェクトfosを作成します
- バイト出力ストリームオブジェクトfosをこのファイルにポイントします
4.1.4データが正常に書き込まれた後、なぜclose()を閉じるのですか?
- ストリームオブジェクトをガベージにして、ガベージコレクタでリサイクルできるようにします。
- ファイルに関連するリソースを解放するようにシステムに通知します
4.2バイト入力ストリームにデータを書き込む方法
- public void write(int b):指定されたバイトをこのファイル出力ストリームに書き込みます
- public void write(byte [] b):指定されたバイト配列からファイル出力ストリームにb.lengthバイトを書き込みます
- public void write(byte [] b、int off、int len):指定されたバイト配列のオフセットoffから始まるlenバイトをこのファイル出力ストリームに書き込みます。
4.2.1データの断線を実現する方法は?
コードは次のように表示されます。
package cn.itcast_01;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
*如何实现数据的换行?使用换行符\r\n
*
* @author HW
*
*/
public class FileOutputStreamDemo2 {
public static void main(String[] args) {
FileOutputStream fos = null;
try {
// 创建字节输出流对象fos
fos = new FileOutputStream("fos.txt");
// 将指定字节写入fos对象中
fos.write(97);
// 实现换行
fos.write("\r\n".getBytes());
// 将一个字节数组写入fos中
byte[] b = { 97, 98, 99, 100, 101 };
fos.write(b);
fos.write("\r\n".getBytes());
//将字节数组b的从1开始的3个字节写入fos中
fos.write(b, 1, 3);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 释放资源
if(fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
4.2.2データの追加書き込みを実装する方法は?
構築方法を使用します。
- public FileOutputStream(File file、boolean append):指定されたFileオブジェクトによって表されるファイルにデータを書き込むファイル出力ストリームを作成します。2番目のパラメーターがtrueの場合、バイトはファイルの最後に書き込まれます。
package cn.itcast_02;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* 如何实现数据的追加写入?
*
* 使用构造方法:
* public FileOutputStream(File file, boolean append):创建一个向指定File对象表示的文件中写入数据的文件输出流,如果第二个参数为true,则将字节写入文件末尾处;
*/
public class FileOutputStreamDemo2 {
public static void main(String[] args) {
// 声明字节输出流的引用
FileOutputStream fos = null;
try {
// 生成一个代表字节输出流的对象,实现在末尾追加写入数据
fos = new FileOutputStream("fos3.txt", true);
// 调用write()方法,写入数据
for (int x = 0; x < 10; x++) {
fos.write(("Hello" + x).getBytes());
// 实现数据换行
fos.write("\r\n".getBytes());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
// 释放资源
// 只有在fos!=null的时候,才需要释放资源,否则会报空指针异常
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
5.バイト入力ストリームFileInputStream
5.1FileInputStreamの構築方法
- public FileInputStream(ファイルファイル)
- public FileInputStream(String name)
5.2FileInputStreamのメンバーメソッド
- public int read():一度に1バイトを読み取ります。ファイルの最後まで読み取り、それ以上データがない場合は、-1を返します。
- public int read(byte [] b):一度に1バイト配列を読み取り、実際に読み取ったバイト数(長さ)を返します。ファイルの終わりが読み取られ、それ以上データがない場合は、-1が返されます。
バイト入力ストリームの手順は何ですか?
- バイト入力ストリームオブジェクトを作成します
- read()メソッドを呼び出してデータを読み取り、コンソールにデータを表示します
- リソースを解放する
5.2.1一度に1バイトを読み取る
- public int read():一度に1バイトを読み取ります。ファイルの最後まで読み取り、それ以上データがない場合は、-1を返します。
要件1:バイトストリームを含むテキストファイルをコピーし、現在のディレクトリのsrcFile.txtのコンテンツを現在のプロジェクトのdestFile.txtにコピーします
コードは次のように表示されます。
package com.hw.inputstream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* public int read():一次读取一个字节,如果读取到文件的末尾,则返回-1
*
* 需求:字节流复制文本文件,把当前目录下的srcFile.txt中的内容复制到当前项目下的destFile.txt中
* 数据源:srcFile.txt
* 目的地:destFile.txt
*
* @author HW
*
*/
public class CopyFileDemo {
public static void main(String[] args) {
// 声明字节输入流的引用(数据源)
FileInputStream fis = null;
// 声明字节输出流的引用(目的地)
FileOutputStream fos = null;
try {
// 生成代表字节输入流的对象
fis = new FileInputStream("srcFile.txt");
// 生成代表字节输出流的对象
fos = new FileOutputStream("destFile.txt");
// 读取数据,一次读取一个字节,如果读取到文件的末尾,则返回-1
int b = 0;
while ((b = fis.read()) != -1) {
fos.write(b);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 释放资源
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
要件2:現在のプロジェクトディレクトリのsunset.jpgにD:\\ development \\ images \\ lover.jpgをコピーします
コードは次のように表示されます。
package com.hw.inputstream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* public int read():一次读取一个字节的数据,如果读取到文件的末尾,则返回-1
*
* 需求:把D:\\develop\\images\\lover.jpg复制到当前项目目录下的sunset.jpg中
*
* @author HW
*
*/
public class CopyImageDemo {
public static void main(String[] args) {
// 声明字节输入流FileInputStream的引用
FileInputStream fis = null;
// 声明字节输出流FileOutputStream的引用
FileOutputStream fos = null;
try {
// 生成代表字节输入流的对象
fis = new FileInputStream("D:\\develop\\images\\lover.jpg");
// 生成代表字节输出流 的对象
fos = new FileOutputStream("sunset.jpg");
// 复制图片
// 一次读取一个字节的数据,如果读取到文件的末尾,则返回-1
int b = 0;
while ((b = fis.read()) != -1) {
fos.write(b);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 释放资源
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
要件3:現在のプロジェクトディレクトリのvideo.aviにD:\\ development \\ images \\ computerbase.aviをコピーします
コードは次のように表示されます。
package com.hw.inputstream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* public int read():一次读取一个字节的数据,如果读取到文件的末尾,则返回-1
*
* 需求:把D:\\develop\\images\\计算机基础.avi复制到当前项目目录下的video.avi中
*
* @author HW
*
*/
public class CopyVideoDemo {
public static void main(String[] args) {
// 声明字节输入流的引用
FileInputStream fis = null;
// 声明字节输出流的引用
FileOutputStream fos = null;
try {
// 生成代表字节输入流的对象
fis = new FileInputStream("D:\\develop\\images\\计算机基础.avi");
// 生成代表字节输出流的对象
fos = new FileOutputStream("video.avi");
// 复制视频
// 一次读取一个字节的数据
int b = 0;
while ((b = fis.read()) != -1) {
fos.write(b);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
5.2.2一度に1バイトの配列を読み取る
- public int read(byte [] b):一度に1バイト配列を読み取り、実際に読み取ったバイト数(長さ)を返します。ファイルの終わりが読み取られ、それ以上データがない場合は、-1が返されます。
要件1:D:\\ development \\ users.xmlのコンテンツを現在のプロジェクトディレクトリのE:\\ student.xmlにコピーします
コードは次のように表示されます。
package com.hw.inputstream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* public int read(byte[] b):一次读取一个字节数组的数据,返回的是实际读取的字节的长度,如果读取到文件的末尾而没有更多的数据,则返回-1
*
* 需求:把D:\\develop\\users.xml中的内容复制到当前项目目录下的E:\\student.xml中
*
* @author HW
*/
public class CopyFileDemo {
public static void main(String[] args) {
// 声明字节输入流的引用
FileInputStream fis = null;
// 声明字节输出流的引用
FileOutputStream fos = null;
File file = null;
try {
// 生成代表字节输入流的对象
fis = new FileInputStream("D:\\develop\\users.xml");
// 生成代表字节输出流的对象
fos = new FileOutputStream("E:\\student.xml");
// 复制数据,一次读取一个字节数组的数据
// 生成一个byte类型的数组
byte[] b = new byte[1024];
// 实际读取的字节长度
int len = 0;
while ((len = fis.read(b)) != -1) {
fos.write(b, 0, len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 释放资源
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
要件2:現在のプロジェクトディレクトリのvideo.aviにD:\\ development \\ images \\ computerbase.aviをコピーします
コードは次のように表示されます。
package com.hw.inputstream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* public int read(byte[] b):一次读取一个字节数组的数据,返回的是实际读取的字节长度,如果读取到文件的末尾,则返回-1
*
* 需求:把D:\\develop\\images\\计算机基础.avi复制到当前项目目录下的video.avi中
*
* @author HW
*/
public class CopyVideoDemo {
public static void main(String[] args) {
// 声明字节输入流的引用
FileInputStream fis = null;
// 声明字节输出流的引用
FileOutputStream fos = null;
try {
// 生成代表字节输入流的对象
fis = new FileInputStream("D:\\develop\\images\\计算机基础.avi");
// 生成代表字节输出流的对象
fos = new FileOutputStream("video.avi");
// 复制视频,一次读取一个字节数组的数据
// 生成一个byte类型的数组
byte[] b = new byte[1024];
// 实际读取的字节长度
int len = 0;
while ((len = fis.read(b)) != -1) {
fos.write(b, 0, len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 释放资源
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
一度に配列を読み書きするバイトストリームの速度は、一度に1バイトを読み書きする速度よりも明らかにはるかに高速です。これは、配列を追加することによるバッファ効果です。java自体を設計する場合、この設計アイデアは次のようになります。また、考慮されるので、バイトバッファストリームが提供されます!
6.バイトバッファリングされた出力ストリームBufferedOutputStream
具体的な使用法については、次のコードを参照してください。
package com.hw.inputstream;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 字节缓冲输出流BufferedOutputStream
*
* @author HW
*
*/
public class BufferedOutputStreamDemo {
public static void main(String[] args) {
// 声明BufferedOutputStream引用
BufferedOutputStream bos = null;
try {
// 创建字节缓冲输出流对象
bos = new BufferedOutputStream(new FileOutputStream("bos.txt"));
// 写入数据
bos.write("hello,bos!".getBytes());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 释放资源
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
7.バイトバッファリングされた入力ストリームBufferedInputStream
具体的な使用法については、次のコードを参照してください。
package com.hw.inputstream;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* 字节缓冲输入流BufferedInputStream
*
* @author HW
*
*/
public class BufferedInputStreamDemo {
public static void main(String[] args) {
// 声明BufferedInputStream引用
BufferedInputStream bis = null;
try {
// 创建字节缓冲输入流对象
bis = new BufferedInputStream(new FileInputStream("bis.txt"));
// 读取数据,一次读取一个字节数组
// 生成一个byte类型的字节数组
byte[] bytes = new byte[1024];
// 实际读取的字节长度
int len = 0;
while ((len = bis.read(bytes)) != -1) {
// 生成String类型的对象
String str = new String(bytes, 0, len);
System.out.println(str);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
8.バイトストリームコピーMP4とテスト効率の4つの方法
要件:現在のプロジェクトディレクトリのvideo.aviにD:\\ development \\ images \\ computerbase.aviをコピーします
4つの方法でファイルをバイトストリームコピーします:FileInputStream&FileOutputStream、BufferedInputStream&BufferedOutputStream
- 基本的なバイトストリームは、一度に1バイトを読み書きします
- 基本的なバイトストリームは、一度に1バイトの配列を読み書きします
- 効率的なバイトストリームは、一度に1バイトを読み書きします
- 一度に1バイト配列を読み書きするための効率的なバイトストリーム
コードは次のように表示されます。
package com.hw.inputstream;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 需求:把D:\\develop\\images\\计算机基础.avi复制到当前项目目录下的video.avi中
*
* 字节流四种方式复制文件:
* FileInputStream & FileOutputStream
* 1.基本字节流一次读写一个字节,共耗时:46788毫秒
* 2.基本字节流一次读写一个字节数组,共耗时:54毫秒
*
* BufferedInputStream & BufferedOutputStream
* 3.高效字节流一次读写一个字节,共耗时:156毫秒
* 4.高效字节流一次读写一个字节数组,共耗时:12毫秒
*
* @author HW
*
*/
public class CopyVideoTest {
public static void main(String[] args) {
long start = System.currentTimeMillis();
// method1("D:\\develop\\images\\计算机基础.avi", "video.avi");
// method2("D:\\develop\\images\\计算机基础.avi", "video.avi");
// method3("D:\\develop\\images\\计算机基础.avi", "video.avi");
method4("D:\\develop\\images\\计算机基础.avi", "video.avi");
long end = System.currentTimeMillis();
System.out.println("共耗时:" + (end - start) + "毫秒");
}
// 高效字节流一次读取一个字节数组
private static void method4(String srcStr, String destStr) {
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
// 创建字节缓冲输入/输出流对象
bis = new BufferedInputStream(new FileInputStream(srcStr));
bos = new BufferedOutputStream(new FileOutputStream(destStr));
// 一次读取一个字节数组
// 生成一个byte类型的数组
byte[] bytes = new byte[1024];
// 实际读取的字节长度
int len = 0;
while ((len = bis.read(bytes)) != -1) {
bos.write(bytes);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 释放资源
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// 高效字节流一次读取一个字节
private static void method3(String srcStr, String destStr) {
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
// 创建字节缓冲输入/输出流对象
bis = new BufferedInputStream(new FileInputStream(srcStr));
bos = new BufferedOutputStream(new FileOutputStream(destStr));
// 一次读取一个字节
int b = 0;
while((b = bis.read()) != -1) {
bos.write(b);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 释放资源
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// 基本字节流一次读写一个字节数组
private static void method2(String srcStr, String destStr) {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
// 创建字节输入/输出流对象
fis = new FileInputStream(srcStr);
fos = new FileOutputStream(destStr);
// 一次读取一个字节数组
// 生成一个byte类型的数组
byte[] bytes = new byte[1024];
// 实际读取的字节长度
int len = 0;
while ((len = fis.read(bytes)) != -1) {
fos.write(bytes);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 释放资源
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// 基本字节流一次读写一个字节
private static void method1(String srcStr, String destStr) {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
// 创建字节输入/输出流对象
fis = new FileInputStream(srcStr);
fos = new FileOutputStream(destStr);
// 读取数据,一次读取一个字节,如果读取到文件的末尾,则返回-1
int b = 0;
while ((b = fis.read()) != -1) {
fos.write(b);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 释放资源
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}