我应该如何在 Java 中暂时在内存中表示一个文件?
How should I represent a File in memory temporarily in Java?
所以我想做的是这样的:假设我有一个 File 对象链接到系统中的物理文件。我想在将内容写回新文件之前对其进行几次修改。我怎样才能做到这一点?所以这是示例代码:
File x = new File("somefile.txt");
// Ask user to enter a String
Scanner s = new Scanner(x);
while(s.hasNextLine())
String nextLine = s.nextLine();
if(userString.equals(nextLine))
nextLine = nextLine.toUpperCase();
此时,我不想修改文件 x 本身。我也不想写物理文件。我只想要相同文件的表示,以相同的顺序,但有些行是大写的,所以我可以再次循环遍历相同的行。
我想要做的是我希望能够再次循环访问相同(但已修改)的文件。
我该怎么做?
使用Files.readAllLines()
将文件作为字符串列表消耗到内存中。
使用 Files.write()
:
将更改写回文件之前,根据需要进行尽可能多的更改
Path path = Paths.get("somefile.txt");
// Ask user to enter a String
List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);
for (ListIterator<String> iterator = lines.listIterator(); iterator.hasNext(); ) {
String line = iterator.next();
if (userString.equals(line)) {
iterator.set(line.toUpperCase());
}
}
Files.write(path, lines, StandardCharsets.UTF_8, StandardOpenOption.TRUNCATE_EXISTING);
如果您需要将此数据作为输入流访问,正如对另一个答案的评论所建议的那样,您可以采纳 Java: accessing a List of Strings as an InputStream 中的建议之一。
您可以在读入时将每一行存储在 ArrayList<String>
中,然后在写出内容之前尽可能多地遍历列表。
import java.io.File;
import java.util.ArrayList;
import java.util.Scanner;
public class Fm {
public static void main(String[] args) throws Exception {
File x = new File("somefile.txt");
ArrayList<String> fileLines = new ArrayList<String>();
String userString = "bar";
Scanner s = new Scanner(x);
while(s.hasNextLine()) {
String nextLine = s.nextLine();
if(userString.equals(nextLine))
nextLine = nextLine.toUpperCase();
fileLines.add(nextLine);
}
for (String line : fileLines) {
System.out.println("Do something with: " + line);
}
}
}
$ cat somefile.txt
foo
bar
baz
$ java Fm
Do something with: foo
Do something with: BAR
Do something with: baz
您可以使用 StringWriter 来存储文件内容并在需要时转换为输入流。
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.Scanner;
public class FileRead {
public static void main(String[] args) throws Exception {
File x = new File("input.txt");
StringWriter sWriter = readToStringWriter(x);
InputStream fis = new ByteArrayInputStream(sWriter.toString()
.getBytes());
String filecontent = convertStreamToString(fis);
System.out.println("File Content:\n" + filecontent);
}
static StringWriter readToStringWriter(File x) throws FileNotFoundException {
StringWriter sWriter = new StringWriter();
Scanner s = new Scanner(x);
while (s.hasNextLine()) {
String nextLine = s.nextLine();
sWriter.write(nextLine);
if (s.hasNextLine())
sWriter.write(System.getProperty("line.separator"));
}
return sWriter;
}
static String convertStreamToString(java.io.InputStream is) {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\A");
return s.hasNext() ? s.next() : "";
}
}
所以我想做的是这样的:假设我有一个 File 对象链接到系统中的物理文件。我想在将内容写回新文件之前对其进行几次修改。我怎样才能做到这一点?所以这是示例代码:
File x = new File("somefile.txt");
// Ask user to enter a String
Scanner s = new Scanner(x);
while(s.hasNextLine())
String nextLine = s.nextLine();
if(userString.equals(nextLine))
nextLine = nextLine.toUpperCase();
此时,我不想修改文件 x 本身。我也不想写物理文件。我只想要相同文件的表示,以相同的顺序,但有些行是大写的,所以我可以再次循环遍历相同的行。
我想要做的是我希望能够再次循环访问相同(但已修改)的文件。
我该怎么做?
使用Files.readAllLines()
将文件作为字符串列表消耗到内存中。
使用 Files.write()
:
Path path = Paths.get("somefile.txt");
// Ask user to enter a String
List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);
for (ListIterator<String> iterator = lines.listIterator(); iterator.hasNext(); ) {
String line = iterator.next();
if (userString.equals(line)) {
iterator.set(line.toUpperCase());
}
}
Files.write(path, lines, StandardCharsets.UTF_8, StandardOpenOption.TRUNCATE_EXISTING);
如果您需要将此数据作为输入流访问,正如对另一个答案的评论所建议的那样,您可以采纳 Java: accessing a List of Strings as an InputStream 中的建议之一。
您可以在读入时将每一行存储在 ArrayList<String>
中,然后在写出内容之前尽可能多地遍历列表。
import java.io.File;
import java.util.ArrayList;
import java.util.Scanner;
public class Fm {
public static void main(String[] args) throws Exception {
File x = new File("somefile.txt");
ArrayList<String> fileLines = new ArrayList<String>();
String userString = "bar";
Scanner s = new Scanner(x);
while(s.hasNextLine()) {
String nextLine = s.nextLine();
if(userString.equals(nextLine))
nextLine = nextLine.toUpperCase();
fileLines.add(nextLine);
}
for (String line : fileLines) {
System.out.println("Do something with: " + line);
}
}
}
$ cat somefile.txt
foo
bar
baz
$ java Fm
Do something with: foo
Do something with: BAR
Do something with: baz
您可以使用 StringWriter 来存储文件内容并在需要时转换为输入流。
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.Scanner;
public class FileRead {
public static void main(String[] args) throws Exception {
File x = new File("input.txt");
StringWriter sWriter = readToStringWriter(x);
InputStream fis = new ByteArrayInputStream(sWriter.toString()
.getBytes());
String filecontent = convertStreamToString(fis);
System.out.println("File Content:\n" + filecontent);
}
static StringWriter readToStringWriter(File x) throws FileNotFoundException {
StringWriter sWriter = new StringWriter();
Scanner s = new Scanner(x);
while (s.hasNextLine()) {
String nextLine = s.nextLine();
sWriter.write(nextLine);
if (s.hasNextLine())
sWriter.write(System.getProperty("line.separator"));
}
return sWriter;
}
static String convertStreamToString(java.io.InputStream is) {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\A");
return s.hasNext() ? s.next() : "";
}
}