我正在编写一个将数据保存到 CSV 文件的游戏小程序,并获得了一些可以读取和写入同一.csv
文件的方法。不知何故,我需要锁定文件,而我的每个方法都有一个打开的写入器流到文件,所以在我关闭写入流之前无法更改文件内容,但我只想允许读取访问。
可能吗?
或者,如果它可以在完全不访问文件的情况下完成,那也很好。
编辑:我的电脑将成为提供在线游戏小程序的服务器,而 csv 文件仅在我的电脑上。要玩本游戏,您必须登录我的网站,并将所有帐户信息(用户名、密码、总赢、总输等)存储到我的计算机(服务器)上的 csv 文件中。所以我有几种方法可以更改文件。因此,我需要在写入文件时将其锁定在每种方法中,如果从理论上讲,将是几个玩家同时玩。
我将信息存储到 csv 文件的原因是我接受了 java 开发人员的教育并且只编程了 4 个月,我们将在几个月内首先了解数据库。
这是一项功课,这就是我制作小程序的原因。唯一将连接到我的计算机(将通过一个简单的 servlet 和网页为小程序提供服务)的用户是我的老师。所以不存在安全威胁。
这是播放器对象的代码:
public class Player {
private String userName;
private String passWord;
private int currentWins;
private int currentLosses;
private int totalWins;
private int totalLosses;
private boolean isLoggedIn = false;
private String playerId;
public Player(String playerId, String userName, String passWord, int totalWins, int totalLosses) {
this.playerId = playerId;
this.userName = userName;
this.passWord = passWord;
this.totalWins = totalWins;
this.totalLosses = totalLosses;
this.currentWins = 0;
this.currentLosses = 0;
}
public Player(String userName, String passWord, int totalWins, int totalLosses) {
this.userName = userName;
this.passWord = passWord;
this.totalWins = totalWins;
this.totalLosses = totalLosses;
this.currentWins = 0;
this.currentLosses = 0;
this.playerId = UUID.randomUUID().toString();
}
public void incrementWins()
{
currentWins++;
totalWins++;
}
public void incrementLosses()
{
currentLosses++;
totalLosses++;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return passWord;
}
public void setPassword(String passWord) {
this.passWord = passWord;
}
public boolean isLoggedIn() {
return isLoggedIn;
}
public void setLoggedIn(boolean isLoggedIn) {
this.isLoggedIn = isLoggedIn;
}
public int getTotalWins()
{
return this.totalWins;
}
public void setTotalWins(int totalWins)
{
this.totalWins = totalWins;
}
public int getTotalLoss()
{
return this.totalLosses;
}
public void setTotalLoss(int totalLoss)
{
this.totalLosses = totalLoss;
}
public int getCurrentWins()
{
return this.currentWins;
}
public void setCurrentWins(int currentWins)
{
this.currentWins = currentWins;
}
public int getCurrentLoss()
{
return this.currentLosses;
}
public void setCurrentLoss(int currentLosses)
{
this.currentLosses = currentLosses;
}
public String getPlayerId() {
return playerId;
}
public void setPlayerId(UUID playerId) {
this.playerId = playerId.toString();
}
}
这里播放器管理器代码:
public class PlayerManager {
private final File file = new File("Players.csv");
public PlayerManager() throws IOException
{
if (!file.exists())
file.createNewFile();
}
public Player getPlayer(String playerId) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
String line;
while((line = reader.readLine()) != null) {
if(line.equalsIgnoreCase("PlayerID;Username;Password;Total Wins;Total Losses"))
continue;
String[] playerInfo = line.split(";");
String existingPlayerID = playerInfo[0];
String userName = playerInfo[1];
String password = playerInfo[2];
int totalWins = Integer.parseInt(playerInfo[3]);
int totalLoss = Integer.parseInt(playerInfo[4]);
if(existingPlayerID.equals(playerId)) {
reader.close();
return new Player(existingPlayerID,userName, password, totalWins, totalLoss);
}
}
reader.close();
return null;
}
public ArrayList<Player> getAllPlayers() throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "utf-8"));
ArrayList<Player> players = new ArrayList<Player>();
String line;
while((line = reader.readLine()) != null)
{
if(line.equalsIgnoreCase("PlayerID;Username;Password;Total Wins;Total Losses"))
continue;
String[] playerInfo = line.split(";");
String playerID = playerInfo[0];
String userName = playerInfo[1];
String password = playerInfo[2];
int totalWins = Integer.parseInt(playerInfo[3]);
int totalLoss = Integer.parseInt(playerInfo[4]);
players.add(new Player(playerID,userName, password, totalWins, totalLoss));
}
reader.close();
return players;
}
public void savePlayer(Player player) throws IOException {
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true), "utf-8"));
if(file.length() == 0) {
writer.write("PlayerID;Username;Password;Total Wins;Total Losses");
writer.newLine();
writer.flush();
}
if(playerExists(player)) {
writer.close();
updatePlayer(player);
return;
}
writer.write(player.getPlayerId() + ";" + player.getUserName() + ";" + player.getPassword() + ";" +
player.getTotalWins() + ";" + player.getTotalLoss());
writer.newLine();
writer.flush();
writer.close();
}
public Player loginPlayer(String userName, String passWord) throws IOException {
for(Player p : getAllPlayers()) {
if(p.isLoggedIn())
return p;
if(p.getUserName().equals(userName) && p.getPassword().equals(passWord)) {
p.setLoggedIn(true);
return p;
}
}
return null;
}
private void updatePlayer(Player player) {
try
{
ArrayList<Player> players = getAllPlayers();
for(Player p : players) {
if(p.getPlayerId().equals(player.getPlayerId())) {
p.setUserName(player.getUserName());
p.setPassword(player.getPassword());
p.setCurrentWins(player.getCurrentWins());
p.setCurrentLoss(player.getCurrentLoss());
p.setLoggedIn(player.isLoggedIn());
p.setTotalWins(player.getTotalWins());
p.setTotalLoss(player.getTotalLoss());
break;
}
}
File tempFile = new File("Players.csv.bak");
if (!tempFile.exists())
tempFile.createNewFile();
else
{
tempFile.delete();
tempFile.createNewFile();
}
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(tempFile), "utf-8"));
if(tempFile.length() == 0) {
writer.write("PlayerID;Username;Password;Total Wins;Total Losses");
writer.newLine();
writer.flush();
}
for(Player p : players) {
writer.write(p.getPlayerId() + ";" + p.getUserName() + ";" + p.getPassword() + ";" +
p.getTotalWins() + ";" + p.getTotalLoss());
writer.newLine();
}
writer.flush();
writer.close();
this.file.delete();
tempFile.renameTo(this.file);
}
catch(Exception ex)
{
}
}
private boolean playerExists(Player player) throws IOException {
Player p = getPlayer(player.getPlayerId());
if(p != null && p.getPlayerId().equals(player.getPlayerId()))
return true;
return false;
}
}
这是 servlet(尚未完成):
public class TickTackToeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private boolean newUser = true;
public String getLoginForm() throws IOException {
File loginForm = new File("login.html");
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(loginForm)));
StringBuilder str = new StringBuilder();
String line;
while((line = reader.readLine()) != null) {
str.append(line);
}
reader.close();
return str.toString();
}
public String displayGamePage() {
return null;
}
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html; charset=utf-8");
response.setStatus(HttpServletResponse.SC_OK);
Writer writer = response.getWriter();
String loginForm = getLoginForm();
writer.write(loginForm);
}
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html; charset=utf-8");
Writer writer = response.getWriter();
String userName = request.getParameter("username");
String passWord = request.getParameter("password");
if(userName == null || passWord == null) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
writer.write("<h1>You forgot to enter username/password. Please refresh to try again.</h1>");
writer.write(getLoginForm());
return;
}
PlayerManager playerManager = new PlayerManager();
playerManager.loginPlayer(userName, passWord);
Player player = new Player(userName, passWord, 0 , 0);
if(!player.isLoggedIn()) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
writer.write("<h1>Bad username or password. Please refresh to try again.</h1>");
return;
}
HttpSession session = request.getSession(true);
if(session.getAttribute(userName) == null || session.getAttribute(passWord) == null) {
session.setAttribute("username", userName);
session.setAttribute("password", passWord);
}
response.setStatus(HttpServletResponse.SC_OK);
response.sendRedirect(request.getParameter("url"));
}
public static void main(String... args) throws Exception {
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.addServlet(TickTackToeServlet.class, "/");
Server server = new Server(8080);
server.setHandler(context);
server.start();
server.join();
}
}
这是小程序(尚未完成):
public class TickTackToeApplet extends JApplet implements ActionListener {
private static final long serialVersionUID = 1L;
private ArrayList<JButton> buttons = new ArrayList<JButton>();
private JPanel panel = new JPanel();
private Game game;
private Player player1;
private Player player2;
private int numberOfPlacedOutChars = 0;
public TickTackToeApplet() {}
public TickTackToeApplet(int gameBoardSize, Player player1, Player player2) {
createGUI(gameBoardSize);
game = new Game(gameBoardSize);
this.player1 = player1;
this.player2 = player2;
if(!player1.isLoggedIn() && !player2.isLoggedIn()) {
try {
PlayerManager playerManager = new PlayerManager();
playerManager.loginPlayer(player1.getUserName(), player1.getPassword());
playerManager.loginPlayer(player2.getUserName(), player1.getPassword());
} catch (IllegalArgumentException e) {
JOptionPane.showMessageDialog(this, "Couldn't login player, please enter correct username & password!");
} catch (IOException e) {
JOptionPane.showMessageDialog(this, "Server error...");
e.printStackTrace();
}
}
}
// public void init() {
// new TickTackToeApplet(4, "Henrik", "temp123");
// }
public void CreateButtons(int gameBoardSize)
{
for(int x=0; x<gameBoardSize; x++)
{
for(int y=0; y<gameBoardSize; y++)
{
JButton btn = new JButton("");
btn.setFont(new Font("Tahoma", Font.PLAIN, 32));
btn.setName(x + ";" + y);
btn.addActionListener(this);
buttons.add(btn);
}
}
}
public void PlaceOutButtons()
{
for(JButton btn : buttons)
panel.add(btn);
}
public void createGUI(int gameBoardSize) {
panel.setSize(gameBoardSize*25, gameBoardSize*25);
panel.setBackground(Color.BLACK);
getContentPane().add(panel, BorderLayout.CENTER);
panel.setLayout(new GridLayout(gameBoardSize, gameBoardSize));
CreateButtons(gameBoardSize);
PlaceOutButtons();
}
@Override
public void actionPerformed(ActionEvent e) {
JButton buttonClicked = (JButton)e.getSource();
String coordinates = buttonClicked.getName();
String[] strArr = coordinates.split(";");
int x = Integer.parseInt(strArr[0]);
int y = Integer.parseInt(strArr[1]);
if (numberOfPlacedOutChars % 2 == 0) {
game.placeChar('X', x, y);
buttonClicked.setText("X");
buttonClicked.setEnabled(false);
}
else {
game.placeChar('O', x, y);
buttonClicked.setText("O");
buttonClicked.setEnabled(false);
}
numberOfPlacedOutChars++;
boolean win = game.checkWin();
if(win == true) {
player1.incrementWins();
try {
PlayerManager playerManager = new PlayerManager();
playerManager.savePlayer(player1);
} catch (IllegalArgumentException | IOException e1) {
JOptionPane.showMessageDialog(this, "Couldn't update player info!");
}
for(JButton btn : buttons) {
btn.setEnabled(false);
}
int choice = JOptionPane.showConfirmDialog(this, "Winner is: " + player1.getUserName() + ", play again?", "WE GOT A WINNER", JOptionPane.YES_NO_OPTION);
if(choice == 0) {
for(JButton btn : buttons) {
btn.setEnabled(true);
btn.setText("");
}
}
}
}
}