Java IO 异常:负寻道偏移

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30216378/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 16:41:32  来源:igfitidea点击:

Java IO Exception: Negative seek offset

javaseek

提问by Java Enthusiast

I have a program to replace contents in a file. But it results in a IO Exception, I don't know where I am making the logic wrong?

我有一个程序来替换文件中的内容。但它导致了 IO 异常,我不知道我在哪里使逻辑错误?

The code is shown below:

代码如下所示:

import java.io.File;
import java.io.RandomAccessFile;

public class Test
{
   public static void main(String args[]) throws Exception
   {
        File f = new File("test.txt");
        replaceAll(f, "hello world", "my world");
   }

       public static void replaceAll(File file, String oldText, String newText) throws Exception
    {
        int[] indices = findAllIndices(file, oldText);
        if(indices.length > 0)
        {
            for(int i=0;i<indices.length;i++)
            {
                replace(file, oldText, newText);
            }
        }
    }

        public static int[] findAllIndices(File file, String text) throws Exception
    {
        int[] indices;
        int index = -1, count = 0, i=0;
        String givenText = FileUtils.readFileToString(file);
        index = givenText.indexOf(text);
        while(index >= 0)
        {
            count++;
            index = givenText.indexOf(text, index+1);
        }
        indices = new int[count];
        index = givenText.indexOf(text);
        while(index >= 0)
        {
            indices[i] = index;
            index = givenText.indexOf(text, index+1);
            i++;
        }
        return indices;
    }

        public static void replace(File file, String oldText, String newText) throws Exception
    {        
        int index = findFirstIndex(file, oldText);
        if(index >=0)
        {
            RandomAccessFile raf = new RandomAccessFile(file, "rw");
            raf.seek(new Integer(index).byteValue());
            String emptyString = fixedLengthString(" ", oldText.length());
            raf.write(emptyString.getBytes());
            raf.seek(new Integer(index).byteValue());            
            raf.write(newText.getBytes());
        }
    }    
}

The MWE is a part of a big code. The stack trace from the original code is:

MWE 是大代码的一部分。原始代码的堆栈跟踪是:

Exception in thread "main" java.io.IOException: Negative seek offset
    at java.io.RandomAccessFile.seek(RandomAccessFile.java:538)
    at org.javaextensions.FindAndReplace.replace(FindAndReplace.java:51)
    at org.javaextensions.FindAndReplace.replaceAll(FindAndReplace.java:76)
    at Test.main(Test.java:16)
Java Result: 1

回答by ControlAltDel

    public static void replace(File file, String oldText, String newText) throws Exception
{        
    int index = findFirstIndex(file, oldText);
    if(index >=0)
    {
        RandomAccessFile raf = new RandomAccessFile(file, "rw");
        raf.seek(new Integer(index).byteValue());

Your problem is either here ^^

你的问题要么在这里^^

        String emptyString = fixedLengthString(" ", oldText.length());
        raf.write(emptyString.getBytes());
        raf.seek(new Integer(index).byteValue());

You should check the value of Integer(index.byteValue()) it is likely returning a negative number. Also, I don't know why you want to cast this to a byte, nor why you're creating an Integer object first. Neither should be necessary

您应该检查 Integer(index.byteValue()) 的值,它可能返回负数。另外,我不知道为什么要将其转换为字节,也不知道为什么要先创建 Integer 对象。两者都不是必要的

回答by Rajesh

I'm not sure why you are reinventing index value again. See below, your code contains array of those indexes:

我不确定您为什么要再次重新发明索引值。见下文,您的代码包含这些索引的数组:

int[] indices = findAllIndices(file, oldText);

You could pass the same while calling replace method as additional argument.

您可以在调用 replace 方法作为附加参数时传递相同的内容。

Code changes to implement:

要实现的代码更改:

public static void replaceAll(File file, String oldText, String newText) throws Exception
{
    int[] indices = findAllIndices(file, oldText);

    for(int i=0;i<indices.length;i++)
        replace(file, oldText, newText, indices[i]);
}

public static void replace(File file, String oldText, String newText, int index) throws Exception
{
    RandomAccessFile raf = new RandomAccessFile(file, "rw");
    ..
    ..
}

回答by Stephen C

The problem is in the way that you generate the offset for your seek:

问题在于您为搜索生成偏移量的方式:

    if(index >=0) {
        ...
        raf.seek(new Integer(index).byteValue());
    }

You start with an index that is non-negative (fine) ...

你从一个非负(很好)的索引开始......

But then you convert the index to a byte.

但是随后您将索引转换为byte.

The problem is that Java bytes are in the range -128 to +127. So what is most likely happening is that your positive integer gets converted into a negative byte value ... and then back to a negative integer. For example the int130 maps to the byte-126 and then back to the int-126

问题是 Java 字节在 -128 到 +127 的范围内。所以最有可能发生的是你的正整数被转换成一个负字节值……然后又回到一个负整数。例如int130 映射到byte-126 然后返回到int-126

I don't understand the reason why you are converting the index to a byte at all, but if you are trying to "reduce" the index value to a number in the range 0 to 255, then you should do this:

我根本不明白您将索引转换为字节的原因,但是如果您试图将索引值“减少”为 0 到 255 范围内的数字,那么您应该这样做:

        raf.seek(index & 0xff);

回答by Mark Leiber

Even though you are checking that index >= 0, you are not accounting for the case of index > 127:

即使您正在检查索引 >= 0,您也没有考虑索引 > 127 的情况:

    if(index >=0)
    {
        ...
        raf.seek(new Integer(index).byteValue());
        ...
    }

The range of a byte is -128 to 127. If you take any int between 128 and 256 and try to get byteValue() you won't get a number greater than zero.
Try it:

一个字节的范围是 -128 到 127。如果您采用 128 到 256 之间的任何 int 并尝试获取 byteValue(),您将不会得到大于零的数字。
试试看:

    int i = 127;
    byte b = new Integer(i).byteValue();
    System.out.println("Value of b = " + b);

This results in b = 127. Try it with i = 128 and you get b = -128.

这导致 b = 127。用 i = 128 试试,你会得到 b = -128。

  • 1 - 127 are greater than zero.
  • 128 - 256 are less than or equal to zero.
  • 257 - 383 are greater than zero. ... and so on.
  • 1 - 127 大于零。
  • 128 - 256 小于或等于 0。
  • 257 - 383 大于零。... 等等。