Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java readChar()方法显示日语字符_Java_Randomaccessfile - Fatal编程技术网

Java readChar()方法显示日语字符

Java readChar()方法显示日语字符,java,randomaccessfile,Java,Randomaccessfile,我试图编写一个代码,根据用户输入的索引从文件中提取一个单词,但问题是RandomAccessFile类中的readChar()方法返回的是日语字符,我必须承认,这不是我第一次在联想笔记本上看到这个,有时在一些安装向导上,我可以看到一些普通字符和日语字符混合的东西,你认为它是来自笔记本电脑还是来自代码 代码如下: package com.project; import java.io.*; import java.util.StringTokenizer; public class Main

我试图编写一个代码,根据用户输入的索引从文件中提取一个单词,但问题是
RandomAccessFile
类中的
readChar()
方法返回的是日语字符,我必须承认,这不是我第一次在联想笔记本上看到这个,有时在一些安装向导上,我可以看到一些普通字符和日语字符混合的东西,你认为它是来自笔记本电脑还是来自代码

代码如下:

package com.project;

import java.io.*;
import java.util.StringTokenizer;

public class Main {

    public static void main(String[] args) throws IOException {
        int N, i=0;
        char C;
        char[] charArray = new char[100];
        String fileLocation = "file.txt";
        BufferedReader buffer = new BufferedReader(new InputStreamReader(System.in));
        do {
            System.out.println("enter the index of the word");
            N = Integer.parseInt(buffer.readLine());
            if (N!=0) {
                RandomAccessFile word = new RandomAccessFile(new File(fileLocation), "r");
                do {
                    word.seek((2*(N-1))+i);
                    C = word.readChar();
                    charArray[i] = C;
                    i++;
                }while(charArray[i-1] != ' ');
                System.out.println("the word of index " + N + " is: " );
                for (char carTemp : charArray )
                System.out.print(carTemp);
                System.out.print("\n");

            }
        }while(N!=0);
        buffer.close();
    }
}
我得到这个输出:

瑯潕啰灰灥敲牃䍡慳獥攨⠩⤍ഊੴ瑯潌䱯潷睥敲牃䍡慳獥攨⠩⤍ഊ੣捯潭浣捡慴琨⡓却瑲物楮湧朩⤍ഊ੣捨桡慲牁䅴琨⡩楮湴琩⤍ഊੳ獵畢扳獴瑲物楮湧木⠠⁳獴瑡慲牴琠⁩楮湤摥數砬Ⱐ⁥敮湤搠⁩楮湤摥數砩⤍ഊੴ瑲物業洨⠩Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 100 out of bounds for length 100
    at Main.main(Main.java:21)

char
是16位,即2字节

seek
查找字节边界

如果文件包含字符,则它们的偏移量为偶数:0、2、4

表达式
(2*(N-1))+i
为偶数,如果
i
为偶数;如果是奇数,你肯定会在一个字符的中间着陆,从而读取垃圾。

i
从零开始,但递增1,即半个字符

您的seek参数可能应该是
(2*(N-1+i))


替代说明:您的文件根本不包含
字符
;例如,您创建了一个ASCII文件,其中字符是单字节

在这种情况下,错误是试图使用
readChar
函数读取ASCII(一种过时的字符编码)


但是,如果文件包含ASCII,那么在seek参数中乘以2的目的就不明确了。它显然没有什么用处。

有很多错误的地方,所有这些都与基本的误解有关

首先:磁盘上的一个文件——不要在意Java或任何其他编程语言中的
文件
接口;文件本身-不存储文本,也不能存储文本。曾经它存储字节。也就是说,原始数据(在每台数十年来一直相关的机器上,但历史上有其他方法)以位量化,这些位被组织成8个字节的组,称为字节

文本是一种抽象;对某些特定字节值序列的解释。它从根本上和不可避免地依赖于编码。因为这不是一个博客,我不想在这里给你上历史课,但我只想说Java的
char
类型只存储了一个文本字符。它存储一个无符号的两字节值,该值可能表示一个文本字符。由于Unicode中的文本字符数超过了两个字节所能表示的数量,因此有时需要数组中两个相邻的
char
s来表示文本字符。(当然,可能有一些代码滥用了
char
类型,仅仅是因为有人想要一个与
short
相当的未签名版本。我甚至可能自己写过一些。那个时代对我来说是一个模糊的时代。)

无论如何,要点是:使用
.readChar()
将从文件中读取两个字节,并将它们存储到
char[]
中的
char
中,相应的数值将与您想要的数值不同-除非您的文件恰好使用Java本机使用的相同编码,打电话来

如果不知道文件编码,您将无法正确阅读和解释文件。句号。你充其量只能欺骗自己相信你能读到它。您也不能
对文本文件进行“随机访问”(即,根据文本的若干字符进行索引),除非所讨论的编码是恒定宽度。(当然,除此之外,您不能仅计算给定文本字符所在文件中的字节距离;这取决于前面的字符占用了多少字节,这取决于它们是哪些字符。)许多文本编码不是恒定宽度,坦率地说,这是目前大多数任务的明智默认建议,但事实并非如此。在这种情况下,你所描述的问题就是运气不佳

无论如何,一旦知道了文件的编码,在Java中从文件中检索文本字符的预期方法是使用一个读卡器类,例如:

InputStreamReader是从字节流到字符流的桥梁:它读取字节并使用指定的字符集将其解码为字符。它使用的字符集可以通过名称指定,也可以显式指定,或者可以接受平台的默认字符集

(这里,
charset
只是指Java用来表示文本编码的类的实例。)


您可以稍微篡改一下问题描述:查找字节偏移量,然后获取从该偏移量开始的文本字符。但是,不能保证“从该偏移量开始的文本字符”有任何意义,或者实际上可以被解码。如果偏移发生在一个字符的多字节编码的中间,剩下的部分不一定是有效的编码文本。

< P>我将文件的编码更改为UTF16,并修改了程序,以便显示正确的索引,表示每个单词的开头,现在它工作正常,谢谢各位。
  import java.io.*;

public class Main {
public static void main(String[] args) throws IOException {
    int N, i=0, j=0, k=0;
    char C;
    char[] charArray = new char[100];
    String fileLocation = "file.txt";
    BufferedReader buffer = new BufferedReader(new InputStreamReader(System.in));
    DataInputStream in = new DataInputStream(new FileInputStream(fileLocation));
    boolean EOF=false;
    do {
        try {
            j++;
            C = in.readChar();
           if((C==' ')||(C=='\n')){
                System.out.print(j+1+"\t");
            }

        }catch (IOException e){
            EOF=true;
        }

    }while (EOF!=true);
    System.out.println("\n");
    do {
        System.out.println("enter the index of the word");
        N = Integer.parseInt(buffer.readLine());
        if (N!=0) {
            RandomAccessFile word = new RandomAccessFile(new File(fileLocation), "r");


            do {

                word.seek((2*(N-1+i)));
                C = word.readChar();
                charArray[i] = C;
                i++;
            }while(charArray[i-1] != ' ' && charArray[i-1] != '\n');
            System.out.print("the word of index " + N + " is: " );
            for (char carTemp : charArray )
                System.out.print(carTemp);
            System.out.print("\n");
             i=0;
            charArray = new char[100];
        }
    }while(N!=0);
    buffer.close();


   }
}

也许这与编码有关?(小错误-您编写了
“/n”
,而不是
“\n”
,或者只是
System.out.println()
)是否可以尝试将它们打印为整数而不是字符?您计算的seek参数是什么?您正在读取的文件中有什么?它是如何编码的?如果是unicode,可能是搜索将您置于字符中间。你对什么
word.seek((2*(N-1))+i)有什么想法是什么?我不认为这会把你带到一个词的边界。而且,你知道什么时候停止阅读的逻辑似乎有缺陷。行
charArray[i++]=C放置下一个