【Java】流处理
“什么是流媒体”
-
- データの流れ
入出力先にかかわらずデータの連なりとして同じように操作することができる
入力(受け取り)/ 出力(書き出し)ストリーム
文字ストリーム / バイナリストリーム
- 基本クラスをもとに操作対象に応じ操作クラスを提供している
文件写入
ファイルオープン
BufferedWriterクラスのnewBufferedWriterメソッドを使う(Bufferは文字列データを一時的に保存するメモリ領域)
引数にStandardOpenOption.APPEND指定で追記モード
ファイル出力
writeメソッド
データをBufferに保存して溜まったらまとめてファイル出力
newLineメソッドで改行区切り(Unixは\n,Windowsは\r\n)
Files.writeメソッドで文字列リストをまとめてファイルに書き込みできる
Files.write(Paths.get(“./data.log”),list,StandardCharsets.UTF_8);
ファイルクローズ
try-with-resources構文を使う
tryで生成されたオブジェクトはブロックを抜けたら自動で破棄される!(途中のエラーでcloseメソッドが呼び出されない場合でも大丈夫)
//実行時間を./data.logに記録
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
//import java.nio.file.StandardOpenOption;
import java.time.LocalDateTime;
public class Main {
public static void main(String[] args) {
try (var writer = Files.newBufferedWriter(Paths.get("./data.log"))) {
//ファイル追記
//try (var writer = Files.newBufferedWriter(Paths.get("./data.log"), StandardOpenOption.APPEND)) {
writer.write(LocalDateTime.now().toString());
// 改行文字を統一する場合
//write(LocalDateTime.now().toString()+"\r\n");
writer.newLine();
} catch (IOException e) {
e.printStackTrace();
}
}
}
文件输入
BufferedReaderクラスのnewBufferedReaderメソッドを使う
readLineメソッドでファイルポインタで1行ずつ読みとり現在行の文字列を返す
ファイルポインター:現在位置の目印。ファイルオープン時にファイル先頭にある。次の行がない場合にnullを返す
Files.readAllLinesメソッドでは、ファイル内容を行単位でまとめてリスト取得できる。ファイルサイズが大きい場合メモリの消費が激しい
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
public class Main {
public static void main(String[] args) {
try (var reader = Files.newBufferedReader(Paths.get("./sample.txt"))) {
var line = "";
while ((line = reader.readLine()) != null) {
//ファイルの中身を
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
读写二进制文件
BufferedInputStream / BufferedOutputStream
バッファー機能を備えたバイトストリーム
ファイルへの入出力はFileInputStream / FileOutputStream
ストリームへの読み書きは read / writeメソッド
readの戻り値はバイトデータ(0~255)
ストリーム終端は-1を返す
//input.pngをBufferedInputStreamで読み込み
//結果をBufferedOutputStreamでoutput.pngに出力
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
try (
var in = new BufferedInputStream(
new FileInputStream("./input.png"));
var out = new BufferedOutputStream(
new FileOutputStream("./output.png"))) {
var data = -1;
while ((data = in.read()) != -1) {
out.write((byte) data);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
对象的序列化
シリアライズ:のような構造化データをバイト配列に変換
オブジェクトをバイト配列にシリアライズすることでオブジェクトをDBに保存、ネットワーク経由の受け渡し可能
シリアライズ可能クラスの条件
Serializableインターフェース実装public class Article implements Serializable {
宣言のみでメソッドを持たない=マーカーインターフェース
インスタンスフィールドは基本型、シリアライズ可能な型
シリアライズバーション宣言
serialVersionUIDでクラスのバージョン指定
シリアライズ/デシリアライズ間で異なるバージョンのクラスを使用するとInvalidClassException
基底クラスがシリアライズできないとき、引数のないコンストラクタを持つ
基底クラスがSerializableインターフェース実装せず、派生クラスのみシリアライズ可能の時、派生クラスのデシリアライズに基底クラスのコンストラクタを呼ぶ
ObjectOutputStreamクラスでオブジェクトのシリアライズを行う
引数にFileOutputStream(file)でファイル出力
writeObjectメソッドにオブジェクトを渡す(article.ser作成)
ObjectInputStreamクラスでデシリアライズ
引数に読み込むfileを渡しreadObjectメソッドで読み込む
戻り値はオブジェクト
//article.serにArticleクラス(シリアライズ可能クラス)を保存
//ファイルからバイト配列を読みデシリアライズした公開鍵暗号オブジェクトの内容を出力
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class Main {
public static void main(String[] args) {
final var file = "./article.ser";
try (var out = new ObjectOutputStream(new FileOutputStream(file))) {
out.writeObject(new Article("Java11の変更点と新しいAPI",
"https://codezine.jp/article/corner/751", false));
} catch (IOException e) {
e.printStackTrace();
}
try (var in = new ObjectInputStream(new FileInputStream(file))) {
var a = (Article)in.readObject();
System.out.println(a);
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
}
}