2012-05-17 17 views
7

我一直在四处寻找一个答案,但不能真正找到任何东西。今天早些时候,我问我如何通过字节数组将文件转换为字符串,然后再返回,以便稍后检索。的BufferedInputStream为字节[]要送过来一个Socket到数据库

什么人告诉我,是我不得不只存储字节数组,避免讨厌的编码问题。所以现在我已经开始研究这个了,但现在我已经碰到了一堵墙。

基本上,我以前使用未缓冲的流,把一个文件到一个字节数组。这在理论上是行得通的,但是它占用了大量的内存,最终会造成堆大小异常。我应该使用缓冲流代替(或者我被告知),我现在遇到的问题是从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(); 
    } 
} 
+0

为什么不告诉我们你想解决什么问题,而不是问一半解决方案有什么问题? – EJP

+0

我原本应该知道现在,但是我会在适当的问题中做到这一点,我只是简单地说出我想实现的目标。 – OmniOwl

回答

9

看一看ByteArrayOutputStream: Java 7 API java.io.ByteArrayOutputStream

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

更新: 如果你坚持这样做,你在做什么,你可以在中间ByteArrayOutputStream只是分配给一个变量,并得到保持array that that:

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,您可以简化异常并流关闭或只是文件与新的API,我复制的Java 7:

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

see java.nio.file.Files

+0

据我的理解,这不是缓冲... – OmniOwl

+0

你不需要更多的缓冲......它在内存中建立一个数组。它没有得到更多的缓冲。 –

+0

但是,如果您不相信我(无论如何您都应该测量自己),您可以直接使用它,但将它分配给它自己的变量。我会更新这个例子。 –

相关问题