当前位置: 首页 > 面试题库 >

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

鲜于阳
2023-03-14
问题内容

好的,所以我试图做的事情看起来应该很简单,但是有了这些新的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 = {0x0A, 0x0D};

    public Test() {

        String pathString = "test.txt";

        //the path to the file
        Path path = Paths.get(pathString);

        try (FileChannel fc = FileChannel.open(path, 
                StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE)) {            
            if (fc.size() > 0) {
                int n;
                ByteBuffer buffer = ByteBuffer.allocate((int) fc.size());
                do {                    
                    n = fc.read(buffer);
                } while (n != -1 && buffer.hasRemaining());
                buffer.flip();
                int pos = 0;
                System.out.println("FILE LOADED: |" + new String(buffer.array(), ENCODING) + "|");
                do {
                    byte b = buffer.get();
                    if (b == NEWLINE_BYTE[0] || b == NEWLINE_BYTE[1]) {
                        System.out.println("POS: " + pos);
                        System.out.println("POSITION: " + buffer.position());
                        System.out.println("LENGTH: " + Integer.toString(buffer.position() - pos));
                        ByteBuffer lineBuffer = ByteBuffer.wrap(buffer.array(), pos + 1, buffer.position() - pos);
                        System.out.println("LINE: |" + new String(lineBuffer.array(), ENCODING) + "|");
                        pos = buffer.position();
                    }
                } while (buffer.hasRemaining());
            } 
        } catch (IOException ioe) {
           ioe.printStackTrace();
        }
    }
    public static void main(String args[]) {
        Test t = new Test();
    }
}

因此,第一部分开始工作,fc.read(buffer)函数仅运行一次并将整个文件拉入ByteBuffer。然后在第二个do循环中,我可以逐个字节地循环播放,当它命中\
n(或\
r)时,它确实命中了if语句,但后来我不知道该如何获取我刚刚浏览过的字节的一部分进入了一个单独的字节数组以供使用!我已经尝试了拼接和各种翻转,并且尝试了如上面的代码中所示的wrap,但是似乎无法使其正常工作,两个缓冲区都始终具有完整的文件,因此我拼接或结束的所有内容也是如此!

我只需要逐字节地遍历文件,一次查看某个部分,然后是我的最终目标,当我查看并找到正确的位置时,我想在正确的位置插入一些数据!我需要lineBuffer输出的lineBuffer,以使到目前为止只有我循环的那部分字节!帮帮忙,谢谢!


问题答案:

这是我最终得到的解决方案,每次使用ByteBuffer的批量相对get函数来获取块。我想我正在按预期使用mark()功能,尽管我正在使用其他变量(pos)来跟踪标记,因为我无法在ByteBuffer中找到函数来返回标记本身的相对位置。另外,我还有显式的功能可以按顺序查找\
r,\ n或两者。请记住,此代码仅适用于UTF-8编码的数据。我希望这可以帮助其他人。

public class Test {
    public static final Charset ENCODING = Charset.forName("UTF-8");
    public static final byte[] NEWLINE_BYTES = {0x0A, 0x0D};

    public Test() {
        //test text file sequence of any strings followed by newline
        String pathString = "test.txt";
        Path path = Paths.get(pathString);

        try (FileChannel fc = FileChannel.open(path, 
                StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE)) {

            if (fc.size() > 0) {
                int n;
                ByteBuffer buffer = ByteBuffer.allocate((int) fc.size());
                do {                    
                    n = fc.read(buffer);
                } while (n != -1 && buffer.hasRemaining());
                buffer.flip();
                int newlineByteCount = 0;
                buffer.mark();
                do {
                    //get one byte at a time
                    byte b = buffer.get();

                    if (b == NEWLINE_BYTES[0] || b == NEWLINE_BYTES[1]) {
                        newlineByteCount++;

                        byte nextByte = buffer.get();
                        if (nextByte == NEWLINE_BYTES[1]) {
                            newlineByteCount++;
                        } else {
                            buffer.position(buffer.position() - 1);
                        }

                        int pos = buffer.position();
                        //reset the buffer back to the mark() position
                        buffer.reset();
                        //create an array just the right length and get the bytes we just measured out 
                        int length = pos - buffer.position() - newlineByteCount;
                        byte[] lineBytes = new byte[length];
                        buffer.get(lineBytes, 0, length);

                        String lineString = new String(lineBytes, ENCODING);
                        System.out.println("LINE: " + lineString);

                        buffer.position(buffer.position() + newlineByteCount);

                        buffer.mark();
                        newlineByteCount = 0;
                    } else if (newlineByteCount > 0) {

                    }
                } while (buffer.hasRemaining());
            } 
        } catch (IOException ioe) { ioe.printStackTrace(); }
    }
    public static void main(String args[]) { new Test(); }
}


 类似资料:
  • 好吧,所以我试图做一些看起来应该相当简单的事情,但是有了这些新的NIO接口,事情让我很困惑!这是我想做的,我需要扫描文件作为字节,直到遇到某些字节!当我遇到那些特定的字节时,需要抓住数据的那一部分并对其做一些事情,然后继续前进并再次这样做。我本以为在ByteBuffer中有了所有这些标记、位置和限制,我就能做到这一点,但我似乎无法让它工作!这是我到目前为止... 测验正文: Test.java:

  • 问题 假设我的工作是扫描从直接字节缓冲区读回的所有字节,那么对我来说最快的方法是什么? 我最初问“...利用sun.misc.unsafe”,但这可能是错误的假设。 null 这不同于“我可以使用Unsafe来更快地迭代一个字节[]吗?”问题是,如果没有必要,我甚至不打算在内部将字节拉到byte[]中。 谢谢你抽出时间;只是好奇如果有人(彼得?)做这样的事不安全。

  • 我创建了一个简单的扫描器,用于计算中的字符串数。txt文件。每个字符串位于下一行。它算错了,每次它给我数字297,甚至有超过20000个字符串。这个txt文件是由我编写的另一个程序创建的,它从网站获取链接,并使用FileWriter和BufferedWriter将其保存到。txt文件。可能有什么问题? 编辑:字符串示例:

  • 我正在建立一个自定义的文件创建与Android应用程序。我试图将Bytebuffer的内容(它是我创建的自定义类中的字符串成员)写入字节类型的文件。但是,每当我这样做时,我得到的是字符串格式的文件内容。我尝试了几种替代方法,例如使用get方法、BufferedOutputStream类、ByteArrayOutputStream类、DataOutputStream类、Filechannel类等。以

  • 我需要通过Java socket发送一个文本消息到服务器,然后发送一个字节数组,然后是一个字符串等等。到目前为止,我所开发的内容还在工作,但客户端只读取发送的第一个字符串。 从服务器端:我使用发送字节数组,使用发送字符串。 问题是客户机和服务器不同步,我的意思是服务器发送字符串然后字节数组然后字符串,而不等待客户机消耗每个需要的字节。 我的意思是情况不是这样的:

  • 我试图使用Jenkins、FxCop和Sonarqube分析一个C#项目。目前,我使用的构建步骤是“用于MSBuild-Begin Analysis的Sonarqube Scanner”、“FxCop Exec.”、“使用MSBuild构建Visual Studio项目或解决方案”和“用于MSBuild-End Analysis的Sonarqube Scanner”。当FxCop和SonarQub