【问题标题】:Store java arrays to file for read and write将 java 数组存储到文件以供读写
【发布时间】:2015-04-18 16:59:00
【问题描述】:

我是 StackOverflow 的新手,所以如果这个问题写得不正确,我很抱歉。

我目前正在学习 java,并且正在寻找一种将一组数组存储为文件的方法,以便对数组的更改将在程序的不同实例之间持续存在。我需要读取并将最佳时间列表的任何更改写入文件。

我对存储数组进行了一些研究,但我读过的大部分内容似乎只存储了一个简单的字符串、整数等数组。这些数组有点复杂,所以我不知道该怎么做。 我不希望任何人为我编写所有代码,但我可以使用一些帮助来了解从哪里开始。

这是需要存储的示例数据。这是 Java 游戏的最佳时机。

有没有办法将这类数据存储在某种文件中?

public class BestTimes 
    {
        BestTimes[] beginner = new BestTimes[10];
        BestTimes[] intermediate = new BestTimes[10];
        BestTimes[] expert = new BestTimes[10];

        public BestTimes() {
        beginner[0] = new BestTimes(1, "John", 10.5);
        beginner[1] = new BestTimes(2, "James", 20.3);
        beginner[2] = new BestTimes(3, "Jill", 30);
        beginner[3] = new BestTimes(4, "Bill", 35);
        beginner[4] = new BestTimes(5, "Kevin", 40);
        beginner[5] = new BestTimes(6, "Nate", 55);
        beginner[6] = new BestTimes(7, "Bob", 75);
        beginner[7] = new BestTimes(8, "Dan", 85);
        beginner[8] = new BestTimes(9, "Amy", 93);
        beginner[9] = new BestTimes(10, "Jane", 100);

        intermediate[0] = new BestTimes(1, "John", 110.5);
        intermediate[1] = new BestTimes(2, "James", 120.3);
        intermediate[2] = new BestTimes(3, "Jill", 130);
        intermediate[3] = new BestTimes(4, "Bill", 135);
        intermediate[4] = new BestTimes(5, "Kevin", 140);
        intermediate[5] = new BestTimes(6, "Nate", 155);
        intermediate[6] = new BestTimes(7, "Bob", 175);
        intermediate[7] = new BestTimes(8, "Dan", 185);
        intermediate[8] = new BestTimes(9, "Amy", 193);
        intermediate[9] = new BestTimes(10, "Jane", 200);

        expert[0] = new BestTimes(1, "John", 210.5);
        expert[1] = new BestTimes(2, "James", 220.3);
        expert[2] = new BestTimes(3, "Jill", 230);
        expert[3] = new BestTimes(4, "Bill", 235);
        expert[4] = new BestTimes(5, "Kevin", 240);
        expert[5] = new BestTimes(6, "Nate", 255);
        expert[6] = new BestTimes(7, "Bob", 275);
        expert[7] = new BestTimes(8, "Dan", 285);
        expert[8] = new BestTimes(9, "Amy", 293);
        expert[9] = new BestTimes(10, "Jane", 300);
        }

    public int ranking;
    public String playerName;
    public double time;

    public BestTimes(int r, String p, double t) 
    {
        ranking = r;
        playerName = p;
        time = t;
    }
}

【问题讨论】:

  • 我大部分时间都在阅读和研究如何做到这一点。我还没有写太多代码。我想出了如何将简单文本放入文件中,但这有很大不同。

标签: java arrays file


【解决方案1】:

为了存储一个对象(数据结构),您需要对其进行序列化:将其转换为字节流、字符流等。

有多种方法可以序列化一个对象,从基于 XML 的 JSON 到 object serializer/deserializer

例如(在网页中指定):

首先你必须在类定义的末尾添加implements Serializable,所以:

public class BestTimes implements Serializable {

然后你可以使用序列化:

try(FileOutputStream f = new FileOutputStream("file.txt");
    ObjectOutput s = new ObjectOutputStream(f)) {
    s.writeObject(beginner);
    s.writeObject(intermediate);
    s.writeObject(expert);
}

后来读作:

BestTimes[] beginner, intermediate, expert;
try(FileInputStream in = new FileInputStream("file.txt");
    ObjectInputStream s = new ObjectInputStream(in)) {
    beginner = (BestTimes[]) s.readObject();
    intermediate = (BestTimes[]) s.readObject();
    expert = (BestTimes[]) s.readObject();
}

对象序列化器的简单之处在于您不必自己定义格式。这是 Java 虚拟机的任务,而且它可以编码 所有 类型的对象,而 JSON 例如不能处理包含循环的数据结构(例如:图),XML 不能处理循环为好吧,CSV 仅适用于表格内容。

然而,一个缺点是数据结构被编码为二进制:它们不容易读取。虽然在这种情况下这可能是一个优势,因为一些用户倾向于更改文件以提高他们的高分;)。

【讨论】:

  • 确保关闭流。
  • @BoristheSpider:完成,非常感谢建设性的 cmets。
  • +1,我更喜欢 JSON。但我建议你要么使用try-with-resources,要么至少使用try..finally。当前的代码是一个等待发生的大规模资源泄漏......
  • @BoristheSpider:更好?
  • @kb4000 closeflush 语句非常混乱。我已经编辑了它们。现在试试。也可以在序列化之前将Arrays.toString 打印到控制台以查看数组中的内容。该文件不应该为空,因为它至少应该有一个“幻数”作为标题。
【解决方案2】:

最简单的方法是将数组序列化为 JSON 并存储它们的 JSON 表示形式。

没有理由想出自己的序列化数组解决方案,因为它已经是一个已解决的问题!我认为越容易越好。

【讨论】:

  • @ByteHamster 我认为没有什么比使用 JSON 库更容易的了,因为这使它成为一个单行。
  • JSON 的唯一问题是当引用循环发生时,问题开始出现。
  • 为什么是 JSON。为什么不直接序列化它们?
  • @BoristheSpider 这是一个公平的观点,但我认为对于初学者来说,一些人类可读的东西比原始序列化更容易理解
  • @CommuSoft 他提供的数组示例不会发生这种情况。
【解决方案3】:

正如其他人所说,使用一些 JSON 库将数据读/写到文件是一个有效的选择。

如果您想要更纯粹的 Java 方法,您可以在实现 Serializable 接口的类中对数据进行建模,并使用 Java 的 ObjectOutput-ObjectInputStream 读取/写入它们。

【讨论】:

  • 我最初想把我的数据放在你提到的类中,但我的导师希望我们使用数组。 :(
  • @kb4000:Array 也是一个对象。您也可以简单地将其放在ObjectOutputStream 中。
【解决方案4】:

我要么使用数据库,要么将您的内容导出为 CSV(逗号分隔值)文件。您可以引入第四个属性,代表您的数据的type(初学者、专家等)。

1, John, 110, beginner
2, Mark, 90, professional
...

【讨论】:

  • 这是个好主意。我认为这会简化很多事情。感谢您的建议。
【解决方案5】:

你也可以存储在csv文件中,

代码

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import com.csvreader.CsvWriter;

public class CsvWriterAppendExample {

public static void main(String[] args) {

    String outputFile = "users.csv";

    // before we open the file check to see if it already exists
    boolean alreadyExists = new File(outputFile).exists();

    try {
        // use FileWriter constructor that specifies open for appending
        CsvWriter csvOutput = new CsvWriter(new FileWriter(outputFile, true), ',');

        // if the file didn't already exist then we need to write out the header line
        if (!alreadyExists)
        {
            csvOutput.write("id");
            csvOutput.write("name");
            csvOutput.endRecord();
        }
        // else assume that the file already has the correct header line

        // write out a few records
        csvOutput.write("1");
        csvOutput.write("Bruce");
        csvOutput.endRecord();

        csvOutput.write("2");
        csvOutput.write("John");
        csvOutput.endRecord();

        csvOutput.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

   }
}

输出格式

id,name
1,Bruce
2,John

查看http://www.csvreader.com/java_csv_samples.php

【讨论】:

  • 感谢您的建议。我最终对这个文件进行了序列化,特别是因为我不希望玩家能够编辑高分,但 CSV 在未来可能会非常有用。
猜你喜欢
  • 2023-03-29
  • 2017-01-18
  • 2013-11-19
  • 2015-07-23
  • 2012-08-18
  • 2013-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多