1つのInputStreamから連続して2つ以上のOutputStreamに書くことは可能か?

このQ&Aのポイント
  • 1つのFileInputStreamのクラスから2つのFileOutputStreamのクラスへwriteし、ファイル2つを作成しようとしています。
  • OutputStream1へwriteし、次にOutputStream2へwriteしたとき、両方のStreamで作成したファイルが空(0KB)の状態になってしまいます。
  • 1つのInputStreamから連続して2つ以上のOutputStreamに書くことはできないのか、また他の方法はあるのか教えてください。
回答を見る
  • ベストアンサー

InputStreamはreadが1回しかできない?

1つのFileInputStreamのクラスから2つのFileOutputStreamのクラス (仮にOutputStream1、OutputStream2とします)へwriteし、 ファイル2つを作成しようとしています。 最初にOutputStream1へwriteし、次にOutputStream2へwriteしたとき、 両方のStreamで作成したファイルが空(0KB)の状態になってしまいます。 1つのInputStreamから連続して2つ以上のOutputStreamに書くことはいけない ことなのでしょうか?(どうしてもやりたいのですが) もしかしてFileInputStreamの完全なコピー(cloneじゃなくシリアライズして 複製を作成する)を作る方法しかないのでしょうか?とはいうものの シリアライズできるInputStreamクラスを作成できず困っていたりします。 (あとOutputStreamをInputStreamに変換できたらなぁとかも思うの  ですが無理ですよね・・・?) どなたかご存じの方、是非ご教授下さい。

  • ct27
  • お礼率80% (40/50)
  • Java
  • 回答数2
  • ありがとう数5

質問者が選んだベストアンサー

  • ベストアンサー
  • thelma
  • ベストアンサー率66% (20/30)
回答No.1

Streamは、その名の通り「データの流れ」であって、データそのものではありません。 そのため、いったんread()を繰り返してファイルの終端に達してしまうと、以降のread()は常にファイルの終端を返します。 (巻き戻せるものもありますが、FileInputStreamは違います) この場合は、処理の順序をうまく組み立てれば解決すると思います。 a)OutputStreamを2つ同時にオープンし、同時に書き込む。 FileInputStream in = new FileInputStream("in.txt"); FileOutputStream out1 = new FileOutputStream("out1.txt"); FileOutputStream out2 = new FileOutputStream("out2.txt"); int b; while ((b = in.read()) != -1) { out1.write(b); out2.write(b); } in.close(); out1.close(); out2.close(); b)InputStreamをいったんbyte配列に読み込み、そのbyte配列をOutputStreamに書き込む。 FileInputStream in = new FileInputStream("in.txt"); byte[] bytes = new byte[in.available()]; in.read(bytes); in.close(); FileOutputStream out1 = new FileOutputStream("out1.txt"); out1.write(bytes); out1.close(); FileOutputStream out2 = new FileOutputStream("out2.txt"); out2.write(bytes); out2.close(); c)InputStreamをいったんcloseして、再度newする。 他にやりたいことにあわせて、お好きな手段が使えると思います。

参考URL:
http://java.sun.com/j2se/1.4/ja/docs/ja/api/java/io/FileInputStream.html

その他の回答 (1)

  • thelma
  • ベストアンサー率66% (20/30)
回答No.2

補足ですが、 Stream系のクラスは、前述のとおり「流れ」なので、シリアライズすることができません。 また、性質上、OutputStreamをInputStreamに変換することもできません。そもそも目的がまったく違いますので、、、。 ストリームについては、参考URL等をごらんください。

参考URL:
http://home.catv.ne.jp/dd/chiba/ken/Java/JavaStream.html
ct27
質問者

お礼

回答&アドバイスありがとうございました。 大変わかりやすく説明していただき、長い間の疑問であった部分がまさに 霧が晴れるかのごとくすっきりとしました。(現在感動中) シリアライズに関してはできないのだろうとは思っていたのですが thelmaさんのご説明のおかげで納得することができました。 参考URLもとても参考になりますね。あとでじっくりと読みたいと思います。 本来やりたいことは"今回教えていただいた内容の変形"+"その他たくさんの内容"。 ですので、全てがうまく流れたら「できました!」のお知らせも兼ねてポイント発行 させていただきたいと思います。

関連するQ&A

  • InputStreamクラスの仕様

    InputStreamクラスのreadメソッドを使用しています。 InputStreamには1MBのデータがバイナリで格納されており、2KBずつ byte配列にreadメソッドを使用して格納する処理を行っています。 処理自体は問題なく終了するのですが、readメソッドを使用して8KBほど 読み込んだ後、決まってパフォーマンスが悪くなり100Bしか読み取れず、 また8KB読み込んで100B読み込むといった処理になってしまいます・・・。 これはInputStreamのreadクラスの仕様なのでしょうか?それとも何か対策があるのでしょうか? ちなみにInputStreamクラスの元ねたはHTMLにてmultipart/form-dataを使用して アップロードしたファイルデータが格納されています。

    • ベストアンサー
    • Java
  • 複数のOutputStreamでサーバ側から送信されるデータを、クライアント側で区別する方法

    こんにちわ。 データの送受信を行う場合のStreamに関して質問があります。 サーバー・クライアントプログラムを組む場合に、サーバー側から複数のOutputStreamを開き、それをクライアント側で受け取る場合は、どのようにInputStreamを開けばよいのでしょうか? また、一対のOutputStreamとInputStreamでデータの送受信を行う場合に関しても、データの内容によってプログラムを分岐したい場合などどのようにすればいいのでしょうか? 現在URLConnectionクラスを利用して、データの送受信を行うプログラムを作成しているのですが、疑問に感じたので教えて頂きたいです。

    • ベストアンサー
    • Java
  • JAVAで別端末へファイル転送

    JAVAで端末から端末にファイルを自動的に転送するプログラムを作成しています。転送手段はUNC(\\path)形式で以下のソースのように転送しています。 -------------------------------------------------- ※READ_FILE → 送信側ファイルパス  WRITE_FILE → 受信側ファイルパス //ファイルを読み込む FileInputStream readFile = new FileInputStream(READ_FILE); //読み込んだファイルを書き込む File writeFile = new File(WRITE_FILE); writeFile.createNewFile(); FileOutputStream fo = new FileOutputStream(writeFile); int count = 0; byte[] buf = new byte[16384]; while ((count=readFile.read(buf)) != -1) { fo.write(buf, 0, count); } readFile.close(); fo.close(); -------------------------------------------------- ここで問題になってしまったのが、認証です。エクスプローラでその端末の認証をすませてしまえば、問題なくこのソースは通るのですが、認証せずに実行すると FileInputStream readFile = new FileInputStream(READ_FILE); のところで落ち FileNotFoundException:(ログオン失敗: ユーザー名を認識できないか、またはパスワードが間違っています。) となってしまいます。 JAVAで認証するためにログオンするようなクラスはありますか?そのクラスの使い方、ソース、参考になるようなホームページがありましたら、教えてください。 よろしくお願い致します。

  • Java Webアプリ。PDFダウンロード

    Tomcat6(Struts2.x)で構築されたWebサイトにPDFダウンロード機能を実装しています。 PDFファイルの内容は動的に変更する必要があり別のライブラリを使いExcelテンプレートを元にに生成しています。 この処理(Excelテンプレ → (DBなどのデータを動的に埋め込み) → PDFファイル生成)は正常にできています。 ただ正常に動かす為には生成したPDFファイルをサーバー内のディレクトリに置いた後、そのファイルを使い InputStream inputStream = FileUtils.openInputStream(new File("そのファイル")); としてこの inputStream をStruts2のアクションの設定ファイルで --------------------------------------------------------------------------- <result type="stream"> <param name="contentType">application/pdf</param> <!-- 上記のメンバ変数の imputStreamを指定。 --> <param name="inputName">inputStream</param> <param name="contentDisposition">attachment; filename = ${fileName}</param> <param name="bufferSize">${bufferSize}</param> <param name="contentLength">${contentLength}</param> </result> --------------------------------------------------------------------------- としています。この方法だとうまくいってますし最終的にやりたい事も実現できてます。 しかし、 生成したPDFファイルをサーバー内のディレクトに置くという処理が気になっています。 というのも前述したExcelファイルからPDFを生成するライブラリは以下のように使います。 ※わかり辛いですが全体的な処理の流れとしては上記までが下記より後に実行されます!! --------------------------------------------------------------------------- // まず FileOutputStream のインスタンスを作る(C:/hoge.pdf はもちろんこの時点では存在しなくてOK)。 FileOutputStream fos = new FileOutputStream("C:/hoge.pdf"); // PDF生成ライブラリのクラスのコンストラクタ。 HogeTemplatePdf pdf = new HogeTemplatePdf("サーバー内に置いたExcelのテンプレ"); // このprintPdf()メソッドを実行するとPDF(C;/hoge.pdf)が生成されます。 pdf.printPdf(fos); --------------------------------------------------------------------------- ※このPDF生成のライブラリは私の方では変更できないものです。 このように printPdf() メソッドは OutputStream へPDFを出力します。 しかし一番上に書いたファイルそのもののダウンロード処理は inputStream で指定しないといけないようです。 つまり現在の処理の流れは、 (FileOutputStream)  ↓ (PDFファイル生成 ※実際に指定したサーバーのパスにファイルができる)  ↓ (サーバー内にできたファイルを指定して inputStream を生成)  ↓ (ダウンロード) という流れですがこれを (FileOutputStream)  ↓ (??? 実際にサーバー内にファイルは生成して欲しくない)  ↓ (サーバー内にできたファイルを指定して inputStream を生成)  ↓ (ダウンロード) のような実装にしたいと考えています。 つまり outputStream を inputStream に変換(?)のような事が行いたいです。 実際にサーバー内にファイルを作るのではなくメモリ上にファイルをつくる(?)のような感じですかね? このような事は可能でしょうか?? 以上です。よろしくお願いします。

  • javaで画像ファイルの入出力方法

    お世話になります、 画像ファイル(データ)をJavaアプリケーションで取り込んで別のディレクトリに同じ画像を複製する方法を探しています。 単なる画像ファイルのコピーではなく、Java側で画像データ(バイナリ)を取得して、新規に作成したファイル(Fileクラスで作成)にそのデータをWriteして複製する方法を探しています。 FileInputStreamやFileOutputStream等の方法で行ってみたのですが、微妙にデータが異なってしまって、画像が表示されません(画像ファイルを秀丸等で表示してデータを比較しました)。 以下にソースを貼り付けます。何か良い方法等ありましたらよろしくお願いします。 //画像ファイルのデータを読み込む CharArrayWriter caw = new CharArrayWriter(); Reader fr = new FileReader("D:\\image\\abcd.gif"); Reader in = new BufferedReader(fr); //新規にファイルを作成する File fil = new File("C:\\image\\abcd.gif"); fil.createNewFile(); FileOutputStream fo = new FileOutputStream(fil); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fo)); int count = 0; char[] buf = new char[16384]; while ((count=in.read(buf)) != -1) { if (count > 0) caw.write(buf, 0, count); } in.close(); //読み込んだ画像ファイルデータを作成したファイルに書き込む bw.write(caw.toCharArray()); よろしくお願いします。

    • ベストアンサー
    • Java
  • java.io.Fileクラスは絶対パス長をチェックしないのですか?

    windows XP+Eclipse3.3+JDK1.5.0_15上でjava.io.Fileクラスを使ってテキストファイルの入出力を行うJavaプログラムを作成しました。 しかし、これによって、パス長が長すぎて(フルパスで300文字)アクセスできないファイルが作成されてしまいました。 (正確には、Windowsのファイルエクスプローラーに存在は表示されているけど、開けないし、削除も、ドラッグアンドドロップもできないという状態。このファイルの右クリックメニューの項目は「開く」と「送る」の2つしかありませんでした。) StreamReader・WriterもIOExceptionを返していませんでした。 Fileクラスは読み書きするにあたってパス長のチェックをしていないのでしょうか? ちなみに、フルパス長259文字のテキストファイル(数行の文字列を記入してある)を入力に与えたとき、空ファイルのように扱われていました。 このファイルをメモ帳で開こうとすると「パス長が長すぎる」というエラーが出て中身が読み取れませんでした。 以下にソース(例外処理を省略)を抜粋します。 ---------------- File inputFile = new File(args[i]); if (!inputFile.isFile() || !inputFile.canRead()) { // ファイルを読む inputStream = new FileInputStream(inputFile); InputStreamReader inputStreamReader = new InputStreamReader( inputStream, "UTF-8"); bufferReader = new BufferedReader(inputStreamReader);   (以下、読み出し処理) // 入力ファイルと同じ階層に「Result」ディレクトリを作る File resultDir = new File(resultDirPath); resultDir.mkdir(); // 読み取った1行の末尾に"a"を付加したものをファイルに書き込み、 // 「Result」ディレクトリに出力。 // ファイル名は「output_(入力テキストファイル名)」とする File outputFile = new File(resultDir.getOutputDirPath(), outputFileName); outputFile.createNewFile(); outputStream = new FileOutputStream(outputFile); outputStreamWriter = new OutputStreamWriter(outputStream, "UTF-8"); bufferedWriter = new BufferedWriter(outputStreamWriter);   (以下、書き込み処理) } ---------------- 以上、よろしくお願いいたします。

    • ベストアンサー
    • Java
  • UNICODEへの文字コード変換

    以下のようにして、 日本語で書かれたファイルを読み込んで、 UNICODEに変換したいのですが、 できません。。。 どこが間違っているのでしょうか?(;;) 元の日本語ファイル「こんにちは」 >>できたファイル「\u3053\u3093\u306b\u3061\u306f」 という風にしたいのですが。。 //FileIOSteramの作成 FileInputStream fis = new FileInputStream(iFile); FileOutputStream fos = new FileOutputStream(oFile); //Stream ラップ InputStreamReader in = new InputStreamReader(fis, "EUC-JP-LINUX"); OutputStreamWriter out = new OutputStreamWriter(fos, "UTF16"); System.out.println(System.getProperty("file.encoding")); //読み込みと書き込み int c; InputStreamReader in = new InputStreamReader(fis, "Unicode"); Writer out = new Writer(fos); while((c = in.read()) != -1){ out.write(c); }

  • ストリームの問題について【至急】

    import java.io.*; public class FileStreamDemo { public static void main(String[] args){ try{ byte[] buffer=new byte[1024]; FileInputStream fileInputStream= new FileInputStream(new File(args[0])); FileOutputStream fileOutputStream= new FileOutputStream(new File(args[1])); System.out.println("コピーファイル: "+fileInputStream.available()+"バイト"); while(true){ if(fileInputStream.available()<1024){ int remain=-1; while((remain=fileInputStream.read())!=-1){ fileOutputStream.write(remain); } break; } else{ fileInputStream.read(buffer); fileOutputStream.write(buffer); } } fileInputStream.close(); fileOutputStream.close(); System.out.println("コピー完了"); } catch(ArrayIndexOutOfBoundsException e){ System.out.println( "using:java FileStreamDemo src des"); e.printStackTrace(); } catch(IOException e){ e.printStackTrace(); } } } JAVAの入門者です。 JAVAの教科書に書いてあるように、上のプログラムを書きましたけど… コンパイルすると、エラーメッセージが出て来ます。 エラー中身は下記のとおりです。 【using:java FileStreamDemo src des java.lang.ArrayIndexOutOfBoundsException: 0 at FileStreamDemo.main(FileStreamDemo.java:8) 】 どうすればいいのか悩んでいます。 誰か、助けていただけないのでしょうか?どこか間違ってるか、教えてください。 よろしく、お願いします。

  • Excelに時刻を入れたい

    はじめまして。 JAVA初心者です。 DBから取得したデータ「09:00」をExcelに入れようとしているんですが、表示された結果が正しくないのです。 DBからTimeタイプとして入れたら、セル値がシリアルになってしまう。 他、Stringとしたら、セル値にアポストロフィが付いてしまう。 今のところ解決方法はありません。 どうすれば、正しい結果(9:00)が表示されるのでしょうか。 教えていただけませんか? ついでに、既存エクセルの書式は「時刻」です。 ソースは以下の通りです。(Timeタイプとする) -------------------jsp ソース------------------ FileInputStream inputStream = null; FileOutputStream outputStream = null; File excel = new File("C:\\123123.xls"); inputStream = new FileInputStream(excel); HSSFWorkbook workBook = new HSSFWorkbook(inputStream); HSSFSheet newSheet = workBook.getSheetAt(0); HSSFRow newRow = newSheet.getRow(16); HSSFCell newCell1 = newRow.getCell((short) 6); java.sql.ResultSet rs = null; rs = DBtest.DBGetdate(); Time modifyTimeTemp = null; HSSFRow newRowtemp = newSheet.getRow(18); HSSFCell newCell1temp = newRow.getCell((short) 6); while(rs.next()){ modifyTimeTemp = rs.getTime("Time"); } //newCell1temp:正しく入力されたデータ newCell1.setCellStyle(newCell1temp.getCellStyle()); newCell1.setCellValue(modifyTimeTemp); try{ response.setContentType("application/msexcel"); response.setHeader("Content-Disposition", "attachment; filename=jsp.xls"); OutputStream outs = response.getOutputStream(); workBook.write(outs); outs.close(); }catch(Exception e){ e.printStackTrace(); }

    • ベストアンサー
    • Java
  • サーブレットでのファイルダウンロードについて

    サーブレットでファイルのダウンロードを 行うプログラムを作成しているのですが ときどきダウンロードするファイルが切れている 場合があります。 なので実際のファイルとダウンロード時のファイル の違いがあった場合はJSPでalert表示を行いたい のですが、うまく実行できません。 処理としては response.setHeader(......) response.setContentType(......) 等の設定を行い ダウンロードするファイルのInputStream を作成、OutputStreamにgetOutputStream() を取得してwriteしています。 上記のwriteする時に件数をカウントして このサーブレットの呼び元のjspに返却したい のですが、取得ができません。 何か参考になるサイトなどないでしょうか? よろしくお願いします。

    • ベストアンサー
    • Java

専門家に質問してみよう