【问题标题】:How should I represent a File in memory temporarily in Java?我应该如何在 Java 中临时表示内存中的文件?
【发布时间】:2015-05-12 23:16:02
【问题描述】:

所以我想做的是这样的:假设我有一个 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 本身。我也不想写物理文件。我只想要相同文件的表示,以相同的顺序,但有些行是大写的,所以我可以再次循环遍历相同的行。

我想要做的是能够再次循环通过相同(但已修改)的文件。

我该怎么做?

【问题讨论】:

    标签: java file io


    【解决方案1】:

    您可以使用 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() : "";
        }
    }
    

    【讨论】:

      【解决方案2】:

      使用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 的建议之一。

      【讨论】:

      • 文件是什么包?
      • @KorayTugay 这是java.nio.file 包的一部分。按照我的问题中的链接找到它。从 Java 7 开始可用。
      【解决方案3】:

      您可以在读入每一行时将它们存储在ArrayList&lt;String&gt; 中,然后在写出内容之前尽可能多次地遍历列表。

      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
      

      【讨论】:

      • 但我需要将此文件传递给接受 InputStream 的方法。 (所以我通过 file.getInputStream)
      • @KorayTugay 你是说你需要将修改后的文件内容作为输入流传递,而不是将其写入磁盘?
      • KorayTugay,我的回答是为了保持代码的基本结构,就像你在你的问题中所说的那样,但如果没有必要,我认为@Duncan 提出的方法更方便。
      猜你喜欢
      • 1970-01-01
      • 2011-06-28
      • 1970-01-01
      • 2010-09-22
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      • 2011-05-28
      • 1970-01-01
      相关资源
      最近更新 更多