我有一个程序来替换文件中的内容。但它导致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
答案 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。