如何在Java中将字节数组写入文件?

73

如何在Java中将字节数组写入文件?


你能否放一些代码并展示你想要写入文件的内容? - Koray Tugay
8个回答

74

byte[] encoded = key.getEncoded();我需要将encoded写入文本文件。 - rover12
KeyGenerator kgen = KeyGenerator.getInstance("AES"); kgen.init(128); SecretKey key = kgen.generateKey(); byte[] encoded = key.getEncoded(); - rover12
然后只需使用FileOutputStream。 - Michael Lloyd Lee mlk
如果提到教程,你会得到一个+1的赞(如果提到www.google.com甚至可以得到+2的赞——好吧,这很恶劣,但这不是Rover的第一个问题...) - Andreas Dolk
你应该像@JuanZe建议的那样,将FileOutputStream包装在BufferedOutputStream中,这样性能会更好。 - Sam Barnum
使用FileOutputStream在Android中可行,而java.nio.file不存在。 - Brent Faust

40

你可以使用Apache Commons IO中的IOUtils.write(byte[] data, OutputStream output)方法。

KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
SecretKey key = kgen.generateKey();
byte[] encoded = key.getEncoded();
FileOutputStream output = new FileOutputStream(new File("target-file"));
IOUtils.write(encoded, output);

65
为什么要添加第三方库来实现这个? - jarnbjo
5
OP没有要求对byteArray进行AES编码。 - Gaurav Agarwal
@GauravAgarwal 在她/他的原始问题中没有提到(他们应该更新!),但请参见此处的第一和第三条评论:http://stackoverflow.com/questions/1769776/how-can-i-write-a-byte-array-to-a-file-in-java#comments-1769788 - Liam
2
@lutz正在为Apache Commons做公关。 - CodeBlue
FileOutputStream output = new FileOutputStream(new File("target-file")); // +1 - bizzr3

35

从Java 1.7开始,有了一种新的方法:java.nio.file.Files.write

import java.nio.file.Files;
import java.nio.file.Paths;

KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
SecretKey key = kgen.generateKey();
byte[] encoded = key.getEncoded();
Files.write(Paths.get("target-file"), encoded);

Java 1.7还解决了Kevin所描述的尴尬情况:现在读取文件的方式为:

byte[] data = Files.readAllBytes(Paths.get("source-file"));

8
现今这可能是推荐的方法。SecretKey 相关的所有内容都不需要,只需调用 Files.write()。感谢 Sebastian! - barfuin

16

一位评论者问道:“为什么要使用第三方库来完成这个任务?”答案是自己动手实现太麻烦了。下面是一个例子,展示如何正确地执行从文件中读取字节数组的逆操作(抱歉,这只是我现成可用的代码,而且我也不希望提问者真的复制和使用这段代码):

public static byte[] toByteArray(File file) throws IOException { 
   ByteArrayOutputStream out = new ByteArrayOutputStream(); 
   boolean threw = true; 
   InputStream in = new FileInputStream(file); 
   try { 
     byte[] buf = new byte[BUF_SIZE]; 
     long total = 0; 
     while (true) { 
       int r = in.read(buf); 
       if (r == -1) {
         break; 
       }
       out.write(buf, 0, r); 
     } 
     threw = false; 
   } finally { 
     try { 
       in.close(); 
     } catch (IOException e) { 
       if (threw) { 
         log.warn("IOException thrown while closing", e); 
       } else {
         throw e;
       } 
     } 
   } 
   return out.toByteArray(); 
 }

每个人都应该对这是多么痛苦感到非常震惊。

使用好的库。我毫不意外地推荐Guava的Files.write(byte[], File)


2
我对这个问题感到非常痛心,更让我惊讶的是这种事情居然没有包含在标准库中。我们并不是在谈论一个晦涩的文件格式,而只是将字节从内存移动到磁盘。 - Jim Pivarski
2
最佳答案:Guava的Files.write(byte[], File)。 - jan
我会选择这个答案而不是使用库!你可能对这个问题感兴趣:https://dev59.com/ysLra4cB1Zd3GeqPSdOX - Nerdy Bunz

12

要将字节数组写入文件,请使用以下方法:

public void write(byte[] b) throws IOException

从BufferedOutputStream类中获取。

java.io.BufferedOutputStream实现了带缓冲的输出流。通过设置这样的输出流,应用程序可以将字节写入底层输出流,而不必为每个写入的字节调用底层系统。

对于您的示例,您需要像这样的东西:

String filename= "C:/SO/SOBufferedOutputStreamAnswer";
BufferedOutputStream bos = null;
try {
//create an object of FileOutputStream
FileOutputStream fos = new FileOutputStream(new File(filename));

//create an object of BufferedOutputStream
bos = new BufferedOutputStream(fos);

KeyGenerator kgen = KeyGenerator.getInstance("AES"); 
kgen.init(128); 
SecretKey key = kgen.generateKey(); 
byte[] encoded = key.getEncoded();

bos.write(encoded);

} 
// catch and handle exceptions...

1
+1 如果提到了 BufferedOutputStream。你应该始终将 FileOutputStream 包装在 BufferedOutputStream 中,这样性能会更好。 - Sam Barnum
4
如果你只想往文件中写入一个16字节的密钥,那么将FileOutputStream包装在BufferedOutputStream中可能比直接向FileOutputStream写入数据要慢。 - jarnbjo
@SamBarnum 你能详细解释一下吗?为什么将FOS包装在BOS中更快? - john_science
这取决于您使用哪个write()方法。如果您一次只写入一个字节(或小块),那么会产生大量的磁盘活动。如果您的磁盘是网络挂载的,这可能会导致灾难性后果。 - Sam Barnum
他确实说过“可能会”造成灾难。天啊,该死的开发人员总是要挑剔和争论不休... :P - User

7

链接已失效(Jim)。 - user1531971

4

不需要使用外部库来使事情变得臃肿 - 特别是在处理 Android 时。这里有一个本地解决方案可以实现此目的。以下代码片段来自一个将字节数组存储为图像文件的应用程序。

    // Byte array with image data.
    final byte[] imageData = params[0];

    // Write bytes to tmp file.
    final File tmpImageFile = new File(ApplicationContext.getInstance().getCacheDir(), "scan.jpg");
    FileOutputStream tmpOutputStream = null;
    try {
        tmpOutputStream = new FileOutputStream(tmpImageFile);
        tmpOutputStream.write(imageData);
        Log.d(TAG, "File successfully written to tmp file");
    }
    catch (FileNotFoundException e) {
        Log.e(TAG, "FileNotFoundException: " + e);
        return null;
    }
    catch (IOException e) {
        Log.e(TAG, "IOException: " + e);
        return null;
    }
    finally {
        if(tmpOutputStream != null)
            try {
                tmpOutputStream.close();
            } catch (IOException e) {
                Log.e(TAG, "IOException: " + e);
            }
    }

0
         File file = ...
         byte[] data = ...
         try{
            FileOutputStream fos = FileOutputStream(file);
            fos.write(data);
            fos.flush();
            fos.close();
         }catch(Exception e){
          }

但是如果字节数组长度超过1024,您应该使用循环来写入数据。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接