Tag: nio

每个客户一个线程。 可行?

我正在编写一个Java服务器,它使用普通套接字来接受来自客户端的连接。 我正在使用相当简单的模型,其中每个连接在阻塞模式下都有自己的线程读取。 伪代码: handshake(); while(!closed) { length = readHeader(); // this usually blocks a few seconds readMessage(length); } cleanup(); (线程是从Executors.newCachedThreadPool()创建的,所以启动它们不会有任何重大开销) 我知道这是一个天真的设置,如果线程是专用的OS线程,它不会很好地扩展到许多连接。 但是,我听说Java中的多个线程可以共享一个硬件线程。 真的吗? 知道我将在Linux上使用Hotspot VM,在具有8核和12GB RAM的服务器上,你认为这个设置适用于成千上万的连接吗? 如果没有,有哪些替代方案?

Java应用程序是否有获得root权限的方法?

当运行Files.walk(Paths.get(“/var/”)).count()作为非特权用户时,执行可能会抛出exception,因为/var/中的文件夹需要遍历root权限。 我不是在寻找一种以root身份执行bash命令的方法(例如sudo find /var ),使用Process等。 我只是想确保Files.walk(Paths.get(“/var/”)).count()不会抛出AccessDeniedException : Exception in thread “restartedMain” java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0 at sun.reflect.NativeMethodAccessorImpl.invoke at sun.reflect.DelegatingMethodAccessorImpl.invoke at java.lang.reflect.Method.invoke at org.springframework.boot.devtools.restart.RestartLauncher.run Caused by: java.io.UncheckedIOException: java.nio.file.AccessDeniedException: /var/cache/httpd at java.nio.file.FileTreeIterator.fetchNextIfNeeded at java.nio.file.FileTreeIterator.hasNext at java.util.Iterator.forEachRemaining at java.util.Spliterators$IteratorSpliterator.forEachRemaining at java.util.stream.AbstractPipeline.copyInto at java.util.stream.AbstractPipeline.wrapAndCopyInto at java.util.stream.ReduceOps$ReduceOp.evaluateSequential at java.util.stream.AbstractPipeline.evaluate at java.util.stream.LongPipeline.reduce at java.util.stream.LongPipeline.sum at java.util.stream.ReferencePipeline.count at com.example.DemoApplication.main … 5 more Caused […]

Java NIO MappedByteBuffer OutOfMemoryException

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

Java中的非阻塞文件IO

我想写一个命名管道(已经创建)而不会阻塞读取器。 我的读者是另一个可能会失败的应用程序。 如果读者确实失败了,我希望编写器应用程序继续写入该命名管道。 像Java这样的东西 fopen(fPath, O_NONBLOCK) 因此,当读者出现时,它可能会从失败的地方恢复。

为什么要在java nio中的`selector.selectedKeys()。iterator()`中删除键?

我找到了一些java nio的示例代码: ServerSocketChannel server = ServerSocketChannel.open(); Selector selector = Selector.open(); server.socket().bind(new InetSocketAddress(8080)); server.configureBlocking(false); server.register(selector, SelectionKey.OP_ACCEPT); while(true) { selector.select(); Iterator iter = selector.selectedKeys().iterator(); while (iter.hasNext()) { SelectionKey key = (SelectionKey) iter.next(); iter.remove(); // Why remove it? process(key); } } 当他获得所选键时,他会删除循环中的键。 我们为什么要这样做? UPDATE 感谢EJP和user270349提供的答案,我想我现在明白了,让我详细解释一下。 选择器中有2个表: 注册表:当我们调用channel.register ,会有一个新项(key)。 只有当我们调用key.cancel() ,它才会从此表中删除。 准备选择表:当我们调用selector.select() ,选择器将查找注册表,找到可用的键,将它们的引用复制到该选择表中。 选择器不会清除此表的项目(这意味着,即使我们再次调用selector.select() ,它也不会清除现有项目) 这就是为什么当我们从选择表中获取密钥时,我们必须调用iter.remove() 。 如果没有,我们将通过selector.selectedKeys()一次又一次地获取密钥,即使它还没有准备好使用。

在Java中,监视附加到的文件的最佳/最安全模式是什么?

其他人的过程是在事件发生时通过一次添加一行来创建CSV文件。 我无法控制文件格式或其他进程,但我知道它只会附加。 在Java程序中,我想监视这个文件,当附加一行时,读取新行并根据内容做出反应。 暂时忽略CSV解析问题。 监视文件以进行更改并一次读取一行的最佳方法是什么? 理想情况下,这将使用标准库类。 该文件可能在网络驱动器上,所以我想要一些强大的失败。 如果可能的话我宁愿不使用轮询 – 我更喜欢某种阻塞解决方案。 编辑 – 鉴于标准类无法实现阻塞解决方案(感谢您的回答),最强大的轮询解决方案是什么? 我不想每次重读整个文件,因为它可能会变得非常大。

检测sockets断开?

我有点不高兴,这不能以优雅的方式处理,在尝试了几个SO问题的答案中提到的不同解决方案( 这个 , 这个和其他几个)之后,我仍然无法检测到sockets断开(通过拔掉电缆)。 我正在使用NIO非阻塞套接字,除了我发现无法检测服务器断开连接外,一切都运行正常。 我有以下代码: while (true) { handlePendingChanges(); int selectedNum = selector.select(3000); if (selectedNum > 0) { SelectionKey key = null; try { Iterator keyIterator = selector.selelctedKeys().iterator(); while (keyIterator.hasNext()) { key = keyIterator.next(); if (!key.isValid()) continue; System.out.println(“key state: ” + key.isReadable() + “, ” + key.isWritable()); if (key.isConnectable()) { finishConnection(key); } else if […]

Java:从具有缓冲输入的随机访问文件中读取字符串

我之前从未接触过Java IO API的经验,现在我真的很沮丧。 我发现很难相信它有多奇怪和复杂,做一个简单的任务有多难。 我的任务:我有2个位置(起始字节,结束字节), pos1和pos2 。 我需要读取这两个字节之间的行(包括起始字节,不包括结尾字节),并将它们用作UTF8字符串对象。 例如,在大多数脚本语言中,它将是一个非常简单的1-2-3-liner(在Ruby中,但对于Python,Perl等基本相同): f = File.open(“file.txt”).seek(pos1) while f.pos < pos2 { s = f.readline # do something with "s" here } Java IO API很快就会出现问题;)实际上,我看到了两种从常规本地文件中读取行(以\n结尾)的方法: RandomAccessFile有getFilePointer()和seek(long pos) ,但它的readLine()读取非UTF8字符串(甚至不是字节数组),但编码破坏的字符串非常奇怪,并且没有缓冲(这可能意味着每次read*()调用将被翻译成单个不正确的OS read() =>相当慢)。 BufferedReader有很好的readLine()方法,它甚至可以用skip(long n)进行一些搜索,但它无法确定已经读取的偶数字节数,也没有提到文件中的当前位置。 我试过用类似的东西: FileInputStream fis = new FileInputStream(fileName); FileChannel fc = fis.getChannel(); BufferedReader br = new BufferedReader( new InputStreamReader( fis, […]

增量读取大文件的最快方法

给定MAX_BUFFER_SIZE的缓冲区,并且文件远远超过它时,如何: 以MAX_BUFFER_SIZE块的forms读取文件? 尽可能快地完成 我尝试使用NIO RandomAccessFile aFile = new RandomAccessFile(fileName, “r”); FileChannel inChannel = aFile.getChannel(); ByteBuffer buffer = ByteBuffer.allocate(CAPARICY); int bytesRead = inChannel.read(buffer); buffer.flip(); while (buffer.hasRemaining()) { buffer.get(); } buffer.clear(); bytesRead = inChannel.read(buffer); aFile.close(); 和常规IO InputStream in = new FileInputStream(fileName); long length = fileName.length(); if (length > Integer.MAX_VALUE) { throw new IOException(“File is too large!”); } […]

将文件写入ServletOutputStream的最有效方法

ServletOutputStream output = response.getOutputStream(); output.write(byte[]); 将文件写入javax.servlet.ServletOutputStream的最有效方法是什么? 编辑: 如果使用NIO,这不会更有效吗?