我想使用java.nio.channels.FileChannel从文件中读取内容,但是我想像读取行一样BufferedReader#readLine()。我需要使用java.nio.channels.FileChannel而不是的java.io原因是,我需要在文件上放置一个锁,然后逐行读取该锁文件。所以我被迫使用java.nio.channels.FileChannel。请帮忙
编辑这是我的代码尝试使用FileInputStream获取FileChannel
public static void main(String[] args){
File file = new File("C:\\dev\\harry\\data.txt");
FileInputStream inputStream = null;
BufferedReader bufferedReader = null;
FileChannel channel = null;
FileLock lock = null;
try{
inputStream = new FileInputStream(file);
channel = inputStream.getChannel();
lock = channel.lock();
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String data;
while((data = bufferedReader.readLine()) != null){
System.out.println(data);
}
}catch(IOException e){
e.printStackTrace();
}finally{
try {
lock.release();
channel.close();
if(bufferedReader != null) bufferedReader.close();
if(inputStream != null) inputStream.close(); …Run Code Online (Sandbox Code Playgroud) 我已经实现了一个在我的计算机上运行的数据结构,现在我正在尝试将其移植到我的Android应用程序中.我打开一个原始.dat资源并得到一个,InputStream但我需要得到一个FileInputStream:
FileInputStream fip = (FileInputStream) context.getResources().openRawResource(fileID);
FileChannel fc = fip.getChannel();
long bytesSizeOfFileChannel = fc.size();
MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0L, bytesSizeOfFileChannel);
...
Run Code Online (Sandbox Code Playgroud)
上面的代码抛出以下异常,因为无法将InputStream强制转换为FileInputStream,但这正是我需要的:
java.lang.ClassCastException: android.content.res.AssetManager$AssetInputStream cannot be cast to java.io.FileInputStream
Run Code Online (Sandbox Code Playgroud)
我的所有代码都是使用FileChannelFileInputStream 构建的,所以我想继续使用它.有没有办法从具有去InputStream从context.getResources().openRawResource(fileID),然后将其转换成一个FileChannel?
一些相关的帖子,我找不到一个工作的解决方案,我的情况下android:
如何将InputStream转换为FileInputStream
将inputStream转换为FileInputStream?
我正在为DNG / TIFF文件编写读写器。一般而言FileInputStream,有几种处理文件的选项(FileChannel,RandomAccessFile),我不知道哪个策略是适合我的需要。
DNG / TIFF文件由以下内容组成:
整个文件的大小范围从15 MiB(压缩的14位原始数据)到大约100 MiB(未压缩的浮点数据)。要处理的文件数为50-400。
有两种使用模式:
我目前正在使用,FileChannel并执行map()来获取MappedByteBuffer覆盖整个文件的信息。如果我只想读取元数据,这似乎很浪费。另一个问题是释放映射的内存:当我四处传递映射缓冲区的切片以进行解析等时,底层MappedByteBuffer将不会收集。
我现在决定FileChannel使用几种read()方法复制较小的块,并仅映射大的原始数据区域。缺点是读取单个值似乎非常复杂,因为没有readShort()诸如此类:
short readShort(long offset) throws IOException, InterruptedException {
return read(offset, Short.BYTES).getShort();
}
ByteBuffer read(long offset, long byteCount) throws IOException, InterruptedException {
ByteBuffer buffer = ByteBuffer.allocate(Math.toIntExact(byteCount));
buffer.order(GenericTiffFileReader.this.byteOrder);
GenericTiffFileReader.this.readInto(buffer, offset);
return buffer;
}
private void readInto(ByteBuffer buffer, long startOffset)
throws IOException, InterruptedException {
long offset …Run Code Online (Sandbox Code Playgroud) 我想说清楚,并立即在FileOutputStream和FileChannel之间绘制一些相似之处.
首先,使用标准Java io编写文件的最有效方法似乎是使用包含BufferedOutputStream的FileOutputStream.因为它会在内部缓冲区溢出时自动刷新.能够进行单次写入(单字节,浮点数等)以及数组写入并且不担心速度是很方便的.你唯一不应该忘记的是关闭它(进行最后的冲洗).使用BufferedOutputStream包装器的好处很明显,每个人都必须拥有(我希望).
现在关于FileChannel.FileChannel有force方法,它相当于FileOutputStream中的flush,不是吗?并且javadocs清楚地说,您应该使用它来确保您对目标文件进行了更改.但是,如果没有"BufferedFileChannel"包装器,我不明白何时以及为什么要使用它.换句话说,FileChannel的缓冲在哪里?它是自动的并隐藏在FileChannel本身,就像在BufferedOutputStream中一样吗?如果没有,那么为什么我需要强制方法,因为没有什么可以强制的(所有更改都已经在使用write方法后应用于文件)并且我必须自己实现缓冲吗?
我正在使用ByteBuffers并将FileChannels二进制数据写入文件.当为大文件或连续多个文件执行此操作时,我得到一个OutOfMemoryError例外.我在其他地方读过,Bytebuffers与NIO一起使用已被打破,应该避免.你们中是否有人遇到过这种问题,并找到了一个有效地在java文件中保存大量二进制数据的解决方案?
jvm选项是否可行-XX:MaxDirectMemorySize?
我正在为FileChannel编写一个实用程序类。
下面的方法看起来可能有效。
// tries to transfer as many bytes as specified
public static long transferTo(final FileChannel src, long position,
long count, final WritableByteChannel dst)
throws IOException {
long accumulated = 0L;
while (position < src.size()) {
final long transferred = src.transferTo(position, count, dst);
position += transferred;
count -= transferred;
accumulated += transferred;
}
return accumulated;
}
Run Code Online (Sandbox Code Playgroud)
但是版本transferFrom有问题。
// tries to transfer as many bytes as specified
public static long transferFrom(final FileChannel dst,
final ReadableByteChannel src,
long …Run Code Online (Sandbox Code Playgroud) 在java中,有FileChannel,我可以从文件通道读取.我也可以在我想要开始阅读的频道中设置位置.
C++/C中的任何类似函数?
为什么java.nio.FileChannel transferTo()和transferFrom()比一些JVM/OS组合上的逐字节传输(基于流或使用ByteBuffer)更快?
这些方法是否使用直接内存访问(DMA)而不是为每个字节传输发出中断请求(IRQ)?
我正在写一个文件的值.
值写得正确.在另一个应用程序中,我可以无任何例外地读取文件.
但是在我的新应用程序中,我Bufferunderflowexception在尝试读取文件时得到了一个.
我花了好几天来解决这个问题,但我只是不知道如何解决它.
做了很多研究.
该bufferunderflowexception指:
Double X1 = mappedByteBufferOut.getDouble(); //8 byte (double)
Run Code Online (Sandbox Code Playgroud)
这是我读取文件的代码:
@Override
public void paintComponent(Graphics g) {
RandomAccessFile randomAccessFile = null;
MappedByteBuffer mappedByteBufferOut = null;
FileChannel fileChannel = null;
try {
super.paintComponent(g);
File file = new File("/home/user/Desktop/File");
randomAccessFile = new RandomAccessFile(file, "r");
fileChannel = randomAccessFile.getChannel();
mappedByteBufferOut = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, randomAccessFile.length());
while (mappedByteBufferOut.hasRemaining()) {
Double X1 = mappedByteBufferOut.getDouble(); //8 byte (double)
Double Y1 = mappedByteBufferOut.getDouble();
Double X2 = mappedByteBufferOut.getDouble();
Double Y2 = mappedByteBufferOut.getDouble();
int …Run Code Online (Sandbox Code Playgroud) java filechannel exception bufferunderflowexception paintcomponent
我试图找到一种以最快的方式复制大文件的方法......
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
public class FastFileCopy {
public static void main(String[] args) {
try {
String from = "...";
String to = "...";
FileInputStream fis = new FileInputStream(from);
FileOutputStream fos = new FileOutputStream(to);
ArrayList<Transfer> transfers = new ArrayList<>();
long position = 0, estimate;
int count = 1024 * 64;
boolean lastChunk = false;
while (true) {
if (position + count < fis.getChannel().size()) {
transfers.add(new Transfer(fis, fos, position, position + count));
position += count + …Run Code Online (Sandbox Code Playgroud) 尝试复制2GB左右大小的文件时,FileChannel.transferFrom(source,0,source.size())提供以下OutOfMemory异常。我了解由于文件较大而导致的内存问题。我们是否可以通过循环处理小块文件来解决问题?
01-22 17:27:03.365: W/System.err(28538): java.io.IOException: mmap failed: ENOMEM (Out of memory)
01-22 17:27:03.375: W/System.err(28538): at java.nio.MemoryBlock.mmap(MemoryBlock.java:119)
01-22 17:27:03.375: W/System.err(28538): at java.nio.FileChannelImpl.map(FileChannelImpl.java:249)
01-22 17:27:03.380: W/System.err(28538): at java.nio.FileChannelImpl.transferFrom(FileChannelImpl.java:381)
01-22 17:27:03.380: W/System.err(28538): at com.druva.inSync.util.InSyncIOUtils.copyFile(InSyncIOUtils.java:123)
01-22 17:27:03.380: W/System.err(28538): at com.druva.inSync.AsyncTasks.ProcessUploadTask.getFileItemForFile(ProcessUploadTask.java:102)
01-22 17:27:03.380: W/System.err(28538): at com.druva.inSync.AsyncTasks.ProcessUploadTask.processUploads(ProcessUploadTask.java:124)
01-22 17:27:03.380: W/System.err(28538): at com.druva.inSync.AsyncTasks.ProcessUploadTask.doInBackground(ProcessUploadTask.java:53)
01-22 17:27:03.380: W/System.err(28538): at com.druva.inSync.AsyncTasks.ProcessUploadTask.doInBackground(ProcessUploadTask.java:1)
01-22 17:27:03.380: W/System.err(28538): at android.os.AsyncTask$2.call(AsyncTask.java:287)
01-22 17:27:03.380: W/System.err(28538): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
01-22 17:27:03.380: W/System.err(28538): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
01-22 17:27:03.380: W/System.err(28538): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
01-22 17:27:03.380: W/System.err(28538): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
01-22 17:27:03.380: W/System.err(28538): at …Run Code Online (Sandbox Code Playgroud) filechannel ×11
java ×8
nio ×4
android ×2
bytebuffer ×2
buffering ×1
c ×1
c++ ×1
dma ×1
exception ×1
file-copying ×1
io ×1
irq ×1
jvm ×1