8

私はこれに対する答えを探していましたが、実際には何も見つかりませんでした。今日の初めに、バイト配列を使用してファイルを文字列に変換し、後で取得するために再度戻す方法を尋ねました。

人々が私に言ったことは、厄介なエンコーディングの問題を避けるために、バイト配列を格納するだけでよいということでした。だから今、私はそれに取り組み始めました、しかし私は今壁にぶつかりました。

基本的に、以前はバッファなしのストリームを使用して、ファイルをバイト配列に変換していました。これは理論的にはうまく機能しますが、多くのメモリを消費し、最終的にヒープサイズの例外が発生します。代わりにバッファリングされたストリームを使用する必要があります(またはそう言われています)。現在の問題は、BufferedInputStreamからbyte[]に移行することです。このドキュメントにある方法をコピーして使用しようとしました

http://docs.guava-libraries.googlecode.com/git/javadoc/index.html?com/google/common/io/package-summary.html

バッファリングされていないストリームをバッファリングされたストリームと交換する場所。唯一の問題は、バッファリングされていないストリームの場合のように、バッファリングされた出力ストリームをバイト配列に直接変換できないことです。

ヘルプ?:)

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

public final class BufferedByteStream {

    private static final int BUF_SIZE = 1024000;

    public static long copy(BufferedInputStream from, BufferedOutputStream to) throws IOException { 
        byte[] buf = new byte[BUF_SIZE];
        long total = 0;
        while(true) {
            int r = from.read(buf);
            if(r == -1) {
                break;
            }
            to.write(buf, 0, r);
            total += r;
        }
        return total;
    }

    public static byte[] toByteArray(BufferedInputStream in) throws IOException {
        BufferedOutputStream out = new BufferedOutputStream(new ByteArrayOutputStream());
        copy(in, out);
        return out. // <--- Problem is here
    }
}

編集:

まだヒープスペースエラーが発生しています。だから私は今すべてのコードを投稿します:

main.java

import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import jserver.io.BufferedByteStream;
/**
*
* @author Vipar
*/
public class main {
    public static void main(String[] args) {
    File f = new File("<doesn't matter>");
        try {
            byte[] buf;
            try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f))) {
                buf = BufferedByteStream.toByteArray(bis);
                bis.close();
            }
            File f2 = new File("<doesn't matter>");
            try (FileOutputStream fos = new FileOutputStream(f2)) {
                fos.write(buf);
                fos.close();
            }
        } catch (FileNotFoundException ex) {
            Logger.getLogger(main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

BufferedByteStream.java

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

public final class BufferedByteStream {

    private static final int BUF_SIZE = 1024000;

    public static long copy(BufferedInputStream from, BufferedOutputStream to) throws IOException { 
        byte[] buf = new byte[BUF_SIZE];
        long total = 0;
        while(true) {
            int r = from.read(buf);
            if(r == -1) {
                break;
            }
            to.write(buf, 0, r);
            total += r;
        }
        return total;
    }

    public static byte[] toByteArray(BufferedInputStream in) throws IOException {
        ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
        BufferedOutputStream out = new BufferedOutputStream(bytesOut);
        copy(in, out);
        return bytesOut.toByteArray();
    }
}
4

2 に答える 2

11

ByteArrayOutputStreamを見てください: Java 7 API java.io.ByteArrayOutputStream

bytesOut = new ByteArrayOutputStream();
byte[] bytes = bytesOut.toByteArray();

更新:実行していることを実行することを主張する場合は、中間のByteArrayOutputStreamを変数に割り当てて、その方法で配列を取得できます。

ByteArrayOutputStream bytesOut = new ByteArrayOutputStream()
BufferedOutputStream out = new BufferedOutputStream(bytesOut);
copy(in, out);
return bytesOut.toByteArray();

更新2:本当の問題は、最初にすべてをメモリに読み込まずにファイルをコピーする方法のようです。

1)手動:

    byte[] buff = new byte[64*1024]; //or some size, can try out different sizes for performance
    BufferedInputStream in = new BufferedInputStream(new FileInputStream("fromFile"));
    BufferedOutputStream out = new BufferedOutputStream(new FileoutputStream("toFile"));
    int n = 0;
    while ((n = in.read(buff)) >= 0) {
        out.write(buff, 0, n);
    }
    in.close();
    out.close();

2)OSによる効率的で、ループなどはありません。

FileChannel from = new FileInputStream(sourceFile).getChannel();
FileChanngel to = new FileOutputStream(destFile).getChannel();
to.transferFrom(from, 0, from.size());
//or from.transferTo(0, from.size(), to);
from.close();
to.close();

3)Java 7を使用している場合は、例外とストリームのクローズを簡略化するか、Java7の新しいAPIiを使用してファイルをコピーすることができます。

java.nio.file.Files.copy(...);

java.nio.file.Filesを参照してください

于 2012-05-17T20:19:55.367 に答える
-1

DataFetcherはこれに最適です:

http://tus.svn.sourceforge.net/viewvc/tus/tjacobs/io/DataFetcher.java?revision=34&view=markup

メモリが不足している場合は、clearBufferを使用して読み取り間のバッファをクリアできます

Timeoutクラスも必要です。これは同じパッケージの同じプロジェクトにあります。

于 2012-05-17T20:39:21.390 に答える