如何使用 java.nio.channels.FileChannel 将字节 [] 写入文件 - 基础知识

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10166011/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 23:53:23  来源:igfitidea点击:

How to use java.nio.channels.FileChannel to write a byte[] to a file - Basics

java

提问by Dan Nissenbaum

I do not have experience using Java channels. I would like to write a byte array to a file. Currently, I have the following code:

我没有使用 Java 频道的经验。我想将字节数组写入文件。目前,我有以下代码:

String outFileString = DEFAULT_DECODED_FILE; // Valid file pathname
FileSystem fs = FileSystems.getDefault();
Path fp = fs.getPath(outFileString);

FileChannel outChannel = FileChannel.open(fp, EnumSet.of(StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE));

// Please note: result.getRawBytes() returns a byte[]
ByteBuffer buffer = ByteBuffer.allocate(result.getRawBytes().length);
buffer.put(result.getRawBytes());

outChannel.write(buffer); // File successfully created/truncated, but no data

With this code, the output file is created, and truncated if it exists. Also, in the IntelliJ debugger, I can see that buffercontains data. Also, the line outChannel.write()is successfully called without throwing an exception. However, after the program exits, the data does not appear in the output file.

使用此代码,将创建输出文件,如果存在则将其截断。此外,在 IntelliJ 调试器中,我可以看到buffer包含数据。此外,该行outChannel.write()已成功调用而不会引发异常。但是,程序退出后,数据不会出现在输出文件中。

Can somebody (a) tell me if the FileChannel API is an acceptable choice for writing a byte array to a file, and (b) if so, how should the above code be modified to get it to work?

有人可以 (a) 告诉我 FileChannel API 是否是将字节数组写入文件的可接受选择,以及 (b) 如果是,应如何修改上述代码以使其正常工作?

回答by Greg Kopff

As gulyan points out, you need to flip()your byte buffer before writing it. Alternately, you could wrap your original byte array:

正如 gulyan 指出的那样,您需要flip()在写入之前使用字节缓冲区。或者,您可以包装原始字节数组:

ByteBuffer buffer = ByteBuffer.wrap(result.getRawBytes());

To guarantee the write is on disk, you need to use force():

为了保证写入在磁盘上,您需要使用force()

outChannel.force(false);

Or you could close the channel:

或者你可以关闭频道:

outChannel.close();

回答by gulyan

You should call:

你应该打电话:

buffer.flip();

before the write.

在写之前。

This prepares the buffer for reading. Also, you should call

这为读取准备了缓冲区。另外,你应该打电话

buffer.clear();

before putting data into it.

在放入数据之前。

回答by Mike Q

To answer your first question

回答你的第一个问题

tell me if the FileChannel API is an acceptable choice for writing a byte array to a file

告诉我 FileChannel API 是否是将字节数组写入文件的可接受选择

It's ok but there's simpler ways. Try using a FileOutputStream. Typically this would be wrapped by a BufferedOutputStreamfor performance but the key is both of these extend OutputStreamwhich has a simple write(byte[])method. This is much easier to work with than the channel/buffer API.

没关系,但有更简单的方法。尝试使用FileOutputStream. 通常这会被一个BufferedOutputStream用于性能的包装,但关键是这两个扩展OutputStream都有一个简单的write(byte[])方法。这比通道/缓冲区 API 更容易使用。

回答by Ajay Kumar

Here is a complete example of FileChannel.

这是一个完整的 FileChannel 示例。

    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.RandomAccessFile;
    import java.nio.ByteBuffer;
    import java.nio.channels.FileChannel;
    import java.nio.channels.WritableByteChannel;


    public class FileChannelTest {
        // This is a Filer location where write operation to be done.
        private static final String FILER_LOCATION = "C:\documents\test";
        // This is a text message that to be written in filer location file.
        private static final String MESSAGE_WRITE_ON_FILER = "Operation has been committed.";

        public static void main(String[] args) throws FileNotFoundException {
            // Initialized the File and File Channel
            RandomAccessFile randomAccessFileOutputFile = null;
            FileChannel outputFileChannel = null;
            try {
                // Create a random access file with 'rw' permission..
                randomAccessFileOutputFile = new RandomAccessFile(FILER_LOCATION + File.separator + "readme.txt", "rw");
                outputFileChannel = randomAccessFileOutputFile.getChannel();
                //Read line of code one by one and converted it into byte array to write into FileChannel.
                final byte[] bytes = (MESSAGE_WRITE_ON_FILER + System.lineSeparator()).getBytes();
                // Defined a new buffer capacity.
                ByteBuffer buffer = ByteBuffer.allocate(bytes.length);
                // Put byte array into butter array.
                buffer.put(bytes);
                // its flip the buffer and set the position to zero for next write operation.
                buffer.flip();
                /**
                 * Writes a sequence of bytes to this channel from the given buffer.
                 */
                outputFileChannel.write(buffer);
                System.out.println("File Write Operation is done!!");

            } catch (IOException ex) {
                System.out.println("Oops Unable to proceed file write Operation due to ->" + ex.getMessage());
            } finally {
                try {
                    outputFileChannel.close();
                    randomAccessFileOutputFile.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }

        }

    }