Tag: filechannel

尝试同时读取时,Java滚动文件创建失败

我正在使用java.util日志记录类来创建滚动文件appender。 我想创建一个日志阅读器,当数据写入它们时从这些日志中读取。 滚动日志appender代码本身可以正常工作。 但是一旦我启动阅读器线程,就不会创建新文件,即如果将滚动日志appender设置为使用5个文件,它将创建1og.0,log.1,log.2等等但是如果阅读器线程启动则它将仅创建log.0没有创建其他文件。 我在java logging和log4j中都注意到了这一点。 我正在使用nio来读取日志阅读器。 所以我的疑问是,在同一个文件上创建另一个FileChannel会产生一些问题吗? 或者我错过了一些导致问题的基本nio内容。 这是代码.. public class Test { private static final long initialTime = System.currentTimeMillis(); private static Logger logger = Logger.getLogger(Test.class.getName()); public static void main(String[] args) { logger.setLevel(Level.INFO); try { BufferedReader reader = new BufferedReader( new InputStreamReader( new FileInputStream( new File(System.getProperty(“user.dir”)+File.separator+”input.dat”)))); FileHandler handler = new FileHandler(“log/test.log”, 1024, 5, true); […]

使用FileChannel和ByteArrays读取ASCII文件

我有以下代码: String inputFile = “somefile.txt”; FileInputStream in = new FileInputStream(inputFile); FileChannel ch = in.getChannel(); ByteBuffer buf = ByteBuffer.allocateDirect(BUFSIZE); // BUFSIZE = 256 /* read the file into a buffer, 256 bytes at a time */ int rd; while ( (rd = ch.read( buf )) != -1 ) { buf.rewind(); for ( int i = 0; […]

我应该关闭FileChannel吗?

我今天遇到了一个我们的实用工具类的问题。 它是文件的帮助程序,包含一些静态文件复制例程。 以下是与测试方法一起提取的相关方法。 问题是有时setLastModified调用失败,返回false。 在我的PC上(Windows 7,最新的Java),我有时会收到“setLastModified failed”消息(大约25次中的1000次)。 我现在通过删除FileChannel.close调用解决了这个问题,但我更愿意理解为什么会发生这种情况,即使这是正确的解决方案。 有没有其他人得到同样的问题? private void testCopy() throws FileNotFoundException, IOException { File src = new File(“C:\\Public\\Test-Src.txt”); File dst = new File(“C:\\Public\\Test-Dst.txt”); for (int i = 0; i < 1000; i++) { copyFile(src, dst); } } public static void copyFile(final File from, final File to) throws FileNotFoundException, IOException { final String […]

java filechannel cpu用法随着时间的推移而增长

我正在使用java nio filechannel transferFrom函数和Apache httpclient从Internet下载文件。 它正常启动但一段时间后cpu使用量突然增长。 并且下载速度降低并最终变为零。 try (CloseableHttpResponse response = client.execute(get); ReadableByteChannel inputChannel = Channels.newChannel( response.getEntity().getContent())) { while (start < end && currentState.get() == 1) { delta = fileChannel.transferFrom(inputChannel, start, 8192); start += delta; bytesDone.addAndGet(delta); intialState.set(name, start); } } 由于声誉低,Sry无法发布图像

Java NIO通过ByteBuffer扫描某些字节和带有节的字

好吧,所以我正在尝试做一些看起来应该相当简单的事情,但是对于这些新的NIO接口,事情让我感到困惑! 这是我正在尝试做的事情,我需要扫描一个文件作为字节,直到遇到某些字节! 当我遇到这些特定字节时,需要抓住该段数据并对其执行某些操作,然后再继续执行此操作。 我本以为在ByteBuffer中有了所有这些标记,位置和限制,我能够做到这一点,但我似乎无法让它工作! 这是我到目前为止所拥有的…… test.text: this is a line of text a this is line 2b line 3 line 4 line etc.etc.etc. Test.java: import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.charset.Charset; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; public class Test { public static final Charset ENCODING = Charset.forName(“UTF-8”); public static final byte[] NEWLINE_BYTE = […]

FileChannel#write总是会写出整个缓冲区吗?

(这与(或者更确切地说是“相反”)有关。 如果有足够的数据,FileChannel.read会读取比指定的更少的字节吗? ) TL; DR : 这总是会写出整个缓冲区…… ByteBuffer bytes = …; fileOutputStream.getChannel().write(bytes); …或者是否有必要使用这样的循环: ByteBuffer bytes = …; while (bytes.remaining() > 0) { fileOutputStream.getChannel().write(bytes); } ? 由于另一个答案的评论 ,我想问一下,通过调用FileChannel#write(ByteBuffer)是否对将Buffer写入FileChannel的行为有任何保证。 仅供参考:文档说明 从给定缓冲区向该通道写入一个字节序列。 除非通道处于追加模式,否则从该通道的当前文件位置开始写入字节,在这种情况下,位置首先前进到文件的末尾。 如有必要,文件将生长以容纳写入的字节,然后使用实际写入的字节数更新文件位置。 否则,此方法的行为与WritableByteChannel接口指定的完全相同。 以及重写方法的文档, WritableByteChannel#write(ByteBuffer)说 从给定缓冲区向该通道写入一个字节序列。 尝试向通道写入最多r个字节,其中r是缓冲区中剩余的字节数,即src.remaining(),此时调用此方法。 假设写入长度为n的字节序列,其中0 <= n <= r。 该字节序列将从索引p开始从缓冲区传输,其中p是调用此方法时缓冲区的位置; 写入的最后一个字节的索引将是p + n – 1.返回时,缓冲区的位置将等于p + n; 它的限制不会改变。 除非另有说明,否则只有在写入所有r请求的字节后才会返回写操作。 某些类型的通道(取决于它们的状态)可能只写入一些字节,或者根本不写。 例如,处于非阻塞模式的套接字通道不能再写入套接字输出缓冲区中可用的字节数。 可以随时调用此方法。 但是,如果另一个线程已经在此通道上启动了写操作,则此方法的调用将阻塞,直到第一个操作完成。 […]

Java NIO MappedByteBuffer OutOfMemoryException

我真的遇到了麻烦:我想使用FileChannel和MappedByteBuffer读取几GB的HUGE文件 – 我发现的所有文档都暗示使用FileChannel.map()方法映射文件相当简单。 当然,限制在2GB,因为所有Buffer方法都使用int来定位,限制和容量 – 但系统隐含的限制如何呢? 实际上,我遇到了很多关于OutOfMemoryException的问题! 并没有真正定义限制的文档! 那么 – 如何将一个适合int-limit的文件安全地映射到一个或多个MappedByteBuffer而不仅仅是获得exception? 在尝试FileChannel.map()之前,我可以问系统我可以安全地映射文件的哪个部分? 怎么样? 为什么关于这个function的文档很少?

multithreading可以在Java中看到直接映射的ByteBuffer上的写入吗?

我正在开发一些使用ByteBuffers的东西,它使用内存映射文件(通过FileChannel.map() )以及内存中的直接ByteBuffers构建。 我试图了解并发和内存模型约束。 我已经阅读了FileChannel,ByteBuffer,MappedByteBuffer等所有相关的Javadoc(和源代码)。很明显,特定的ByteBuffer(和相关的子类)有一堆字段,并且状态不受内存模型的保护观点看法。 因此,如果跨线程使用该缓冲区,则必须在修改特定ByteBuffer的状态时进行同步。 常见的技巧包括使用ThreadLocal包装ByteBuffer,复制(同步)以获取指向相同映射字节的新实例等。 鉴于这种情况: manager有一个映射的字节缓冲区B_all用于整个文件(比如它<2gb) 管理器调用B_all上的duplicate(),position(),limit()和slice()来创建一个新的较小的ByteBuffer B_1 ,该文件的一大块并将其提供给线程T1 manager执行所有相同的操作来创建指向相同映射字节的ByteBuffer B_2并将其提供给线程T2 我的问题是:T1能否同时写入B_1和T2写入B_2并保证看到彼此的变化? T3是否可以使用B_all读取这些字节并保证看到T1和T2的变化? 我知道,除非您使用force()指示操作系统将页面写入磁盘,否则不一定会在进程中看到映射文件中的写入。 我不在乎。 假设这个问题,这个JVM是编写单个映射文件的唯一进程。 注意:我不是在寻找猜测(我可以自己做得很好)。 我想引用一些关于内存映射直接缓冲区保证(或不保证)的内容。 或者,如果您有实际经验或负面测试用例,那么这也可以作为充分的证据。 更新:我已经完成了一些测试,让多个线程并行写入同一个文件,到目前为止,这些写入似乎可以从其他线程立即看到。 我不确定我是否可以依赖它。