Existe algum utilitário que ajude a ler um arquivo de texto no recurso em uma String. Suponho que esse seja um requisito popular, mas não consegui encontrar nenhum utilitário após pesquisar no Google.
Existe algum utilitário que ajude a ler um arquivo de texto no recurso em uma String. Suponho que esse seja um requisito popular, mas não consegui encontrar nenhum utilitário após pesquisar no Google.
Respostas:
Sim, o Guava fornece isso na Resources
classe. Por exemplo:
URL url = Resources.getResource("foo.txt");
String text = Resources.toString(url, StandardCharsets.UTF_8);
getResource
está sendo usada, Resource.class.getClassLoader
mas em aplicativos da web, esse pode não ser o "seu" carregador de classes, por isso é recomendável (por exemplo, em [1]) usar Thread.currentThread().getContextClassLoader().getResourceAsStream
em vez disso (referência [1]: stackoverflow.com/questions/676250/… )
Resources.toString(MyClass.getResource("foo.txt"), Charsets.UTF_8)
que garante o uso do carregador de classes correto.
com.google.common.io.Resources
está marcado como instável de acordo com o SonarQube
guava
mudou a implementação. Para a goiaba 23, a implementação gosta de seguir. ClassLoader loader = MoreObjects.firstNonNull( Thread.currentThread().getContextClassLoader(), Resources.class.getClassLoader());
Você pode usar o antigo truque do Stupid Scanner oneliner para fazer isso sem nenhuma dependência adicional como a goiaba:
String text = new Scanner(AppropriateClass.class.getResourceAsStream("foo.txt"), "UTF-8").useDelimiter("\\A").next();
Pessoal, não use coisas de terceiros, a menos que você realmente precise disso. Já existe muita funcionalidade no JDK.
CartApplication.class.getResourceAsStream
para CartApplication.class.getClassLoader().getResourceAsStream
carregar recursos nos atuais jar..like srm / teste / recursos
Para java 7:
new String(Files.readAllBytes(Paths.get(getClass().getResource("foo.txt").toURI())));
getClass().getClassLoader()
outra solução ótima!
Este método simples abaixo funcionará bem se você estiver usando o Java 8 ou superior:
/**
* 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()));
}
}
}
E também funciona com recursos em arquivos jar .
Sobre a codificação de texto: InputStreamReader
usará o conjunto de caracteres padrão do sistema caso você não especifique um. Você pode especificá-lo para evitar problemas de decodificação, como este:
new InputStreamReader(isr, StandardCharsets.UTF_8);
Sempre prefira não depender de grandes bibliotecas gordas. A menos que você já esteja usando o Guava ou o Apache Commons IO para outras tarefas, adicionar essas bibliotecas ao seu projeto apenas para poder ler de um arquivo parece um pouco demais.
Eu entendo que o Java puro não faz um bom trabalho quando se trata de executar tarefas simples como essa. Por exemplo, é assim que lemos de um arquivo no Node.js:
const fs = require("fs");
const contents = fs.readFileSync("some-file.txt", "utf-8");
Simples e fácil de ler (embora as pessoas ainda gostem de contar com muitas dependências, principalmente devido à ignorância). Ou em Python:
with open('some-file.txt', 'r') as f:
content = f.read()
É triste, mas ainda é simples para os padrões do Java e tudo o que você precisa fazer é copiar o método acima para o seu projeto e usá-lo. Eu nem peço que você entenda o que está acontecendo lá, porque realmente não importa para ninguém. Apenas funciona, ponto final :-)
InputStream
variável is
é null
ou não.
A Goiaba possui um método "toString" para ler um arquivo em uma String:
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);
Este método não requer que o arquivo esteja no caminho de classe (como na resposta anterior de Jon Skeet ).
String stringFromStream = CharStreams.toString(new InputStreamReader(resourceAsStream, "UTF-8"));
O yegor256 encontrou uma boa solução usando o Apache Commons IO :
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()
à cadeia de métodos: String text = IOUtils.toString( getClass().getClassLoader().getResourceAsStream("foo.xml"), StandardCharsets.UTF_8);
apache-commons-io tem um nome de utilitário FileUtils
:
URL url = Resources.getResource("myFile.txt");
File myFile = new File(url.toURI());
String content = FileUtils.readFileToString(myFile, "UTF-8"); // or any other encoding
Muitas vezes eu também tive esse problema. Para evitar dependências em projetos pequenos, costumo escrever uma função de utilitário pequeno quando não preciso de bens comuns io ou algo assim. Aqui está o código para carregar o conteúdo do arquivo em um buffer de cadeia:
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());
A especificação da codificação é importante nesse caso, porque você pode ter editado seu arquivo em UTF-8 e, em seguida, colocado em um jar, e o computador que abre o arquivo pode ter o CP-1251 como codificação de arquivo nativo (por exemplo) ; portanto, nesse caso, você nunca conhece a codificação de destino; portanto, as informações de codificação explícitas são cruciais. Além disso, o loop para ler o arquivo char por char parece ineficiente, mas é usado em um BufferedReader e, portanto, bastante rápido.
Você pode usar o seguinte código Java
new String(Files.readAllBytes(Paths.get(getClass().getResource("example.txt").toURI())));
Se você deseja obter sua String de um recurso do projeto, como o arquivo testcase / foo.json em src / main / resources em seu projeto, faça o seguinte:
String myString=
new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("testcase/foo.json").toURI())));
Observe que o método getClassLoader () está ausente em alguns dos outros exemplos.
Use o FileUtils do Apache commons. Possui um método readFileToString
Estou usando o seguinte para ler arquivos de recursos em 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() : "";
}
}
}
Não são necessárias dependências de terceiros.
Com o conjunto de importações estáticas, a solução Guava pode ser uma linha muito compacta:
toString(getResource("foo.txt"), UTF_8);
As seguintes importações são necessárias:
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;
}
}
Pelo menos a partir do Apache commons-io 2.5, o método IOUtils.toString () suporta um argumento URI e retorna o conteúdo dos arquivos localizados dentro dos jars no caminho de classe:
IOUtils.toString(SomeClass.class.getResource(...).toURI(), ...)
Gosto da resposta de akosicki com o Stupid Scanner Trick. É o mais simples que vejo, sem dependências externas, que funciona no Java 8 (e, de fato, até o Java 5). Aqui está uma resposta ainda mais simples se você pode usar o Java 9 ou superior (já que InputStream.readAllBytes()
foi adicionado no Java 9):
String text = new String(AppropriateClass.class.getResourceAsStream("foo.txt").readAllBytes());
A goiaba também possui Files.readLines()
se você deseja um valor de retorno como List<String>
linha por linha:
List<String> lines = Files.readLines(new File("/file/path/input.txt"), Charsets.UTF_8);
Consulte aqui para comparar três maneiras ( BufferedReader
vs. Guava Files
vs. Guava Resources
) de obter String
um arquivo de texto.
Charsets
também está na Goiaba. Veja isto: google.github.io/guava/releases/23.0/api/docs
Aqui está a minha abordagem funcionou bem
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
}
}
Eu escrevi métodos readResource () aqui , para poder fazer isso em uma chamada simples. Depende da biblioteca do Guava, mas eu gosto dos métodos somente JDK sugeridos em outras respostas e acho que vou mudar dessa maneira.
Aqui está uma solução usando Java 11 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);
}
}
Eu criei o método estático de dependência NO, como este:
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
}
Eu gosto dos utilitários comuns do Apache para esse tipo de material e uso esse caso de uso exato (lendo arquivos do caminho de classe) extensivamente ao testar, especialmente para ler arquivos JSON /src/test/resources
como parte do teste de unidade / integração. por exemplo
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);
}
}
}
Para fins de teste, pode ser bom pegar IOException
e lançar uma RuntimeException
- sua classe de teste pode parecer, por exemplo,
@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");