Java IO异常:负搜索偏移

时间:2015-05-13 13:30:17

标签: java seek

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

代码如下所示:

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());
        }
    }    
}

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

4 个答案:

答案 0 :(得分:1)

    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());

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

答案 1 :(得分:0)

我不确定你为什么要再次重塑指数值。请参阅下文,您的代码包含这些索引的数组:

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

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

要实施的代码更改:

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");
    ..
    ..
}

答案 2 :(得分:0)

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

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

你从一个非负的索引开始(精细)......

但是你将索引转换为byte

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

我根本不理解您将索引转换为字节的原因,但是如果您正在尝试&#34;减少&#34;索引值为0到255之间的数字,那么你应该这样做:

        raf.seek(index & 0xff);

答案 3 :(得分:0)

即使您正在检查索引&gt; = 0,您也不会考虑索引&gt;的情况。 127:

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

一个字节的范围是-128到127.如果你取128到256之间的任何int并尝试得到byteValue()你就不会得到一个大于零的数字。
试试吧:

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

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

  • 1 - 127大于零。
  • 128 - 256小于或等于零。
  • 257 - 383大于零。 ......等等。