锁定CSV文件(仅允许读取访问)。可能?

时间:2013-01-04 00:19:31

标签: java applet locking persistence file-locking

我正在编写一个游戏小程序,用于将数据保存到CSV文件,并获得一些可以读取和写入同一.csv文件的方法。不知何故,我需要锁定文件,而我的每个方法都有一个打开的文件写入流到文件,因此在关闭写入流之前不能更改文件内容,但我只想允许读取访问。

有可能吗?

或者,如果可以在没有任何文件访问权限的情况下完成它也可以。

编辑:我的计算机将是服务于在线游戏小程序的服务器,而csv文件仅在我的计算机上。要播放,您必须登录我的网站并将所有帐户信息(用户名,密码,总胜利,总损失等)存储到我的计算机(服务器)上的csv文件中。所以我有几种方法可以改变文件。因此,我需要在写入文件的同时将其锁定在每个方法中,如果理论上,将会有几个玩家同时玩。

我将信息存储到csv文件的原因是,我正在向javadeveloper教育并且只编程了4个月,我们将在几个月内首先了解数据库。

这是一个学校作业,这就是我制作applet的原因。将连接到我的计算机的唯一用户(通过简单的servlet和网页提供applet)是我的老师。所以没有安全威胁。

以下是玩家对象的代码:

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("");
                }
            }
        }
    }

}

1 个答案:

答案 0 :(得分:2)

使用Java.NIO,您可以使用名为FileLock的类来执行此操作。以下是article on JavaBeat

的示例
import java.io.*;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;

public class FileLockTest {
  public static void main(String[] args) throws Exception {
    RandomAccessFile file = null;
    FileLock fileLock = null;
    try {
      file = new RandomAccessFile("FileToBeLocked", "rw");
      FileChannel fileChannel = file.getChannel();

      fileLock = fileChannel.tryLock();
      if (fileLock != null){
        System.out.println("File is locked");
        accessTheLockedFile();
      }
    } finally {
      if (fileLock != null) {
        fileLock.release();
      }
    }
  }

  static void accessTheLockedFile() {
    try {
      FileInputStream input = new FileInputStream("FileToBeLocked");
      int data = input.read();
      System.out.println(data);
    } catch (Exception exception) {
      exception.printStackTrace();
    }
  }
}

因为这涉及到文件系统,所以你需要一个.policy文件,你需要签署applet。虽然您应read up on this

,但此政策应该有效
grant {
  permission java.io.FilePermission "<<ALL FILES>>","write";
};