はじめに
Java では、InputStreamクラスを使用して、ファイルからデータを順序付きのシーケンスで読み取ります。データを文字列として使用するには、InputStream を文字列に変換する必要があります。この実験では、InputStream を文字列に変換するさまざまな方法を学びます。
InputStreamReader を使用する
InputStreamReader クラスは、read() メソッドを提供して、InputStream からのデータを文字配列に読み取ります。この文字配列を文字列に変換することができます。次のコンテンツを持つ ~/project ディレクトリに新しい Java ソースファイル InputStreamToString.java を作成します。
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class InputStreamToString {
public static String inputStreamToString(InputStream input) throws IOException {
InputStreamReader reader = new InputStreamReader(input);
char[] charArray = new char[256];
reader.read(charArray);
return new String(charArray);
}
public static void main(String[] args) {
try {
InputStream input = new ByteArrayInputStream("hello world".getBytes());
String strFromInputStream = inputStreamToString(input);
System.out.print("String from the Input Stream is: " + strFromInputStream);
} catch(Exception e) {
System.out.print(e);
}
}
}
コードを実行するには、ターミナルを開き、次のコマンドでコードをコンパイルして実行します。
javac InputStreamToString.java && java InputStreamToString
InputStreamReader と BufferedReader を StringBuilder とともに使用する
前の手順は、より大きな入力に対して非効率的です。代わりに、効率を向上させるために、BufferedReader を使用して InputStreamReader をラップします。そして、StringBuilder オブジェクトを使用して、BufferedReader から読み取った行を追加します。次のコードを使用して、InputStreamToString.java のステップ 1 の後に新しいステップを作成します。
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class InputStreamToString {
public static String inputStreamToString(InputStream input) throws IOException {
StringBuilder builder = new StringBuilder();
InputStreamReader reader = new InputStreamReader(input);
BufferedReader bufferedReader = new BufferedReader(reader);
String line;
while ((line = bufferedReader.readLine())!= null) {
builder.append(line);
}
return builder.toString();
}
public static void main(String[] args) {
try {
InputStream input = new ByteArrayInputStream("hello world".getBytes());
String strFromInputStream = inputStreamToString(input);
System.out.print("String from the Input Stream is: " + strFromInputStream);
} catch(Exception e) {
System.out.print(e);
}
}
}
StringBuilder を使用せずに InputStreamReader と BufferedReader を使用する
BufferedReader クラスの lines() メソッドを使用することで、より簡単なアプローチが可能です。これにより、各行を個別の StringBuilder インスタンスに追加する必要がなくなります。次のコードを使用して、InputStreamToString.java のステップ 2 の後に新しいステップを作成します。
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.stream.Collectors;
public class InputStreamToString {
public static String inputStreamToString(InputStream input) throws IOException {
InputStreamReader reader = new InputStreamReader(input);
BufferedReader bufferedReader = new BufferedReader(reader);
String str = bufferedReader.lines().collect(Collectors.joining("\n"));
return str;
}
public static void main(String[] args) {
InputStream input = new ByteArrayInputStream("hello world".getBytes());
String strFromInputStream = inputStreamToString(input);
System.out.print("String from the Input Stream is: " + strFromInputStream);
}
}
InputStream の readAllBytes() メソッドを使用する
InputStream クラスは、Java 9 で readAllBytes() メソッドを導入しました。これにより、1 行のコードで効率的に InputStream オブジェクト全体を文字列に変換できます。ただし、このメソッドは、より大きな入力に対しては推奨されません。次のコードを使用して、InputStreamToString.java のステップ 3 の後に新しいステップを作成します。
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
public class InputStreamToString {
public static String inputStreamToString(InputStream input) throws IOException {
return new String(input.readAllBytes());
}
public static void main(String[] args) {
try {
InputStream input = new ByteArrayInputStream("hello world".getBytes());
String strFromInputStream = inputStreamToString(input);
System.out.print("String from the Input Stream is: " + strFromInputStream);
} catch(Exception e) {
System.out.print(e);
}
}
}
Scanner クラスを使用する
入力ストリームを文字列に変換するために、データの読み取りと解析に一般的に使用される Scanner クラスを使用することもできます。次のコードを使用して、InputStreamToString.java のステップ 4 の後に新しいステップを作成します。
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;
public class InputStreamToString {
public static String inputStreamToString(InputStream input) throws IOException {
Scanner scanner = new Scanner(input);
StringBuilder builder = new StringBuilder();
while (scanner.hasNext()) {
builder.append(scanner.nextLine());
}
return builder.toString();
}
public static void main(String[] args) {
try {
InputStream input = new ByteArrayInputStream("hello world".getBytes());
String strFromInputStream = inputStreamToString(input);
System.out.print("String from the Input Stream is: " + strFromInputStream);
} catch(Exception e) {
System.out.print(e);
}
}
}
ByteArrayOutputStream を使用する
java.io パッケージ内の ByteArrayOutputStream クラスを使用して、入力ストリームからデータをバイト配列にコピーします。そして、バイト配列を ByteArrayOutputStream に書き込みます。最後に、ByteArrayOutputStream の toString() メソッドを使用して文字列形式を取得します。次のコードを使用して、InputStreamToString.java のステップ 5 の後に新しいステップを作成します。
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class InputStreamToString {
public static String inputStreamToString(InputStream input) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[128];
int length;
while ((length = input.read(buffer))!= -1) {
byteArrayOutputStream.write(buffer, 0, length);
}
return byteArrayOutputStream.toString();
}
public static void main(String[] args) {
try {
InputStream input = new ByteArrayInputStream("hello world".getBytes());
String strFromInputStream = inputStreamToString(input);
System.out.print("String from the Input Stream is: " + strFromInputStream);
} catch(Exception e) {
System.out.print(e);
}
}
}
java.nio パッケージを使用する
java.nio パッケージでは、Files.createTempFile を使用して一時ファイルを作成し、InputStream からのデータをこのファイルにコピーすることができます。その後、この一時ファイルの内容を文字列に読み込むことができます。次のコードを使用して、InputStreamToString.java のステップ 6 の後に新しいステップを作成します。
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
public class InputStreamToString {
public static String inputStreamToString(InputStream input) throws IOException {
Path file = Files.createTempFile(null, null);
Files.copy(input, file, StandardCopyOption.REPLACE_EXISTING);
return new String(Files.readAllBytes(file));
}
public static void main(String[] args) {
try {
InputStream input = new ByteArrayInputStream("hello world".getBytes());
String strFromInputStream = inputStreamToString(input);
System.out.print("String from the Input Stream is: " + strFromInputStream);
} catch(Exception e) {
System.out.print(e);
}
}
}
Google Guava ライブラリを使用する
Google Guava ライブラリは、InputStream を文字列に変換するための CharStreams クラスを提供しています。このクラスの toString() メソッドを使用することで、これを行うことができます。これは、Readable オブジェクト(InputStreamReader のようなもの)を取り、そこからデータを読み取って文字列に変換します。次のコードを使用して、InputStreamToString.java のステップ 7 の後に新しいステップを作成します。
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import com.google.common.io.CharStreams;
public class InputStreamToString {
public static String inputStreamToString(InputStream input) throws IOException {
try(InputStreamReader reader = new InputStreamReader(input)) {
return CharStreams.toString(reader);
}
}
public static void main(String[] args) {
try {
InputStream input = new ByteArrayInputStream("hello world".getBytes());
String strFromInputStream = inputStreamToString(input);
System.out.print("String from the Input Stream is: " + strFromInputStream);
} catch(Exception e) {
System.out.print(e);
}
}
}
Apache Commons IO を使用する
org.apache.commons.io パッケージの IOUtils クラスにも toString() メソッドが含まれています。このメソッドに InputStream オブジェクトを直接渡すことができ、そこからデータを読み取って文字列に変換します。また、Charset も指定する必要があります。次のコードを使用して、InputStreamToString.java のステップ 8 の後に新しいステップを作成します。
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import org.apache.commons.io.IOUtils;
public class InputStreamToString {
public static void main(String[] args) {
try {
InputStream input = new ByteArrayInputStream("hello world".getBytes());
String strFromInputStream = IOUtils.toString(input, StandardCharsets.UTF_8.name());
System.out.print("String from the Input Stream is: " + strFromInputStream);
} catch(Exception e) {
System.out.print(e);
}
}
}
Apache Commons IO とともに StringWriter クラスを使用する
java.io パッケージの StringWriter クラスを使用して、InputStream の内容を StringWriter にコピーすることができます。IOUtils クラスの copy() メソッドを使用します。次のコードを使用して、InputStreamToString.java のステップ 9 の後に新しいステップを作成します。
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import org.apache.commons.io.IOUtils;
public class InputStreamToString {
public static void main(String[] args) {
try {
InputStream input = new ByteArrayInputStream("hello world".getBytes());
StringWriter sw = new StringWriter();
IOUtils.copy(input, sw, StandardCharsets.UTF_8.name());
String strFromInputStream = sw.toString();
System.out.print("String from the Input Stream is: " + strFromInputStream);
} catch(Exception e) {
System.out.print(e);
}
}
}
まとめ
この実験では、Java において InputStream を文字列に変換するさまざまな方法を学びました。効率を向上させるために、ByteArrayOutputStream や BufferedReader クラスを使用することができます。また、入力ストリームを文字列に変換するために Scanner クラスも利用できます。readAllBytes() メソッドは、小さな入力にのみ適しています。Google Guava や Apache Commons IO のような外部ライブラリを使用して、処理を簡略化することもできます。例外処理を行い、InputStream を閉じてリソースリークを回避することを忘れないでください。



