001package com.streamconverter.command.impl.charcode; 002 003import com.streamconverter.command.AbstractStreamCommand; 004import java.io.IOException; 005import java.io.InputStream; 006import java.io.InputStreamReader; 007import java.io.OutputStream; 008import java.io.OutputStreamWriter; 009import java.nio.charset.Charset; 010import java.util.Objects; 011 012/** 013 * Converts the character encoding of a stream from one encoding to another. 014 * 015 * <p>This class extends the AbstractStreamCommand and implements the conversion of character 016 * encodings. 017 */ 018// BEGIN CharacterConvertCommand.java 019public class CharacterConvertCommand extends AbstractStreamCommand { 020 private String from; 021 private String to; 022 023 /** 024 * Constructor to initialize the character encodings for conversion. 025 * 026 * @param from The source character encoding. 027 * @param to The target character encoding. 028 * @throws IllegalArgumentException if the specified character encodings are not supported. 029 */ 030 private CharacterConvertCommand(String from, String to) { 031 this.from = from; 032 this.to = to; 033 } 034 035 /** 036 * Factory method to create a CharacterConvertCommand. 037 * 038 * @param from The source character encoding. 039 * @param to The target character encoding. 040 * @return a new CharacterConvertCommand instance 041 * @throws IllegalArgumentException if the specified character encodings are not supported. 042 */ 043 public static CharacterConvertCommand create(String from, String to) { 044 Objects.requireNonNull(from); 045 Objects.requireNonNull(to); 046 if (!Charset.isSupported(from)) { 047 throw new IllegalArgumentException("変換元文字コードがサポートされていません"); 048 } 049 if (!Charset.isSupported(to)) { 050 throw new IllegalArgumentException("変換先文字コードがサポートされていません"); 051 } 052 return new CharacterConvertCommand(from, to); 053 } 054 055 /** 056 * Executes the character encoding conversion on the provided input stream and writes the result 057 * to the output stream. 058 * 059 * @param inputStream The input stream to read data from. 060 * @param outputStream The output stream to write data to. 061 * @throws IOException If an I/O error occurs during the execution of the command. 062 */ 063 @Override 064 public void execute(InputStream inputStream, OutputStream outputStream) throws IOException { 065 Objects.requireNonNull(inputStream); 066 Objects.requireNonNull(outputStream); 067 068 // 省メモリストリーミング文字コード変換 069 try (InputStreamReader reader = new InputStreamReader(inputStream, this.from); 070 OutputStreamWriter writer = new OutputStreamWriter(outputStream, this.to); ) { 071 072 // transferTo()は大容量データでメモリを大量消費するため、 073 // 固定サイズバッファでストリーミング処理を実装 074 char[] buffer = new char[8192]; // 8KB char buffer (16KB memory) 075 int charsRead; 076 077 while ((charsRead = reader.read(buffer)) != -1) { 078 writer.write(buffer, 0, charsRead); 079 writer.flush(); // 即座に出力してメモリを解放 080 } 081 } 082 } 083}