# Buggy code
def _OpenZIPFile(self, path, read_only):
    """Opens the ZIP file.

    Args:
      path (str): path of the ZIP file.
      read_only (bool): True if the file should be opened in read-only mode.

    Raises:
      IOError: if the ZIP file is already opened or if the ZIP file cannot
               be opened.
    """
    if self._zipfile:
        raise IOError("ZIP file already opened.")

    if read_only:
        access_mode = "r"

        zipfile_path = path
    else:
        access_mode = "a"

        # Create a temporary directory to prevent multiple ZIP storage
        # files in the same directory conflicting with each other.
        directory_name = os.path.dirname(path)
        basename = os.path.basename(path)
        directory_name = tempfile.mkdtemp(dir=directory_name)
        zipfile_path = os.path.join(directory_name, basename)

        if os.path.exists(path):
            os.rename(path, zipfile_path)

    try:
        self._zipfile = zipfile.ZipFile(
            zipfile_path,
            mode=access_mode,
            compression=zipfile.ZIP_DEFLATED,
            allowZip64=True,
        )
        self._zipfile_path = zipfile_path

    except zipfile.BadZipfile as exception:
        raise IOError(
            "Unable to open ZIP file: {0:s} with error: {1:s}".format(
                zipfile_path, exception
            )
        )

    self._is_open = True
    self._path = path
    self._read_only = read_only


# Traceback (WindowsError)
(plaso) C:\dev\plaso>python tools\psort.py -o xlsx G:\test_data\set_1_output.zip -w G:\test_data\set_1_output.xlsx --status_view none -d --analysis browser_search
2016-08-30 12:37:21,882 [INFO] (MainProcess) PID:9376 <psort> Starting analysis plugins.
2016-08-30 12:37:21,888 [DEBUG] (MainProcess) PID:9376 <zeromq_queue> Creating socket for browser_search output event queue
2016-08-30 12:37:21,898 [DEBUG] (MainProcess) PID:9376 <zeromq_queue> browser_search output event queue bound to random port 61649
2016-08-30 12:37:22,417 [INFO] (MainProcess) PID:9376 <psort> Started analysis plugin: browser_search (PID: 14200).
2016-08-30 12:37:24,822 [INFO] (MainProcess) PID:9376 <psort> Analysis plugins running
Traceback (most recent call last):
File "tools\psort.py", line 867, in <module>
if not Main():
File "tools\psort.py", line 853, in Main
tool.ProcessStorage()
File "tools\psort.py", line 787, in ProcessStorage
status_update_callback=status_update_callback)
File "C:\dev\plaso\plaso\frontend\psort.py", line 103, in AnalyzeEvents
status_update_callback=status_update_callback)
File "C:\dev\plaso\plaso\multi_processing\psort.py", line 536, in AnalyzeEvents
storage_writer.Open()
File "C:\dev\plaso\plaso\storage\zip_file.py", line 3217, in Open
self._storage_file.Open(path=self._output_file, read_only=False)
File "C:\dev\plaso\plaso\storage\zip_file.py", line 2754, in Open
self._OpenZIPFile(path, read_only)
File "C:\dev\plaso\plaso\storage\zip_file.py", line 1740, in _OpenZIPFile
os.rename(path, zipfile_path)
WindowsError: [Error 32] The process cannot access the file because it is being used by another process

# Fixed code
def _OpenZIPFile(self, path, read_only):
    """Opens the ZIP file.

    Args:
      path (str): path of the ZIP file.
      read_only (bool): True if the file should be opened in read-only mode.

    Raises:
      IOError: if the ZIP file is already opened or if the ZIP file cannot
               be opened.
    """
    if self._zipfile:
        raise IOError("ZIP file already opened.")

    if read_only:
        access_mode = "r"

        zipfile_path = path
    else:
        access_mode = "a"

        # Create a temporary directory to prevent multiple ZIP storage
        # files in the same directory conflicting with each other.
        directory_name = os.path.dirname(path)
        basename = os.path.basename(path)
        directory_name = tempfile.mkdtemp(dir=directory_name)
        zipfile_path = os.path.join(directory_name, basename)

        if os.path.exists(path):
            attempts = 1
            # On Windows the file can sometimes be in use and we have to wait.
            while attempts <= self._MAXIMUM_NUMBER_OF_LOCKED_FILE_RETRIES:
                try:
                    os.rename(path, zipfile_path)
                    break

                except OSError:
                    if attempts == self._MAXIMUM_NUMBER_OF_LOCKED_FILE_RETRIES:
                        raise
                    time.sleep(self._LOCKED_FILE_SLEEP_TIME)
                    attempts += 1

    try:
        self._zipfile = zipfile.ZipFile(
            zipfile_path,
            mode=access_mode,
            compression=zipfile.ZIP_DEFLATED,
            allowZip64=True,
        )
        self._zipfile_path = zipfile_path

    except zipfile.BadZipfile as exception:
        raise IOError(
            "Unable to open ZIP file: {0:s} with error: {1:s}".format(
                zipfile_path, exception
            )
        )

    self._is_open = True
    self._path = path
    self._read_only = read_only