リソース内のテキストファイルを文字列に読み込むのに役立つユーティリティはありますか?これは一般的な要件だと思いますが、グーグルした後はユーティリティが見つかりませんでした。
回答:
getResource
はを使用してResource.class.getClassLoader
いますが、Webアプリケーションでは、これは「あなたの」クラスローダーではない可能性があるため、([1]などで)使用することをお勧めしますThread.currentThread().getContextClassLoader().getResourceAsStream
代わりに(参照[1]:stackoverflow.com/questions/676250/…)
Resources.toString(MyClass.getResource("foo.txt"), Charsets.UTF_8)
は、正しいクラスローダーの使用を保証することができます。
com.google.common.io.Resources
SonarQube
guava
実装が変更されました。guava 23の場合、実装は次のようになります。ClassLoader loader = MoreObjects.firstNonNull( Thread.currentThread().getContextClassLoader(), Resources.class.getClassLoader());
古いStupidScannerトリックonelinerを使用して、guavaのような追加の依存関係なしでそれを行うことができます。
String text = new Scanner(AppropriateClass.class.getResourceAsStream("foo.txt"), "UTF-8").useDelimiter("\\A").next();
みんな、本当に必要な場合を除いて、サードパーティのものを使用しないでください。JDKにはすでに多くの機能があります。
CartApplication.class.getResourceAsStream
しCartApplication.class.getClassLoader().getResourceAsStream
て、現在のjarにリソースをロードします。srm/ test / resourcesなど
Java 7の場合:
new String(Files.readAllBytes(Paths.get(getClass().getResource("foo.txt").toURI())));
getClass().getClassLoader()
が、そうでなければ素晴らしい解決策です!
以下のこの簡単な方法は、Java8以降を使用している場合に問題なく機能します。
/**
* Reads given resource file as a string.
*
* @param fileName path to the resource file
* @return the file's contents
* @throws IOException if read fails for any reason
*/
static String getResourceFileAsString(String fileName) throws IOException {
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
try (InputStream is = classLoader.getResourceAsStream(fileName)) {
if (is == null) return null;
try (InputStreamReader isr = new InputStreamReader(is);
BufferedReader reader = new BufferedReader(isr)) {
return reader.lines().collect(Collectors.joining(System.lineSeparator()));
}
}
}
また、jarファイル内のリソースでも機能します。
テキストエンコーディングについて:InputStreamReader
指定しない場合は、デフォルトのシステム文字セットを使用します。次のようなデコードの問題を回避するために、自分で指定することをお勧めします。
new InputStreamReader(isr, StandardCharsets.UTF_8);
大きくて太いライブラリに依存しないことを常に好みます。すでにGuavaまたはApacheCommons IOを他のタスクに使用している場合を除いて、ファイルから読み取るためだけにこれらのライブラリをプロジェクトに追加するのは少し多すぎるようです。
このような単純なタスクを実行する場合、純粋なJavaはうまく機能しないことを理解しています。たとえば、Node.jsのファイルから読み取る方法は次のとおりです。
const fs = require("fs");
const contents = fs.readFileSync("some-file.txt", "utf-8");
シンプルで読みやすい(ただし、ほとんどの場合、無知のために、とにかく多くの依存関係に依存することを好む人がいます)。またはPythonの場合:
with open('some-file.txt', 'r') as f:
content = f.read()
悲しいことですが、Javaの標準ではそれでも簡単であり、上記のメソッドをプロジェクトにコピーして使用するだけです。私はあなたにそこで何が起こっているのかを理解するようにさえ求めません。なぜならそれは本当に誰にとっても重要ではないからです。それはうまくいきます、期間:-)
InputStream
変数is
がそうであるnull
かどうかのチェックを追加するだけです。
Guavaには、ファイルを文字列に読み込むための「toString」メソッドがあります。
import com.google.common.base.Charsets;
import com.google.common.io.Files;
String content = Files.toString(new File("/home/x1/text.log"), Charsets.UTF_8);
このメソッドでは、ファイルがクラスパスにある必要はありません(Jon Skeetの前の回答のように)。
String stringFromStream = CharStreams.toString(new InputStreamReader(resourceAsStream, "UTF-8"));
yegor256は、Apache CommonsIOを使用した優れたソリューションを見つけました。
import org.apache.commons.io.IOUtils;
String text = IOUtils.toString(this.getClass().getResourceAsStream("foo.xml"),
"UTF-8");
IOUtils.toString(this.getClass().getResource("foo.xml"), "UTF-8")
。
getClassLoader()
メソッドチェーンに: String text = IOUtils.toString( getClass().getClassLoader().getResourceAsStream("foo.xml"), StandardCharsets.UTF_8);
IOUtils.resourceToString("/foo.xml", StandardCharsets.UTF_8);
apache-commons-ioにはユーティリティ名がありますFileUtils
:
URL url = Resources.getResource("myFile.txt");
File myFile = new File(url.toURI());
String content = FileUtils.readFileToString(myFile, "UTF-8"); // or any other encoding
Javaから次のコードを使用できます
new String(Files.readAllBytes(Paths.get(getClass().getResource("example.txt").toURI())));
私はしばしばこの問題を自分で抱えていました。小さなプロジェクトへの依存を避けるために、commonsioなどが必要ないときに小さなユーティリティ関数を書くことがよくあります。ファイルの内容を文字列バッファにロードするコードは次のとおりです。
StringBuffer sb = new StringBuffer();
BufferedReader br = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("path/to/textfile.txt"), "UTF-8"));
for (int c = br.read(); c != -1; c = br.read()) sb.append((char)c);
System.out.println(sb.toString());
その場合、エンコードを指定することが重要です。ファイルをUTF-8で編集してから、jarファイルに入れ、ファイルを開くコンピューターのネイティブファイルエンコードがCP-1251である可能性があるためです(たとえば)。 ; したがって、この場合、ターゲットエンコーディングがわからないため、明示的なエンコーディング情報が重要です。また、charごとにファイルを読み取るループは非効率に見えますが、BufferedReaderで使用されるため、実際には非常に高速です。
ApachecommonsのFileUtilsを使用します。readFileToStringメソッドがあります
私は以下からリソースファイルを読み取るために以下を使用していますclasspath
:
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.util.Scanner;
public class ResourceUtilities
{
public static String resourceToString(String filePath) throws IOException, URISyntaxException
{
try (InputStream inputStream = ResourceUtilities.class.getClassLoader().getResourceAsStream(filePath))
{
return inputStreamToString(inputStream);
}
}
private static String inputStreamToString(InputStream inputStream)
{
try (Scanner scanner = new Scanner(inputStream).useDelimiter("\\A"))
{
return scanner.hasNext() ? scanner.next() : "";
}
}
}
サードパーティの依存関係は必要ありません。
静的インポートのセットを使用すると、Guavaソリューションは非常にコンパクトなワンライナーになります。
toString(getResource("foo.txt"), UTF_8);
次のインポートが必要です。
import static com.google.common.io.Resources.getResource
import static com.google.common.io.Resources.toString
import static java.nio.charset.StandardCharsets.UTF_8
package test;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
try {
String fileContent = getFileFromResources("resourcesFile.txt");
System.out.println(fileContent);
} catch (Exception e) {
e.printStackTrace();
}
}
//USE THIS FUNCTION TO READ CONTENT OF A FILE, IT MUST EXIST IN "RESOURCES" FOLDER
public static String getFileFromResources(String fileName) throws Exception {
ClassLoader classLoader = Main.class.getClassLoader();
InputStream stream = classLoader.getResourceAsStream(fileName);
String text = null;
try (Scanner scanner = new Scanner(stream, StandardCharsets.UTF_8.name())) {
text = scanner.useDelimiter("\\A").next();
}
return text;
}
}
少なくともApachecommons-io 2.5の時点では、IOUtils.toString()メソッドはURI引数をサポートし、クラスパスのjar内にあるファイルの内容を返します。
IOUtils.toString(SomeClass.class.getResource(...).toURI(), ...)
Charsets
もグアバにあります。これを参照してください:google.github.io/guava/releases/23.0/api/docs
これが私のアプローチがうまくいった
public String getFileContent(String fileName) {
String filePath = "myFolder/" + fileName+ ".json";
try(InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream(filePath)) {
return IOUtils.toString(stream, "UTF-8");
} catch (IOException e) {
// Please print your Exception
}
}
ここにreadResource()メソッドを記述して、1回の簡単な呼び出しで実行できるようにしました。Guavaライブラリに依存しますが、他の回答で提案されているJDKのみの方法が好きで、そのように変更すると思います。
Java11を使用したソリューションは次のFiles.readString
とおりです。
public class Utils {
public static String readResource(String name) throws URISyntaxException, IOException {
var uri = Utils.class.getResource("/" + name).toURI();
var path = Paths.get(uri);
return Files.readString(path);
}
}
私はこのようなNO依存性の静的メソッドを作成しました:
import java.nio.file.Files;
import java.nio.file.Paths;
public class ResourceReader {
public static String asString(String resourceFIleName) {
try {
return new String(Files.readAllBytes(Paths.get(new CheatClassLoaderDummyClass().getClass().getClassLoader().getResource(resourceFIleName).toURI())));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
class CheatClassLoaderDummyClass{//cheat class loader - for sql file loading
}
私はこのタイプのものにApachecommons utilsが好きで、テスト時に、特に/src/test/resources
ユニット/統合テストの一部としてJSONファイルを読み取るために、この正確なユースケース(クラスパスからファイルを読み取る)を広く使用します。例えば
public class FileUtils {
public static String getResource(String classpathLocation) {
try {
String message = IOUtils.toString(FileUtils.class.getResourceAsStream(classpathLocation),
Charset.defaultCharset());
return message;
}
catch (IOException e) {
throw new RuntimeException("Could not read file [ " + classpathLocation + " ] from classpath", e);
}
}
}
テストの目的で、をキャッチしIOException
てスローするのは良いことですRuntimeException
-テストクラスは次のようになります。
@Test
public void shouldDoSomething () {
String json = FileUtils.getResource("/json/input.json");
// Use json as part of test ...
}
public static byte[] readResoureStream(String resourcePath) throws IOException {
ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
InputStream in = CreateBffFile.class.getResourceAsStream(resourcePath);
//Create buffer
byte[] buffer = new byte[4096];
for (;;) {
int nread = in.read(buffer);
if (nread <= 0) {
break;
}
byteArray.write(buffer, 0, nread);
}
return byteArray.toByteArray();
}
Charset charset = StandardCharsets.UTF_8;
String content = new String(FileReader.readResoureStream("/resource/...*.txt"), charset);
String lines[] = content.split("\\n");