Hola:
Tengo un problema,con un programa que me genera un .txt y lo va rellenando por lineas de datos.(hecho en c)
Bien,ahora con otro programa,quiero leer ese fichero .txt(hecho con Visual Basic)
El problema es que no me deja leerlo,porque el fichero esta abierto,ya que se esta rellenando constantemente.
Que me recomendais que puedo hacer??
HOLA!!!
Probaste copiarlo y leer la copia?
GRACIAS POR LEER!!!
* Se me ocurre usar Semaforos para que sepa si tu programa en C esta haciendo algo en el archivo o si el programa en VB6 le esta haciendo algo...
* Tambien se me ocurre usar SendMessage para que se avises enre procesos...
* PIPES...
* Sockets...
* habra mas soluciones... pero no se me ocurre ninguna mas.
Ducles Lunas!¡.
Creo que esto está más que contestado aquí: http://foro.elhacker.net/programacion_cc/cerrar_ficheros_en_c-t345142.0.html
¿Se podría considerar doble post? no se, las preguntas son diferentes, pero imagino que van enfocadas al mismo problema
---EDIT---
A lo que me entra una. Si el archivo se está actualizando en todo momento los cambios que se realicen de reflejaran una vez el archivo haya sido abierto? O solo se cargara en memoría el contenido que llevaba hasta ese momento. porque si es así entonces es mucho mejor hacer pipes o sockets.
Hola:
Gracias por vuestras respuestas.
El caso es que se llama a una funcion,que tiene ordenes de escribir en fichero y cerrarlo en su cuerpo....pero el programa que tiene que leerlo me da el error de otro programa lo tiene ocupado.
Lo del sendMessage me puedes informar mejor?
Un socket me seria util?Seria dificil programarlo?
eso debe ser porque el programa que lo abre no esta "compartiendo" por asi decirlo para que lo puedan abrir externamente, por ejemplo en C# o en VB .NET es una pavada, con abrir el archivo como FileShare.ReadWrite, te deja abrirlo desde otro programa aun cuando este en uso.
ese programa que lo lee vos tenes acceso al codigo fuente ?
saludos.
El problema debe estar en que desde la aplicación en c estas abriendo el archivo con +w para escribir dentro del archivo y lo mas seguro es que desde visual basic también lo estas abriendo con atributos de lectura y escritura.
Intenta abrirlo solamente con atributos de lectura.
Cita de: farlaine23 en 19 Noviembre 2011, 22:45 PM
Hola:
Gracias por vuestras respuestas.
El caso es que se llama a una funcion,que tiene ordenes de escribir en fichero y cerrarlo en su cuerpo....pero el programa que tiene que leerlo me da el error de otro programa lo tiene ocupado.
Lo del sendMessage me puedes informar mejor?
Un socket me seria util?Seria dificil programarlo?
Se me ocurre para que tus APP corran adecuadamente intercomunicarlos con Sockets o PIPES o algun metodo que no use el disco duro a un 3er programa que se encargue de hacer las Colas que requieras...
Es decir un "microservidor" que solo leea o escriba en el txt de manera adecuada siendo este el que se encargue de manipular por completo el archivo... Desde mi punto de vista seria lo Ideasl...
Dulces Lunas!¡.
Hola de nuevo
Os respondo:
-Tengo acceso al codigo fuente de los 2 programas,pero FileShare.ReadWrite para C o Visual Basic,no me va a servir no??
-He intentado lo que recomendo whk y no lo consegui.El programa de c lo habre con permiso a y el de Visual lo abre con r.
-BlackZeroX como podria hacer ese microservidor?Aunque las aplicaciones esten en 2 lenguajes diferentes,se podra hacer??Es arduo complicado??
Una cosa,mientras escribe los datos en el .txt,tambien saca los mismos datos por pantalla,podria utilizar esos datos para leerlos,en vez del .txt?Me daria el mismo problema,verdad??
Cita de: farlaine23 en 20 Noviembre 2011, 04:39 AM
Hola de nuevo
Os respondo:
-Tengo acceso al codigo fuente de los 2 programas,pero FileShare.ReadWrite para C o Visual Basic,no me va a servir no??
-He intentado lo que recomendo whk y no lo consegui.El programa de c lo habre con permiso a y el de Visual lo abre con r.
-BlackZeroX como podria hacer ese microservidor?Aunque las aplicaciones esten en 2 lenguajes diferentes,se podra hacer??Es arduo complicado??
Una cosa,mientras escribe los datos en el .txt,tambien saca los mismos datos por pantalla,podria utilizar esos datos para leerlos,en vez del .txt?Me daria el mismo problema,verdad??
- Si optas por abrir en solo lectura pues peudes usar las APIS...
- ...
- Pues si usas Sockets no importara el lenguaje para este micro servidor (Independientemente si es C/C++ o vb6, hazlo en el que te acomodes más, si quieres mas velocidad y acceso mas directo a la memoria usa C/C++)... necesitarías un protocolo para que se intercomuniquen los procesos y leerte la teoría de colas (queue) o mejor conocida como FIFO... con esta teoría podrás armar el servidor de una manera muy amena y optima y las instrucciones será amigables desde un punto de vista de análisis en comunicaciones entre procesos. (EDITO) Añado que inclusive puedes implementar un sistema de cache para agilizar tu sistema...
Dulces Lunas!¡.
Hola:
He creado ya el servidor,el cual lee los datos de un .txt,asi que ya tengo la mitad del trabajo hecho.
Ahora quiero saber si me podeis ayudar a enviar esos datos directamente al servidor,sin tener que tener ese paso del .txt intermedio
.
Mira mas o menos seria algo asi... Solo arme 3 microclientes de PRUEBA que realizar acciones de escritura en un archivo llamada "c:\BDD.txt" las demas acciones serán ya cosa tuya.
Nesesitas
5 Controles Winsock
1 llamado wsSrv sin index
1 llamado wsCon con index = 0
3 winsock llamados Winsock1, Winsock2 y Winsock3
Option Explicit
Private Type t
lSizeData As Long 'Currency
lCountPages As Long
lStep As Long
bRead As Long
End Type
Private Enum SockState
sckClosed = 0
sckOpen
sckListening
sckConnectionPending
sckResolvingHost
sckHostResolved
sckConnecting
sckConnected
sckClosing
sckError
End Enum
Private collectionSockets() As t
Public Function max(ByVal l1 As Long, ByVal l2 As Long) As Long
If l1 > l2 Then
max = l1
Exit Function
End If
max = l2
End Function
Public Function getIndexSocket(ByRef osck As Object) As Integer
Dim Index As Integer
Dim SockSt As SockState
getIndexSocket = -1
For Index = osck.lbound To osck.UBound
With osck(Index)
SockSt = .State
If SockSt = sckClosed Or SockSt = sckListening Or SockSt = sckClosing Then
'If SockSt = sckClosed Or SockSt = sckListening Or SockSt = sckClosing Or SockSt = sckError Then ' // Optativo
getIndexSocket = Index
Exit For
End If
End With
Next
End Function
Public Function acceptConection(ByRef osck As Object, ByVal requestID As Long) As Long
Dim i As Integer
i = getIndexSocket(osck)
If i = -1 Then
i = osck.UBound + 1
Load osck(i)
End If
osck(i).Close ' // Poner Close en lugar de CloseSck si se usa el OCX WindSock de M$.
osck(i).Accept requestID
acceptConection = i
End Function
Private Sub Form_Load()
With wsSrv
.Close
.LocalPort = 456
.Listen
End With
Open "c:\BDD.txt" For Binary As 1
Winsock1.Connect "127.0.0.1", 456
Winsock2.Connect "127.0.0.1", 456
Winsock3.Connect "127.0.0.1", 456
End Sub
Private Sub Form_Unload(Cancel As Integer)
Close 1
End Sub
' // Pequeño Cliente 1...
Private Sub Winsock1_Connect()
Dim lAux As Long
Const NAME As String = "Miguel agel ortega avila"
lAux = 2
Winsock1.SendData lAux
lAux = Len(NAME)
Winsock1.SendData lAux
Winsock1.SendData NAME
' // El protocolo seria:
' * 4 bytes para decirle que hacer al Servidor.
' * 4 bytes para decirle la longitud de los datos a enviar (segun el caso anterior).
' * Paquete de Bytes a enviar.
' * Termina.
End Sub
' // Pequeño Cliente 2...
Private Sub Winsock2_Connect()
Dim lAux As Long
Const NAME As String = vbCrLf & "No programe las acciones de lectura para el archivo debido a que no tengo mucho tiempo."
lAux = 2
Winsock2.SendData lAux
lAux = Len(NAME)
Winsock2.SendData lAux
Winsock2.SendData NAME
' // El protocolo seria:
' * 4 bytes para decirle que hacer al Servidor.
' * 4 bytes para decirle la longitud de los datos a enviar (segun el caso anterior).
' * Paquete de Bytes a enviar.
' * Termina.
End Sub
' // Pequeño Cliente 3...
Private Sub Winsock3_Connect()
Dim lAux As Long
Const NAME As String = vbCrLf & "Solo falta aplicar Adecuadamente la teoria FIFO, con pocos clientes esto ira adecuadamente."
lAux = 2
Winsock3.SendData lAux
lAux = Len(NAME)
Winsock3.SendData lAux
Winsock3.SendData NAME
' // El protocolo seria:
' * 4 bytes para decirle que hacer al Servidor.
' * 4 bytes para decirle la longitud de los datos a enviar (segun el caso anterior).
' * Paquete de Bytes a enviar.
' * Termina.
End Sub
' // Fin del pequeño Cliente...
Private Sub wsCon_DataArrival(Index As Integer, ByVal bytesTotal As Long)
Dim bData() As Byte
Dim lSize As Long
Do
Select Case collectionSockets(Index).lStep
Case 0
lSize = 4 ' // Flags.
collectionSockets(Index).lCountPages = 0
Case 1
lSize = 4 ' // Size of Data
collectionSockets(Index).lCountPages = 0
Case 2
lSize = min(1024, bytesTotal) ' // Size of Data leemos de a 1kB...
collectionSockets(Index).lCountPages = 0
Case Else
End Select
ReDim bData(0 To (lSize - 1))
wsCon(Index).GetData bData, vbByte, lSize
bytesTotal = (bytesTotal - lSize)
Select Case collectionSockets(Index).lStep
Case 0 ' // Tipo de accion
Select Case byteToLong(bData)
Case 1
collectionSockets(Index).bRead = True
Case 2
collectionSockets(Index).bRead = False
Case Else
collectionSockets(Index).lStep = 0
Exit Do
End Select
collectionSockets(Index).lStep = 1
Case 1 ' // Longitud de los datos.
If collectionSockets(Index).bRead Then
' // No lo programare...
Else
collectionSockets(Index).lSizeData = byteToLong(bData)
End If
collectionSockets(Index).lStep = 2
Case 2 ' // Reseccion/Envio de los datos.
collectionSockets(Index).lSizeData = (collectionSockets(Index).lSizeData - lSize)
Put 1, , bData
End Select
Loop While (bytesTotal > &H0) Or (collectionSockets(Index).lSizeData > &H0)
End Sub
Private Sub wsSrv_ConnectionRequest(ByVal requestID As Long)
Dim i As Long
Dim a As Winsock
i = acceptConection(wsCon, requestID)
ReDim Preserve collectionSockets(max(i, wsCon.UBound))
End Sub
Public Function min(ByVal l1 As Long, ByVal l2 As Long) As Long
If l1 < l2 Then
min = l1
Exit Function
End If
min = l2
End Function
Public Function byteToLong(ByRef bData() As Byte) As Long
If (bData(3) And &H80000000) Then byteToLong = byteToLong Or &H80000000
byteToLong = (bData(3) And &H7F) * &H1000000
byteToLong = byteToLong Or (bData(2) * &H10000)
byteToLong = byteToLong Or (bData(1) * &H100)
byteToLong = byteToLong Or bData(0)
End Function
Dulces Lunas!¡.