- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
给定文件
OrangePurpleIndigoPink
Why won't the myWay
method in the code below give me the content of the ByteBuffer
via the Charset.decode
? Notice I validate that the ByteBuffer
has the file content, but it seems no matter what methodology I use from within myWay
, I cannot get the generated CharBuffer
to have the content. The otherWay
method works as expected. Does anyone know what's going on? I've read the javdoc for ByteBuffer and CharBuffer but didn't really see anything that explains this (or I just missed it.) What difference would it make to use FileChannel.read
vs FileChannel.map
if I can show the content of the buffer with read
?
public class Junk {
private static final int BUFFER_SIZE = 127;
private static final String CHARSET = "UTF-8";
public static void main(String[] args) {
try {
String fileName = "two.txt";
myWay(fileName);
otherWay(fileName);
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
private static void myWay(String fileName) throws IOException {
System.out.println("I did it MY WAY!......");
FileChannel channel = FileChannel.open(Paths.get(fileName), StandardOpenOption.READ);
// I tried both `allocate` and `allocateDirect`
ByteBuffer buffer = ByteBuffer.allocateDirect(BUFFER_SIZE);
int bytesRead = channel.read(buffer);
channel.close();
// Manually build the string from the ByteBuffer.
// This is ONLY to validate the buffer has the content
StringBuilder sb = new StringBuilder();
for(int i=0;i<bytesRead;i++){
sb.append((char)buffer.get(i));
}
System.out.println("manual string='"+sb+"'");
CharBuffer charBuffer = Charset.forName(CHARSET).decode(buffer);
// WHY FOR YOU NO HAVE THE CHARS??!!
System.out.println("CharBuffer='" + new String(charBuffer.array()) + "'");
System.out.println("CharBuffer='" + charBuffer.toString() + "'");
System.out.println("........My way sucks.");
}
private static void otherWay(String fileName) throws IOException{
System.out.println("The other way...");
FileChannel channel = FileChannel.open(Paths.get(fileName), StandardOpenOption.READ);
ByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
channel.close();
Charset chars = Charset.forName(CHARSET);
CharBuffer cbuf = chars.decode(buffer);
String str = new String(cbuf.array());
System.out.println("str = '" + str + "'");
System.out.println("...works.");
}
}
输出:
I did it MY WAY!......manual string='OrangePurpleIndigoPink'CharBuffer='������������������������������������������������������������������������������������������������������'CharBuffer='������������������������������������������������������������������������������������������������������'........My way sucks.The other way...str = 'OrangePurpleIndigoPink'...works.
最佳答案
简单而微妙:您不会倒回缓冲区。
当您调用 FileChannel#read(ByteBuffer)
时,那么此方法将推进 position()
缓冲区的:
System.out.println("Before "+buffer.position()); // prints 0
int bytesRead = channel.read(buffer);
System.out.println("After "+buffer.position()); // prints 28
当您随后将其解码为 CharBuffer
时,您基本上会准确地解码那些从未被写入的 99 个字节(并且它们仍然是 0
)。
只需添加
buffer.rewind(); // (or buffer.position(0))
buffer.limit(bytesRead);
在您从文件 channel 读取数据后,decode
方法会准确抓取已接收数据的部分。
关于java - 为什么我使用 FileChannel、ByteBuffer 和 CharBuffer 的方式与其他方式不一样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30630100/
我正在考虑更改 this question进入我的情况。然后我决定我的情况需要自己的问题并希望得到答案。在调用 FileChannel.truncate() 减小文件大小后,我调用 FileChann
我已阅读关于 FileChannel 的 transferFrom 的评论 * This method is potentially much more efficient than a simp
我必须按照小端顺序写一个整数。所以我创建了一个带有 FileChannel 属性和一些写入方法的类(此类不扩展任何内容)。 但是有一个问题:只有一种方法有效,另一种无效! 这里是工作方法(dis是Fi
以下是我将一个文件附加到另一个文件的方法。 public static void appendFile(File baseFile, File newFile) throws IOException
我正在创建一个 fileChannel 来执行内存映射写入。该文件 channel 的大小为 100 字节。我只向其中写入 80 个字节。因此,当我稍后读取该文件时,它会在 and 上添加 5 个“0
我有一个 IO 类,它使用 ByteBuffer 来缓冲对 FileChannel 的访问(因此它基本上在构造函数中接受 FileChannel)。我想对它进行单元测试,所以如果我能得到一个字节数组支
我是 Java NIO 新手。我发现 FileChannel 对象具有读取和写入方法。但我无法在单个时间点使用相同的 FileChannel 进行读写。有没有办法做到这一点? 最佳答案 从具有“rw”
使用 FileChannel.position() 从不同线程写入一个文件是否安全?这对于分段下载是必需的。每个线程都会写入其在文件中的位置,即线程的位置不会相交。 最佳答案 虽然单个选项是线程安全的
在读取大文件时,我从这段代码中得到了一些奇怪的输出,该文件是使用 while 循环打印到 99,999 位数的,但是,在读取文件并打印内容时,它只输出 99,988 行。另外,使用 ByteBuffe
我正在使用fileChannel.lock(long position, long size, boolean shared)获得文件特定部分的独占访问权限。具体代码为: fileChannel.lo
我尝试使用 FileChannel 将特定字节写入文件的特定位置。但实际上文件缩小到我写更改的最后位置。我这样做: Path path = Paths.get("I://music - Cop
我正在使用 FileChannel 将 2MB 数据写入文件。 private void write(int numEntries, int entrySize) throws Exc
我有一个管道,我需要从中读取数据。但是,正如我在阅读之前所了解的那样,我必须创建一定大小的缓冲区。问题是如何定义缓冲区的大小以从管道读取所有数据? 这是我的代码: RandomAccessFile a
我正在尝试使用以下方法连接一组文本文件。但是,只有第一个文件显示在输出文件中。 public void concatenateFiles(List fileLocations, String outp
当我执行以下类(class)时 import java.io.*; import java.nio.*; import java.nio.file.*; import java.nio.channel
我目前正在开发一个应用程序,需要随机访问许多(60k-100k)相对较大的文件。由于打开和关闭流是一项相当昂贵的操作,因此我更愿意将最大文件的 FileChannel 保持打开状态,直到不再需要它们为
我正在使用 RandomAccessFile 打开大文件(~ 200 MB),然后获取它的 Channel。我正在尝试将一些数据映射到 MappedByteBuffer,但出现异常: Channel
文件 a.txt 看起来像: ABC 文件 d.txt 看起来像: DEF 我正在尝试获取“DEF”并将其附加到“ABC”,因此 a.txt 看起来像 ABC DEF 我尝试过的方法总是完全覆盖第一个
对于我的特定任务,我需要从 FileChannel 中读取数据到 Stream (或 Collection )属于 String的。 在常规 NIO对于 Path我们可以使用一个方便的方法Files.
我想我误解了 FileChannel 的锁定功能是如何工作的。 我想在一个文件上拥有独占写入锁,但允许从任何进程读取。 在运行 Java 7 的 Windows 7 机器上,我可以使用 FileCha
我是一名优秀的程序员,十分优秀!