1. ホーム
  2. Java

Javaがテキストファイルを読み込む

2022-02-12 16:01:34
<パス

記事目次


Javaを使ってテキストファイル(txt)から文字を読みたいと思いましたが、Javaのファイル操作にあまり慣れていなかったので、公式ドキュメントを調べ始め、ファイルから1行または全部のデータを読み取る方法を解決しました。

ファイル

File ディレクトリやファイルを表す
File このクラスのインスタンスは不変です。 File オブジェクトは決して変更されません。ここでは File クラスはいくつかのメソッドを持っています。

public File(String pathname)
public File(String parent, String child)
public File(File parent, String child)
public File(URI uri)

public String getName() 
public String getParent()
public String getPath()
public URL toURL()
public boolean canRead()
public boolean canWrite()
public boolean exists()
public boolean isDirectory()
public boolean isFile()
public boolean isHidden()
public long lastModified()
public long length()
public boolean createNewFile()
public boolean delete()
public void deleteOnExit()
....

File

FileReader クラス自体は入出力のためのメソッドを提供せず、単にコンピュータ上のファイルやディレクトリを表します。

ファイルリーダー

InputStreamReader を継承しています。 public FileReader(String fileName) public FileReader(File file) public FileReader(FileDescriptor fd) クラスファイルでは、3つの新しいコンストラクタ・メソッドだけが表示されます。

InputStreamReader
ドキュメントによると、FileReaderは文字ファイルを読むためのもので、文字のストリームとして読み出すとありますが、まだ入力メソッドが見当たらないので、欲しいメソッドがあるかどうか、その親を見てみましょう。

InputStreamReader

Reader 抽象クラスから継承する // All constructor parameters are InputStream public InputStreamReader(InputStream in) public InputStreamReader(InputStream in, String charsetName) // Create the object with the specified character set public InputStreamReader(InputStream in, Charset cs) public InputStreamReader(InputStream in, CharsetDecoder dec) public String getEncoding() // Get the character set public int read() //Reading the character set encoding of a single character, if the stream is read out, return -1 public int read(char cbuf[], int offset, int length) //Read part of the characters to the character array cbuf public boolean ready() // if the stream's input buffer is not empty, return true public void close() 以下はInputstreamReaderのすべてのパブリックメソッドです。

  public class Main {
    public static void main(String[] args) throws IOException {

        String fileName = "C:\\Users\\\\lin\\Desktop\\\\English.txt";
        FileReader fileReader = new FileReader(fileName);

        char[] chars = new char[10];

        fileReader.read(chars,0,9);//try reading ten characters first

        for(char ch:chars){
            System.out.print(ch);
        }
    }
}


ようやくread()メソッドを見て、テキストファイルから文字を読み取る方法がわかりました。

FileReader

ファイルの内容

実行結果です。

中国の混乱、とりあえず無視。
にかかわらず、その InputStreamReader または public int read() どちらも、データを読み出すための2つの方法しか持っていません。
public int read(char[] cbuf,int offset,int length)

BufferedReader
明らかにこの単純な方法は私のニーズを満たしていませんでした。
BufferedReader in = new BufferedReader(new FileReader("foo.in"));

BufferedReader (解決策はこちら)

BufferedReader (jdk1.8) のドキュメントと、English Scum の無責任な翻訳を紹介します。

文字入力ストリームからテキストを読み込み、文字、配列、行の効率的な読み込みを提供するように文字をバッファリングします。
文字入力ストリームからテキストを読み込み、文字、配列、行を効率的に読み込めるように文字をバッファリングします。
バッファーのサイズは、指定することもできるし、デフォルトのサイズを使用することもできる。デフォルトは、ほとんどの用途で十分な大きさです。
バッファーのサイズを指定することもできますし、デフォルトのサイズを使用することもできます。
一般に、Readerに対して行われる各読み取り要求は、その下にある文字またはバイトストリームに対して、対応する読み取り要求を行うことになる。
一般に、リーダが行う各読み出し要求は、その下にある文字またはバイトストリームに対応する読み出し要求を行うことになる。
したがって、FileReader や InputStreamReader のような read() 操作が高価になりそうな Reader は、BufferedReader で囲むことが推奨される。例えば
したがって、次のような read() 操作が高価になる可能性がある Reader の read() メソッドには BufferedReader をラップすることが推奨されます。

BufferedReader
は、指定されたファイルからの入力をバッファリングします。
は、指定されたファイルからの入力ストリームをバッファリングします。
バッファリングを行わないと、read() や readLine() を起動するたびに、ファイルからバイトを読み込んで文字に変換し、それを返すことになり、非常に非効率的です。
キャッシュを使用しない場合、read() または readLine() メソッドを呼び出すたびに、ファイルからバイトを読み取り、バイトを文字に変換して返しますが、これは非効率的です。
テキスト入力にDataInputStreamを使用するプログラムは、各DataInputStreamを適切なBufferedReaderに置き換えることで、ローカライズすることができます。

以下は public BufferedReader(Reader in, int sz) public BufferedReader(Reader in) public int read() public int read(char cbuf[], int off, int len) public String readLine() public long skip(long n) public boolean ready() public boolean markSupported() public void mark(int readAheadLimit) public void reset() public void close() public Stream<String> lines() のパブリックメソッド一式は

FileReader

ドキュメントでは read は、その BufferedReader メソッドは非効率的であり、また解決策もあります。 FileReader を包む public class Main { public static void main(String[] args) throws IOException { String fileName = "C:\\Users\\\\lin\\Desktop\\\\English.txt"; FileReader fileReader = new FileReader(fileName); BufferedReader bufferedReader = new BufferedReader(fileReader); System.out.println(bufferedReader.readLine()); bufferedReader.close(); fileReader.close(); } } そこで、私は自分のコードを次のように修正した。

public class Main {
    public static void main(String[] args) throws IOException {

        String fileName = "C:\\Users\\\\lin\\Desktop\\\\English.txt";
        FileReader fileReader = new FileReader(fileName);

        BufferedReader bufferedReader = new BufferedReader(fileReader);

        String line = bufferedReader.readLine();

        while (line!=null){
            System.out.println(line);
            line = bufferedReader.readLine();
        }

        bufferedReader.close();
        fileReader.close();

    }
}


実行結果。

テキストファイルのすべてのデータを読み込む場合は、次のようにすると、より良い感じです。

InputStreamReader

実行結果。




妥協する ����Э

小説 �����С˵




シンクロナイズド
非同期型 ��첽
従業員

表示 ʾָʾ
デノート ָʾ
部分
オフセット

中国語の文字化けを解消する

ドキュメントに目を通すと public String getEncoding() があり、その中に InputStreamReader(InputStream, String) メソッドがあり、jdk1.8 では以下のように記述されています。

このストリームで使用されている文字エンコーディングの名前を返します。
このストリームで使用されている文字エンコーディングの名前を返します。
もしそのエンコーディングに歴史的な名前があればその名前が返され、 そうでなければそのエンコーディングの正式な (権威ある、司祭的な) 名前が返されます。
エンコーディングに歴史的な名前がある場合はその名前が返され、そうでない場合はエンコーディングの正式名称が返されます。つまり、ストリームの文字エンコーディング名を返します。
このインスタンスが InputStreamReader(InputStream, String) コンストラクタで作成された場合、返される名前はエンコーディングによって一意であり、コンストラクタに渡された名前とは異なる可能性があります。このメソッドは、ストリームが閉じられている場合、null を返します。
インスタンスが public class Main { public static void main(String[] args) throws IOException { String fileName = "C:\\Users\\\\lin\\Desktop\\\\English.txt"; FileReader fileReader = new FileReader(fileName); BufferedReader bufferedReader = new BufferedReader(fileReader); System.out.println("Character set: "+fileReader.getEncoding()); String line =bufferedReader.readLine(); while (line!=null){ System.out.println(line); line = bufferedReader.readLine(); } bufferedReader.close(); fileReader.close(); } } のコンストラクタに渡された場合、返される一意なエンコーディング名は渡されたフォームパラメータと異なる可能性があります。ストリームが閉じられている場合、null が返されます。

このメソッドは、ファイルのエンコーディングではなく、ファイルストリームの文字エンコーディングを返すことに注意してください。
次に、このメソッドを使用すると、コンソール出力はUTF8であることがわかりました。

FileInputStream

Win10メモ帳のデフォルトの文字コードがASCIであることを思い出し、English.txtをUTF8に変更したら、コンソールにちゃんと中国語が表示されるようになった。

ファイルインプットストリーム

前回紹介したのは、文字ストリームを出力するためのJava APIです。
FileInputStream は、ファイルをバイトのストリームとして読み込むバイト出力ストリームです
InputStream 抽象クラスから継承する

FileInputStream

FileInputStreamは、ファイルシステム内のファイルから入力バイトを取得します。どのようなファイルが利用できるかは、ホスト環境に依存します。
FileInputStream ファイルシステム上のファイルから入力バイナリバイトを取得する。ファイルが利用可能かどうかは、ローカルコンピュータに依存する。
FileInputStreamは、画像データのような生のバイトのストリームを読み取るためのものです。文字のストリームを読むには、FileReaderの使用を検討してください。
FileReader は、画像などのネイティブ・バイナリ・バイトを読み込むために設計されています。文字ストリームを読み込むには

FileReader


読み込みは書き込みに対応し、それぞれのInputStreamやReaderはOutputStreamやWriterに対応しますが、これは前者とほとんど同じなので、改めて説明しません。
また、JavaのI/Oが設計されているのは 複雑そう は、元のコードを壊さずに機能を拡張するために、継承よりも優れた柔軟性を提供することを目的とした ***decoration pattern*** の使用によるもので、つまりは 修正にはクローズド、拡張にはオープン